2016-11-12 8 views
1

최근 바이너리 실행 파일이있는 퍼즐을 받았는데이 퍼즐의 목적은 바이너리 파일의 16 진 덤프에 숨겨진 비밀번호를 찾는 것입니다. 내가 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

어셈블리 코드와 동일한 작업을 수행하는 C 코드를 작성하십시오. – fuz

+0

@FUZxxl 이미이 작업을 시도했지만 이진 작성자가 완전히 다른 논리를 사용했다고 생각합니다. 이진 실행 파일의 hexdump는 근처에서도 얻을 수 없습니다. ( – Barretxx

+0

이 코드를 근사화하기 위해 작성한 C 코드는 동일한 어셈블리를 생성하지 않을 가능성이 있습니다. 어셈블리가 일치하지 않아야합니다. – fuz

답변

0

어쩌면 일부 등, 메모리 주소 범위를 검색, 중단 점을 사용하는 것과 같이, 효과적으로 디버거를 사용하는 방법을 배울 수 있도록 더 나은, 단지 미끼, 또는 붉은 청어입니다 crackme의 일종에서 추적

시작 문자열을 가져와 응용 프로그램 버퍼에 저장하는 부분, 입력 문자열을 조작하는 지침을 추적하는 부분, 입력 내용을 올바른 암호와 비교하는 방법을 찾으십시오.

암호가 상수 $ 0xd490262인데, [rbp-0x54]의 값과 비교하여 [rbp-0x54]에 $ 0xd490262가 포함되어 있으면 비교 후 jne이 포함되지 않습니다. 도약. 그로 인해 좋은 소년 메시지가 인쇄됩니다.

+0

"암호는 다음과 같습니다. 상수 $ 0xd490262 "는 말 그대로 문자열"$ 0xd490262 "또는 그 십진수를 의미합니다. 222888546? – Barretxx

+0

즉, 암호는 16 진수 값이 0d490262h 인 하드 코드 된 값이므로 사용자가 입력 한 값은 0입니다. 그 값으로 끝나야하거나 4 바이트 값을 가지므로 통과 할 수 있지만 그 값은 "형식 가능"문자가 아니므로 입력 값을 조작하고있는 것으로 추측됩니다. 해시를 해독하기가 어렵고, 디버거를 사용하여 런타임에이를 검사하여 어떤 일이 일어나는지 더 자세히 분석하십시오. – rcd