6.2.2 re ECTF2016 tayy

    下载文件

    1. tayy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=1fcd1c49eae4807f77d51227a3b457d8874170b4, not stripped
    1. 每次我们与 Tayy 交谈后,flag 就会变
    2. 最多可以交谈 8 次,然后程序退出

    通过调试,我们首先发现了 flag 的初始值:

    1. gdb-peda$ n
    2. [----------------------------------registers-----------------------------------]
    3. RAX: 0x0
    4. RBX: 0x0
    5. RCX: 0x0
    6. RDX: 0x7ffff7dd4710 --> 0x0
    7. RSI: 0x7fffffffe460 --> 0x231819834c584545
    8. RDI: 0x400d2c ("Flag: %s\n")
    9. RBP: 0x7fffffffe490 --> 0x400a70 (<__libc_csu_init>: push r15)
    10. RSP: 0x7fffffffe450 --> 0x2
    11. RIP: 0x4009e5 (<main+292>: call 0x4005c0 <printf@plt>)
    12. R8 : 0x7fffffffdf11 --> 0x3f00007ffff7ff00
    13. R9 : 0xa ('\n')
    14. R10: 0x0
    15. R11: 0xa ('\n')
    16. R13: 0x7fffffffe570 --> 0x1
    17. R14: 0x0
    18. R15: 0x0
    19. EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
    20. 0x4009d8 <main+279>: mov rsi,rax
    21. 0x4009db <main+282>: mov edi,0x400d2c
    22. 0x4009e0 <main+287>: mov eax,0x0
    23. => 0x4009e5 <main+292>: call 0x4005c0 <printf@plt>
    24. 0x4009ea <main+297>: jmp 0x4009f6 <main+309>
    25. 0x4009ec <main+299>: mov edi,0x400d38
    26. 0x4009f1 <main+304>: call 0x4005a0 <puts@plt>
    27. 0x4009f6 <main+309>: mov eax,DWORD PTR [rip+0x201688] # 0x602084 <num2>
    28. Guessed arguments:
    29. arg[0]: 0x400d2c ("Flag: %s\n")
    30. arg[1]: 0x7fffffffe460 --> 0x231819834c584545
    31. [------------------------------------stack-------------------------------------]
    32. 0000| 0x7fffffffe450 --> 0x2
    33. 0008| 0x7fffffffe458 --> 0x7fffffffe460 --> 0x231819834c584545
    34. 0016| 0x7fffffffe460 --> 0x231819834c584545
    35. 0024| 0x7fffffffe468 --> 0x67035b26354e401c
    36. 0032| 0x7fffffffe470 (",q2H7?09:G>4!O]iJ('\nV")
    37. 0040| 0x7fffffffe478 (":G>4!O]iJ('\nV")
    38. 0056| 0x7fffffffe488 --> 0x74941753df1a500
    39. [------------------------------------------------------------------------------]
    40. 0x00000000004009e5 in main ()
    41. gdb-peda$ x/s 0x7fffffffe460
    42. 0x7fffffffe460: "EEXL\203\031\030#\034@N5&[\003g,q2H7?09:G>4!O]iJ('\nV"
    43. gdb-peda$ x/37x 0x7fffffffe460
    44. 0x7fffffffe460: 0x45 0x45 0x58 0x4c 0x83 0x19 0x18 0x23
    45. 0x7fffffffe468: 0x1c 0x40 0x4e 0x35 0x26 0x5b 0x03 0x67
    46. 0x7fffffffe470: 0x2c 0x71 0x32 0x48 0x37 0x3f 0x30 0x39
    47. 0x7fffffffe478: 0x3a 0x47 0x3e 0x34 0x21 0x4f 0x5d 0x69
    48. 0x7fffffffe480: 0x4a 0x28 0x27 0x0a 0x56

    该函数的汇编代码大概可以整理成下面的伪代码:

    1. int num2 = 0; // 交谈次数
    2. void giff_flag(&flag, int key) {
    3. for(int i = 0; i <= 36; i++) {
    4. if (num2 % 2 == 1) {
    5. flag[i] = flag[i] - i * key % 37;
    6. } else {
    7. flag[i] = flag[i] + i * key % 37;
    8. }
    9. }
    10. num2++;
    11. }

    参考资料