6.2.5 re PicoCTF2014 Baleful

    经过简单地检查,我们发现二进制文件被加了壳,使用 upx 脱掉就好了。

    运行下看看,典型的密码验证题:

    1. Please enter your password: ABCD
    2. Sorry, wrong password!

    打开 r2 开干吧!

    1. [0x08048540]> pdf @ main
    2. / (fcn) main 96
    3. | main ();
    4. | ; var int local_8h @ ebp-0x8
    5. | ; var int local_10h @ esp+0x10
    6. | ; var int local_8ch @ esp+0x8c
    7. | ; DATA XREF from entry0 (0x8048557)
    8. | 0x08049c82 push ebp
    9. | 0x08049c83 mov ebp, esp
    10. | 0x08049c85 push edi
    11. | 0x08049c86 push ebx
    12. | 0x08049c87 and esp, 0xfffffff0
    13. | 0x08049c8a sub esp, 0x90
    14. | 0x08049c90 mov eax, dword gs:[0x14] ; [0x14:4]=-1 ; 20
    15. | 0x08049c96 mov dword [local_8ch], eax
    16. | 0x08049c9d xor eax, eax
    17. | 0x08049c9f lea eax, [local_10h] ; 0x10 ; 16
    18. | 0x08049ca5 mov eax, 0
    19. | 0x08049caa mov edx, 0x1f ; 31
    20. | 0x08049caf mov edi, ebx
    21. | 0x08049cb1 mov ecx, edx
    22. | 0x08049cb3 rep stosd dword es:[edi], eax
    23. | 0x08049cb9 mov dword [esp], eax
    24. | 0x08049cbc call fcn.0804898b
    25. | 0x08049cc1 mov eax, 0
    26. | 0x08049cc6 mov edx, dword [local_8ch] ; [0x8c:4]=-1 ; 140
    27. | 0x08049ccd xor edx, dword gs:[0x14]
    28. | ,=< 0x08049cd4 je 0x8049cdb
    29. | | 0x08049cd6 call sym.imp.__stack_chk_fail ; void __stack_chk_fail(void)
    30. | | ; CODE XREF from main (0x8049cd4)
    31. | `-> 0x08049cdb lea esp, [local_8h]
    32. | 0x08049cde pop ebx
    33. | 0x08049cdf pop edi
    34. | 0x08049ce0 pop ebp
    35. \ 0x08049ce1 ret

    使用 Pin 求解

    就像上面那样逆向实在是太难了,不如 Pin 的黑科技。

    编译 32 位 pintool:

    随便输入几个长度不同的密码试试:

    1. [ManualExamples]$ echo "A" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    2. Please enter your password: Sorry, wrong password!
    3. Count 437603
    4. [ManualExamples]$ echo "AA" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    5. Please enter your password: Sorry, wrong password!
    6. Count 438397
    7. [ManualExamples]$ echo "AAA" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    8. Please enter your password: Sorry, wrong password!
    9. Count 439191
    1. 794
    2. 794
    1. Please enter your password: Sorry, wrong password!
    2. count: 459041
    3. diff: 794
    4. Please enter your password: Sorry, wrong password!
    5. count: 459835
    6. diff: 794
    7. Please enter your password: Sorry, wrong password!
    8. count: 508273
    9. diff: 48438
    10. length of password: 30

    好,密码长度为 30,接下来是逐字符爆破,首先要确定字符不同对 count 没有影响:

    1. [ManualExamples]$ echo "A" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    2. Please enter your password: Sorry, wrong password!
    3. Count 437603
    4. [ManualExamples]$ echo "b" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    5. Please enter your password: Sorry, wrong password!
    6. Count 437603
    7. [ManualExamples]$ echo "_" | ../../../pin -t obj-ia32/inscount0.so -o inscount.out -- ~/baleful_unpack ; cat inscount.out
    8. Please enter your password: Sorry, wrong password!
    9. Count 437603

    确实没有,写下脚本:

    1. packers_and_vms_and_xors_oh_mx
    2. Please enter your password: Sorry, wrong password!
    3. count: 507925
    4. packers_and_vms_and_xors_oh_my
    5. Please enter your password: Congratulations!

    简单到想哭。

    参考资料