NSA Codebreaker Challenge 2015: Task 2
This is a continuation of my previous post on the NSA Codebreaker Challenge 2015, and covers the second task in the challenge.
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
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
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
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.