May 03, 2019

Microcorruption - Sydney

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


While going through the description of this challenge you’ll come to know that unlike the previous one, the password isn’t present in the memory.

This is Software Revision 02. We have received reports that the prior version of the lock was bypassable without knowing the password. We have fixed this and removed the password from memory.

So let’s proceed to solve this level.
As always, let’s start by examining 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

The code flow here is very close to the previous one except the create_password routine has been removed. The check_password routine looks interesting here. Let’s take a closer look.

448a <check_password>
448a:  bf90 2457 0000 cmp	#0x5724, 0x0(r15)
4490:  0d20           jnz	$+0x1c
4492:  bf90 555b 0200 cmp	#0x5b55, 0x2(r15)
4498:  0920           jnz	$+0x14
449a:  bf90 427a 0400 cmp	#0x7a42, 0x4(r15)
44a0:  0520           jne	#0x44ac <check_password+0x22>
44a2:  1e43           mov	#0x1, r14
44a4:  bf90 4924 0600 cmp	#0x2449, 0x6(r15)
44aa:  0124           jeq	#0x44ae <check_password+0x24>
44ac:  0e43           clr	r14
44ae:  0f4e           mov	r14, r15
44b0:  3041           ret

While examining the main routine, we observe that right before calling check_password, mov sp, r15 instruction is executed at 0x444a. So, r15 is the location where the user input is being stored & here in the check_password routine its relatives are being compared to some other arguments using cmp which compares a word unlike cmp.b which compares a byte.

You’ll also observe that there is a jump instruction after every compare instruction. There the $ operator represents the address of the Program Counter(PC) reffered as Instruction Pointer(IP).

In this way the check_password routine checks if
contents of r15 -r15+1 is 0x5724
contents of r15+2-r15+3 is 0x5b55
contents of r15+4-r15+5 is 0x7a42
contents of r15+6-r15+7 is 0x2449

In layman’s terms, r15 is checked against 0x57245b557a422449.


So that’s our 8 bytes password. But its not that easy.
Data Representation in memory is done here in little-endianess.
This architecture uses a 16-bit addressing mode, so we have to convert each 2 bytes & then pass it through.

PASSWORD[hex] : 2457555b427a4924

This was also a little tricky one & I tried to do it quick & easy.
Hope you understood it.

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