Microcorruption CTF Sydney Write-up

Microcorruption CTF Sydney Write-up

- 2 mins

Summary:

This is a write-up of my solution to the Microcorruption CTF challenge “Sydney” (LOCKIT PRO r a.02).

Let’s again begin by first taking a look inside the main function:

4438 <main>
4438: 3150 9cff add #0xff9c, sp
443c: 3f40 b444 mov #0x44b4 "Enter the password to continue.", r15
4440: b012 6645 call #0x4566 <puts>
4444: 0f41 mov sp, r15
4446: b012 8044 call #0x4480 <get_password>
444a: 0f41 mov sp, r15
444c: b012 8a44 call #0x448a <check_password>
4450: 0f93 tst r15
4452: 0520 jnz #0x445e <main+0x26>
4454: 3f40 d444 mov #0x44d4 "Invalid password; try again.", r15
4458: b012 6645 call #0x4566 <puts>
445c: 093c jmp #0x4470 <main+0x38>
445e: 3f40 f144 mov #0x44f1 "Access Granted!", r15
4462: b012 6645 call #0x4566 <puts>
4466: 3012 7f00 push #0x7f
446a: b012 0245 call #0x4502 <INT>
446e: 2153 incd sp
4470: 0f43 clr r15
4472: 3150 6400 add #0x64, sp

This looks similar to the last binary, however, we can see that the create_password() subroutine was removed. A function called check_password() exists and we can see that after the call is returned, r15 is tested. If that register does not contain 0, the code will eventually hit the jmp instruction at 0x445c and will subsequently exit without unlocking the door, so we need to make sure that when the call is returned, r15 contains a non-zero value.

Let’s dig deeper and see what’s going on inside check_password():

448a <check_password>
448a: bf90 3622 0000 cmp #0x2236, 0x0(r15)
4490: 0d20 jnz $+0x1c
4492: bf90 5355 0200 cmp #0x5553, 0x2(r15)
4498: 0920 jnz $+0x14
449a: bf90 5d59 0400 cmp #0x595d, 0x4(r15)
44a0: 0520 jne #0x44ac <check_password+0x22>
44a2: 1e43 mov #0x1, r14
44a4: bf90 3356 0600 cmp #0x5633, 0x6(r15)
44aa: 0124 jeq #0x44ae <check_password+0x24>
44ac: 0e43 clr r14
44ae: 0f4e mov r14, r15
44b0: 3041 ret

We can see that there are 4 cmp instructions occurring which will compare 8 hard-coded bytes, 2 at a time with 2-byte offsets from r15 (the start of our input in memory). If execution can reach the final cmp instruction, the program will jump over the clr r14 instruction at 0x44ac, which means that when mov r14, r15 is executed, r15 will have a non-zero value (and instead will contain 0x1 which was set by the previous 44a2: mov #0x1, r14 instruction). Once execution is returned back to main(), the subsequent tst r15 instruction will cause the jump to 0x445e to occur, which will print the access granted message and proceed to unlock the door. Let’s grab those 8 hard coded bytes and try it out. Don’t forget that MSP430 byte pairs are little-endian, so we’ll need to reverse the byte order.

Reykjavik Sydney Solved

Flag (mouse over to reveal)

362253555d593356

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