NSA Codebreaker Challenge 2015: Task 2
Thu 02 June 2016 by bbloughThis is a continuation of my previous post on the NSA Codebreaker Challenge 2015, and covers the second task in the challenge.
Task 2
Through SIGINT we have collected a new message file - this one appears to
have been sent to a field operative in the terrorist organization that is
of particular interest. A key file for this invidiual was collected
previously and should still be valid. We believe that this message may
contain actionable intelligence, so please report back with the message
contents as soon as possible. This task will require you to figure out how
to bypass the access controls built into the program that limit which
recipient can decode each message.
Running the program with the new message and key produced a new error:
user@host:~/nsa_codebreaker_2015/task_2$ ./secret-messenger --reveal --action tier2_msg.txt --symbol tier2_key.pem
Invalid (failed check 4)
Once again running the program under gdb, it was possible to discover where
in the code the error message was being used. First, I used the process
memory map to get the starting and ending addresses. Then I used gdb's find
command to search for the error message string.
(gdb) info proc map
process 13651
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x81a7000 0x15f000 0x0 /home/user/nsa_codebreaker_2015/task_2/secret-messenger
0x81a7000 0x81a8000 0x1000 0x15e000 /home/user/nsa_codebreaker_2015/task_2/secret-messenger
0x81a8000 0x81aa000 0x2000 0x15f000 /home/user/nsa_codebreaker_2015/task_2/secret-messenger
0x81aa000 0x81ad000 0x3000 0x0 [heap]
<remaining map removed for brevity>
(gdb) find 0x8048000, 0x81a7000, "Invalid (failed check 4)\n"
0x814e5e3
1 pattern found.
(gdb) p (char *) 0x814e5e3
$1 = 0x814e5e3 "Invalid (failed check 4)\n"
With the address of the error message string, I could then search the address space for references to it
(gdb) find 0x8048000, 0x81a7000, 0x814e5e3
0x804aad1 <tier2+1233>
1 pattern found.
(gdb) disassemble 0x804aac8, 0x804aaec
Dump of assembler code from 0x804aac8 to 0x804aaec:
0x0804aac8 <tier2+1224>: call 0x8049700 <exit@plt>
0x0804aacd <tier2+1229>: mov DWORD PTR [esp+0x4],0x814e5e3
0x0804aad5 <tier2+1237>: mov DWORD PTR [esp],0x1
0x0804aadc <tier2+1244>: call 0x80498a0 <__printf_chk@plt>
0x0804aae1 <tier2+1249>: mov DWORD PTR [esp],0x1
0x0804aae8 <tier2+1256>: call 0x8049700 <exit@plt>
End of assembler dump.
Searching for references to 0x0804aacd
found nothing. If I were using a
more advanced tool, such as IDA, I could follow the call graph and see
what jumps to that address. Rather than step through the program and watch
for the jump manually, I decided to use gdb's ability to step backwards while
debugging. This allowed me to set a breakpoint on 0x0804aacd
and run the
program up to that point, then step backwards to see what led there.
Just prior to the jump was a comparison checking if the value contained in the
ax
register was equal to 0x6962. Since the goal of this task is to bypass this check,
the most straightforward solution is to patch out the jmp so it is never taken.
I did this with the hexedit
utility, and replaced the 6 bytes that made up the jne
instruction
with the NOOP
value of 0x90.
However, when using the hex editor to edit the binary, the addressing starts at
zero. So in order to patch in the correct place, it was necessary to calculate
the offset from the beginning of the memory space to the target address
(0x804a7c3 - 0x8048000 = 0x27c3
), and then modify the binary at that offset in
the editor.
After patching the binary, decoding the message worked without errors and showed that the bypass of the check was successful
user@host:~/nsa_codebreaker_2015/task_2$ ./secret-messenger --reveal --action tier2_msg.txt --symbol tier2_key.pem
*****SIGNATURE IS VALID*****
Message: Our plans have been set into motion - Member number 392 is ready to carry out his tasking, and in 2 weeks time the window of opportunity will be open. If it is necessary to abort the action, the authentication code to use is hw8qviacbj6xkus6wsel.
*****SIGNATURE IS VALID*****
A successful decode of the message also meant that Task 2 was complete.