Monday, July 7, 2014

Pwnium CTF 2014 - Breakpoints - RE 300 - [Team SegFault]

We were given a 64-bit stripped ELF for this challenge. We need to generate a valid password for this executable.
[root@renorobert Pwnium]# ./re300
Password : A
:(
Analyzing the file in IDA, there was only 2 functions. Main function at 0x040661A and CheckPassword function at 0x040063A. The Main function had nothing interesting except a ptrace call for anti-debugging.

This is what CheckPassword looked like:
The CheckPassword function was large, so we decided to trace the interesting instructions in it, as the program executes. Idea was to supply arbitrary input and trace the execution.
[root@renorobert MyPinTool]# pin -t trace.so -- ./re300 
Password : Z
:(
0x40064d: cmp eax, 0x712a6ee0
0x400658: cmp eax, 0x712a6ee0
0x400aac: cmp eax, 0xb2fc91ab
0x400ab7: cmp eax, 0xb2fc91ab
0x400cd0: cmp eax, 0xdd01eab3
0x400cdb: cmp eax, 0xdd01eab3
0x400de2: cmp eax, 0xe81c0d24
0x400ded: cmp eax, 0xe81c0d24
0x400e69: cmp eax, 0xf03ad87a
0x400e74: cmp eax, 0xf03ad87a
0x400eb8: cmp eax, 0xf487628c
0x400ec3: cmp eax, 0xf487628c
0x400eda: cmp eax, 0xf6fbb4e5
0x400ee5: cmp eax, 0xfe129837
0x40580e: cmp al, 0x44
0x40582d: cmp al, 0x64
0x40584c: cmp al, 0x31
0x40586b: cmp al, 0x34
0x40588a: cmp al, 0x2a
0x4058a9: cmp al, 0xb
0x4058c8: cmp al, 0x3d
0x4058e7: cmp al, 0x66
0x405906: cmp al, 0x63
0x405925: cmp al, 0x46
0x405944: cmp al, 0x36
0x405963: cmp al, 0x69
0x405982: cmp al, 0x6d
0x40599a: add qword ptr [rbp-0x8], 0x1
0x400586: sub rax, 0x606b20
0x40058c: cmp rax, 0xe
The user supplied value is compared against 0x44, 0x64 ,.., 0x6D. But there was no other computations performed. Looks like only comparisons are made with supplied password.
Lets try another run by supplying 0x44(D) as input.
[root@renorobert MyPinTool]# pin -t trace.so -- ./re300 
Password : D
:(
0x40064d: cmp eax, 0x712a6ee0
0x400658: cmp eax, 0x712a6ee0
0x400aac: cmp eax, 0xb2fc91ab
0x400ab7: cmp eax, 0xb2fc91ab
0x400cd0: cmp eax, 0xdd01eab3
0x400cdb: cmp eax, 0xdd01eab3
0x400de2: cmp eax, 0xe81c0d24
0x400ded: cmp eax, 0xe81c0d24
0x400e69: cmp eax, 0xf03ad87a
0x400e74: cmp eax, 0xf03ad87a
0x400eb8: cmp eax, 0xf487628c
0x400ec3: cmp eax, 0xf487628c
0x400eda: cmp eax, 0xf6fbb4e5
0x400ee5: cmp eax, 0xfe129837
0x40580e: cmp al, 0x44
0x40581c: add qword ptr [rbp-0x8], 0x1
0x400586: sub rax, 0x606b20
0x40058c: cmp rax, 0xe
When the comparison succeeds, rest of the checks are skipped. That looked promising. Lets pass 2 bytes input as 'DZ'
[root@renorobert MyPinTool]# pin -t trace.so -- ./re300 
Password : DZ
:(
0x40064d: cmp eax, 0x712a6ee0
0x400658: cmp eax, 0x712a6ee0
0x400aac: cmp eax, 0xb2fc91ab
0x400ab7: cmp eax, 0xb2fc91ab
0x400cd0: cmp eax, 0xdd01eab3
0x400cdb: cmp eax, 0xdd01eab3
0x400de2: cmp eax, 0xe81c0d24
0x400ded: cmp eax, 0xe81c0d24
0x400e69: cmp eax, 0xf03ad87a
0x400e74: cmp eax, 0xf03ad87a
0x400eb8: cmp eax, 0xf487628c
0x400ec3: cmp eax, 0xf487628c
0x400eda: cmp eax, 0xf6fbb4e5
0x400ee5: cmp eax, 0xfe129837
0x40580e: cmp al, 0x44
0x40581c: add qword ptr [rbp-0x8], 0x1
0x40064d: cmp eax, 0x712a6ee0
0x400658: cmp eax, 0x712a6ee0
0x400aac: cmp eax, 0xb2fc91ab
0x400ab7: cmp eax, 0xb2fc91ab
0x400cd0: cmp eax, 0xdd01eab3
0x400cdb: cmp eax, 0xdd01eab3
0x400ce6: cmp eax, 0xcfcddef9
0x400cf1: cmp eax, 0xcfcddef9
0x400d6d: cmp eax, 0xd81f6c49
0x400d78: cmp eax, 0xd81f6c49
0x400d7f: cmp eax, 0xd28dcea2
0x400d8a: cmp eax, 0xd4f27687
0x400d95: cmp eax, 0xd2283d5c
0x401c5c: cmp al, 0x33
0x401c7b: cmp al, 0x23
0x401c9a: cmp al, 0x36
0x400586: sub rax, 0x606b20
0x40058c: cmp rax, 0xe
The first char is checked against 0x44 which succeeds. The second char is checked against 0x33(3), 0x23 and 0x36. So the next valid char is '3'. Thus by dumping the first checks of each block of comparison we got D3bugG1nG_Th1s_ObfuSc4t3d_C0d3_1s_R34lly_H4rD
[root@renorobert Pwnium]# ./re300
Password : D3bugG1nG_Th1s_ObfuSc4t3d_C0d3_1s_R34lly_H4rD
:)
So flag for the challenge is D3bugG1nG_Th1s_ObfuSc4t3d_C0d3_1s_R34lly_H4rD

No comments :

Post a Comment