Another Microcorruption CTF level!
Sydney & New Orleans Writeups
New Orleans Writeup

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
So let’s take a look at the main function given here.
A few interesting routines stand out, namely the create_password and check_password. Let’s take a look at both of them and analyze them.
```
447e <create_password>
447e: 3f40 0024 mov #0x2400, r15
4482: ff40 3400 0000 mov.b #0x34, 0x0(r15)
4488: ff40 4c00 0100 mov.b #0x4c, 0x1(r15)
448e: ff40 6200 0200 mov.b #0x62, 0x2(r15)
4494: ff40 6300 0300 mov.b #0x63, 0x3(r15)
449a: ff40 5b00 0400 mov.b #0x5b, 0x4(r15)
44a0: ff40 6800 0500 mov.b #0x68, 0x5(r15)
44a6: ff40 7100 0600 mov.b #0x71, 0x6(r15)
44ac: cf43 0700 mov.b #0x0, 0x7(r15)
44b0: 3041 ret
```
We can see from the above code that certain bytes are being moved in an incremental manner into bytes from the offset 0x2400.
The last byte stored is the null byte as shown in 44ac.
Now let us take a look at the check_password function
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
Hmm, so the value stored in r13 is compared.
Let us take a closer look at 44c2
44c2: ee9d 0024 cmp.b @r13, 0x2400(r14)
44c6: 0520 jne #0x44d2 <check_password+0x16>
So the password is compared relative to the memory location.
Let’s put a breakpoint on 44c2 and then enter some random input.
Once we hit our breakpoint, we can read the value stored, shown below
> r 2400 8
2400: 344c 6263 5b68 7100 4Lbc[hq.
2408: 0000 0000 0000 0000 ........
2410: 0000 0000 0000 0000 ........
2418: 0000 0000 0000 0000 ........
So the password is stored in the hex bytes 344c 6263 5b68 7100
We can solve the lock by submitting the password after enabling the hex input option
Another method:
We can create a breakpoint at 4400 we can read the memory address at 2400.
In the raw memory dump:
0150: 0000 0000 0000 0000 0000 0000 085a 0000 .............Z..
0160: *
2400: 344c 6263 5b68 7100 0000 0000 0000 0000 4Lbc[hq.........
2410: *
4390: 0000 0000 0000 0000 0000 4044 0000 0000 ..........@D....
43a0: *
4400: 3140 0044 1542 5c01 75f3 35d0 085a 3f40 1@.D.B\.u.5..Z?@
Which once again gives us 344c 6263 5b68 7100.
or 4Lbc[hq
Sydney

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
Once again, let us take a look at check_password
448a: bf90 7a3f 0000 cmp #0x3f7a, 0x0(r15)
4490: 0d20 jnz $+0x1c
4492: bf90 642c 0200 cmp #0x2c64, 0x2(r15)
4498: 0920 jnz $+0x14
449a: bf90 3773 0400 cmp #0x7337, 0x4(r15)
44a0: 0520 jne #0x44ac <check_password+0x22>
44a2: 1e43 mov #0x1, r14
44a4: bf90 456e 0600 cmp #0x6e45, 0x6(r15)
44aa: 0124 jeq #0x44ae <check_password+0x24>
44ac: 0e43 clr r14
44ae: 0f4e mov r14, r15
We can see that we are comparing bytes to the bytes relative to r15
We can decipher the password from this so we get: 3f7a 2c64 7337 6e45
However, since these are in Little Endian, we must convert them.
Therefore password is 7a3f 642c 3773 456e which is to be input in hex
Previous in this series: Level 0
Sydney & New Orleans Writeups
Leave a Reply