May 02, 2019

Microcorruption - New Orleans

This is the another post about Microcorruption CTF where we’ll be solving the NEW ORLEANS challenge. So let’s start.


THE CHALLENGE

This is the first DIY Microcorruption Challenge as it no longer guides & gives hints to exploit the code. You have to figure it out all by yourself.

So let’s proceed to solve this level.
I always start by examining the main function.

4438 <main>
4438:  3150 9cff      add	#0xff9c, sp
443c:  b012 7e44      call	#0x447e <create_password>
4440:  3f40 e444      mov	#0x44e4 "Enter the password to continue", r15
4444:  b012 9445      call	#0x4594 <puts>
4448:  0f41           mov	sp, r15
444a:  b012 b244      call	#0x44b2 <get_password>
444e:  0f41           mov	sp, r15
4450:  b012 bc44      call	#0x44bc <check_password>
4454:  0f93           tst	r15
4456:  0520           jnz	#0x4462 <main+0x2a>
4458:  3f40 0345      mov	#0x4503 "Invalid password; try again.", r15
445c:  b012 9445      call	#0x4594 <puts>
4460:  063c           jmp	#0x446e <main+0x36>
4462:  3f40 2045      mov	#0x4520 "Access Granted!", r15
4466:  b012 9445      call	#0x4594 <puts>
446a:  b012 d644      call	#0x44d6 <unlock_door>
446e:  0f43           clr	r15
4470:  3150 6400      add	#0x64, sp

This code is similar to previous one & the code flow is super simple to understand. The create_password routine is run to create the password then a user input is taken via get_password routine & then the input is checked using check_password routine.

Now let’s examine the create_password routine.

447e <create_password>
447e:  3f40 0024        mov     #0x2400, r15
4482:  ff40 3a00 0000   mov.b	#0x3a, 0x0(r15)
4488:  ff40 3700 0100   mov.b	#0x37, 0x1(r15)
448e:  ff40 5d00 0200   mov.b	#0x5d, 0x2(r15)
4494:  ff40 7100 0300   mov.b	#0x71, 0x3(r15)
449a:  ff40 2900 0400   mov.b	#0x29, 0x4(r15)
44a0:  ff40 4000 0500   mov.b	#0x40, 0x5(r15)
44a6:  ff40 4600 0600   mov.b	#0x46, 0x6(r15)
44ac:  cf43 0700        mov.b	#0x0, 0x7(r15)
44b0:  3041             ret

This routine seems to move bytes using mov.b at incrementing offsets relative to 0x2400 & the last one moves a null byte to last memory location. So it’s probably the password we are looking for.

Now let’s examine the check_password routine.

44bc <check_password>
44bc:  0e43           clr	r14
44be:  0d4f           mov	r15, r13
44c0:  0d5e           add	r14, r13
44c2:  ee9d 0024      cmp.b	@r13, 0x2400(r14)
44c6:  0520           jne	#0x44d2 <check_password+0x16>
44c8:  1e53           inc	r14
44ca:  3e92           cmp	#0x8, r14
44cc:  f823           jne	#0x44be <check_password+0x2>
44ce:  1f43           mov	#0x1, r15
44d0:  3041           ret
44d2:  0f43           clr	r15
44d4:  3041           ret

This routine has the same offsets at address 0x44c2 as we had in the create_password routine. We can easily interpret that create_password writes the password to memory, check_password just compares those bytes to the ones entered by the user.

SOLUTION

The real password is in the code itself in form of hex. We just have to enter it. So, to solve this challenge just extract the bytes moved in r15 in create_password routine & pass it through.

PASSWORD : :7]q)@F
PASSWORD[hex] : 3a375d7129404600


This was also an easy one & I tried to keep it short & simple & didn’t went much deeper. Hope you understood it.

That’s it for this one.
Good Bye !!!