This is a write-up of my solution to the Microcorruption CTF challenge “Reykjavik” (LOCKIT PRO r a.03).
The last two challenges were relatively straightforward and pretty easy to solve. This version promises “military-grade encryption”:
Let’s see what they have up their sleeves. As always, let’s check out what’s going on in main():
As you can see, this version does not have a call to check_password(). Instead, the program makes a call to enc() and then makes another call to a mysterious portion of memory located at 0x2400. Interesting.
Another thing to note is that the memory located at 0x2400 doesn’t actually appear to contain anything interesting before the program is run (i.e. contains a bunch of zeros):
Let’s set a breakpoint on the main() function and see if we can figure out what’s going on:
Did you catch that? It looks like the portion of memory located at 0x2400 is being allocated beforemain() is called. Let’s step through the program as soon as it’s executed and keep an eye on 0x2400. Let’s also keep an eye on what instructions are being executed:
We can see that before we enter into main(), a call is made to __do_copy_data(). In this function, 0x7c bytes are being copied from 0x4538 into 0x2400. Interesting. Let’s continue on to enc() and observe what it does:
So… we can see that this subroutine is doing a number of things. Let’s attempt to break down these instructions down slightly to get a sense of what’s going on:
Instructions 0x4490 to 0x449a are going to loop while loading bytes 0x00 to 0xff into the memory address starting at 0x0x247c.
Instructions 0x449c to 0x44d6 appears to be obfuscating the previously created 256 bytes using the string located at 0x4472, ThisIsSecureRight?
Instructions 0x44d8 to 0x4510 appear to be using the previously obfuscated byte string as an XOR key to the original data written at memory location 0x2400.
After returning back into main(), call #0x2400 is immediately executed. Stepping through this code reveals sensible instructions are being executed. It appears as though the bytes at memory location 0x2400 were originally obfuscated/encrypted, and the call to enc() ultimately deobfuscated/decrypted this memory for us. Sweet! Let’s dissect these bytes and disassemble them to see if we can see what instructions are going to be executed:
After stepping through this deobfuscated code, we can see that it is printing out the password input prompt. After entering in the password and stepping forward a few instructions, we see that the program will exit or continue based on the result of cmp #0xab11, -0x24(r4). In other words, the door should open if the password is 0xab11. Wow… so much for that “military-grade encryption”! Let’s try it out (don’t forget the byte order):