2016-11-12 19 views
1

我最近收到一个包含二进制可执行文件的难题,该难题的目的是发现隐藏在二进制文件的十六进制转储中的密码。我试图按照this guideline,但我没有想法继续在我达到的点。这是一个有逻辑的代码部分:如何在二进制文件中发现密码

#h begins the printf "password: " 

4006dc: bf 14 08 40 00   mov $0x400814,%edi 
4006e1: b8 00 00 00 00   mov $0x0,%eax 
#h sets %eax to NULL 

4006e6: e8 a5 fe ff ff   callq 400590 <[email protected]> 
4006eb: 48 8b 15 6e 09 20 00 mov 0x20096e(%rip),%rdx  # 601060 <[email protected]@GLIBC_2.2.5> 
4006f2: 48 8d 45 b0    lea -0x50(%rbp),%rax 
#h probably the address of the string "password: " 

4006f6: be 32 00 00 00   mov $0x32,%esi 
4006fb: 48 89 c7    mov %rax,%rdi 
4006fe: e8 ad fe ff ff   callq 4005b0 <[email protected]> 
#h calling the fgets function, so here we know which register is being used for storing the input 

400703: c7 45 ac 00 00 00 00 movl $0x0,-0x54(%rbp) 
#h makes mem[rbp-84] = NULL 

40070a: c7 45 a8 00 00 00 00 movl $0x0,-0x58(%rbp) 
#h makes mem[rpb-88] = NULL 

400711: eb 27     jmp 40073a <[email protected]+0x17a> 
#h jumps unconditionally to the pc address 40073a 

400713: 8b 45 a8    mov -0x58(%rbp),%eax 
400716: 48 98     cltq 
400718: 0f b6 44 05 b0   movzbl -0x50(%rbp,%rax,1),%eax 
40071d: 0f be d0    movsbl %al,%edx 
400720: 8b 45 a8    mov -0x58(%rbp),%eax 
400723: 48 98     cltq 
400725: 0f b6 44 05 b0   movzbl -0x50(%rbp,%rax,1),%eax 
40072a: 0f be c0    movsbl %al,%eax 
40072d: 89 c1     mov %eax,%ecx 
#h ecx loop counter 

40072f: d3 e2     shl %cl,%edx 
400731: 89 d0     mov %edx,%eax 
#h moves edx to eax 

400733: 31 45 ac    xor %eax,-0x54(%rbp) 
#h do a xor between eax and -0x54(rbp) 

400736: 83 45 a8 01    addl $0x1,-0x58(%rbp) 

#h pc address 40073a is below here 
40073a: 8b 45 a8    mov -0x58(%rbp),%eax 
40073d: 48 63 d8    movslq %eax,%rbx 
400740: 48 8d 45 b0    lea -0x50(%rbp),%rax 
#h register rax receives the mem[rbp-80] (first local variable) 

400744: 48 89 c7    mov %rax,%rdi 
400747: e8 24 fe ff ff   callq 400570 <[email protected]> 
40074c: 48 39 c3    cmp %rax,%rbx 
40074f: 72 c2     jb  400713 <[email protected]+0x153> 
#h if %rax < %rdi, jump to pc = 400713 

400751: 81 7d ac 62 02 49 0d cmpl $0xd490262,-0x54(%rbp) 
#here it compares the 0xd490262 memory address with mem[rbp-84], so I guess that the -0x54(%rbp) contains the string we want, but where??? 

400758: 75 0c     jne 400766 <[email protected]+0x1a6> 
#h here it does the jump if not equal, so the contents we want is on $0xd490262 

#h WELL DONE! 
40075a: bf 1f 08 40 00   mov $0x40081f,%edi 
40075f: e8 fc fd ff ff   callq 400560 <[email protected]> 
400764: eb 0a     jmp 400770 <[email protected]+0x1b0> 
#h wrong password 
400766: bf 2b 08 40 00   mov $0x40082b,%edi 
40076b: e8 f0 fd ff ff   callq 400560 <[email protected]> 
400770: 48 8b 4d e8    mov -0x18(%rbp),%rcx 
400774: 64 48 33 0c 25 28 00 xor %fs:0x28,%rcx 
40077b: 00 00 

注:我不知道,如果我所有的我的意见是正确的,所以在这个不信任的100%,请。

所以,我分析这个文件2天试图得到一个想法,但我想我到了一个死胡同。

以防万一,二进制执行的是:

$./binary 
$password: (fgets function in here) 
$wrong password! 

谁能给我一个提示?

+0

尝试编写与代码汇编代码完全相同的代码。 – fuz

+0

@FUZxxl我已经试过这样做了,但我认为二进制文件的作者使用了与我完全不同的逻辑。二进制可执行文件的十六进制文件不能接近: – Barretxx

+0

您编写的C代码不太可能接近此代码会产生相同的程序集。行为应该匹配,而不是程序集。 – fuz

回答

0

,因为这是某种形式的crackme的也许有些部分只是诱饵,或红鲱鱼,所以最好学会如何有效地使用你的调试器,如使用断点,搜索内存地址范围等

开始从跟踪将字符串保存到应用程序缓冲区的部分,跟踪操作输入字符串的指令,找出输入与正确密码比较的方式。

从它的外观密码是常数$ 0xd490262我猜,因为它的值来自[rbp-0x54],所以如果[rbp-0x54]包含$ 0xd490262那么比较后的jne将不会跳。从而打印好男孩的消息。

+0

当您说“密码是恒$ 0xd490262" 你的意思是字面上的字符串‘$ 0xd490262’或十进制数从它222888546? – Barretxx

+0

我的意思是,密码是具有0d490262h的十六进制值硬编码的值,所以输入值,这些来自用户,必须以该值为结尾或具有4字节值以便它可以通过,但这些值不是“可输入类型”的字符?,所以我猜测某些操作输入值,难以在反汇编中解密,使用您的调试器在运行时检查它以进一步分析发生了什么。 – rcd

相关问题