Microcorruption CTF Reykjavik Write-up

Microcorruption CTF Reykjavik Write-up

- 6 mins

Summary:

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”:

This is Software Revision 02. This release contains military-grade
encryption so users can be confident that the passwords they enter
can not be read from memory.   We apologize for making it too easy
for the password to be recovered on prior versions.  The engineers
responsible have been sacked.

Let’s see what they have up their sleeves. As always, let’s check out what’s going on in main():

4438 <main>
4438: 3e40 2045 mov #0x4520, r14
443c: 0f4e mov r14, r15
443e: 3e40 f800 mov #0xf8, r14
4442: 3f40 0024 mov #0x2400, r15
4446: b012 8644 call #0x4486 <enc>
444a: b012 0024 call #0x2400
444e: 0f43 clr r15

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):

Reykjavik Initial Memory Dump

Let’s set a breakpoint on the main() function and see if we can figure out what’s going on:

Reykjavik Break Main

Did you catch that? It looks like the portion of memory located at 0x2400 is being allocated before main() 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:

4486 <enc>
4486: 0b12 push r11
4488: 0a12 push r10
448a: 0912 push r9
448c: 0812 push r8
448e: 0d43 clr r13
4490: cd4d 7c24 mov.b r13, 0x247c(r13)
4494: 1d53 inc r13
4496: 3d90 0001 cmp #0x100, r13
449a: fa23 jne #0x4490 <enc+0xa>
449c: 3c40 7c24 mov #0x247c, r12
44a0: 0d43 clr r13
44a2: 0b4d mov r13, r11
44a4: 684c mov.b @r12, r8
44a6: 4a48 mov.b r8, r10
44a8: 0d5a add r10, r13
44aa: 0a4b mov r11, r10
44ac: 3af0 0f00 and #0xf, r10
44b0: 5a4a 7244 mov.b 0x4472(r10), r10
44b4: 8a11 sxt r10
44b6: 0d5a add r10, r13
44b8: 3df0 ff00 and #0xff, r13
44bc: 0a4d mov r13, r10
44be: 3a50 7c24 add #0x247c, r10
44c2: 694a mov.b @r10, r9
44c4: ca48 0000 mov.b r8, 0x0(r10)
44c8: cc49 0000 mov.b r9, 0x0(r12)
44cc: 1b53 inc r11
44ce: 1c53 inc r12
44d0: 3b90 0001 cmp #0x100, r11
44d4: e723 jne #0x44a4 <enc+0x1e>
44d6: 0b43 clr r11
44d8: 0c4b mov r11, r12
44da: 183c jmp #0x450c <enc+0x86>
44dc: 1c53 inc r12
44de: 3cf0 ff00 and #0xff, r12
44e2: 0a4c mov r12, r10
44e4: 3a50 7c24 add #0x247c, r10
44e8: 684a mov.b @r10, r8
44ea: 4b58 add.b r8, r11
44ec: 4b4b mov.b r11, r11
44ee: 0d4b mov r11, r13
44f0: 3d50 7c24 add #0x247c, r13
44f4: 694d mov.b @r13, r9
44f6: cd48 0000 mov.b r8, 0x0(r13)
44fa: ca49 0000 mov.b r9, 0x0(r10)
44fe: 695d add.b @r13, r9
4500: 4d49 mov.b r9, r13
4502: dfed 7c24 0000 xor.b 0x247c(r13), 0x0(r15)
4508: 1f53 inc r15
450a: 3e53 add #-0x1, r14
450c: 0e93 tst r14
450e: e623 jnz #0x44dc <enc+0x56>
4510: 3841 pop r8
4512: 3941 pop r9
4514: 3a41 pop r10
4516: 3b41 pop r11
4518: 3041 ret

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:

  1. Instructions 0x4490 to 0x449a are going to loop while loading bytes 0x00 to 0xff into the memory address starting at 0x0x247c.

  2. Instructions 0x449c to 0x44d6 appears to be obfuscating the previously created 256 bytes using the string located at 0x4472, ThisIsSecureRight?

  3. 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:

2400: 0b12 push r11
2402: 0412 push r4
2404: 0441 mov sp, r4
2406: 2452 add #0x4, r4
2408: 3150 e0ff add #0xffe0, sp
240c: 3b40 2045 mov #0x4520, r11
2410: 073c jmp $+0x10
2412: 1b53 inc r11
2414: 8f11 sxt r15
2416: 0f12 push r15
2418: 0312 push #0x0
241a: b012 6424 call #0x2464
241e: 2152 add #0x4, sp
2420: 6f4b mov.b @r11, r15
2422: 4f93 tst.b r15
2424: f623 jnz $-0x12
2426: 3012 0a00 push #0xa
242a: 0312 push #0x0
242c: b012 6424 call #0x2464
2430: 2152 add #0x4, sp
2432: 3012 1f00 push #0x1f
2436: 3f40 dcff mov #0xffdc, r15
243a: 0f54 add r4, r15
243c: 0f12 push r15
243e: 2312 push #0x2
2440: b012 6424 call #0x2464
2444: 3150 0600 add #0x6, sp
2448: b490 11ab dcff cmp #0xab11, -0x24(r4)
244e: 0520 jnz $+0xc
2450: 3012 7f00 push #0x7f
2454: b012 6424 call #0x2464
2458: 2153 incd sp
245a: 3150 2000 add #0x20, sp
245e: 3441 pop r4
2460: 3b41 pop r11
2462: 3041 ret
2464: 1e41 0200 mov 0x2(sp), r14
2468: 0212 push sr
246a: 0f4e mov r14, r15
246c: 8f10 swpb r15
246e: 024f mov r15, sr
2470: 32d0 0080 bis #0x8000, sr
2474: b012 1000 call #0x10
2478: 3241 pop sr
247a: 3041 ret

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):

Reykjavik Solve

Flag (mouse over to reveal)

11ab

jiva

jiva

Security guy, busticati, professional button-pusher

rss hackthebox keybase facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora