TIL that the capital of Uruguay is Montevideo. This is the next level in Microcorruption, which was unlocked after I completed Whitehorse.
If we read the release notes, it says:
Lockitall developers have rewritten the code to conform to the internal secure development process.
Lol okay, whatever that means.
Hahaha oh no. Let’s get started!
Montevideo Code
If we have a look around, we see:
Login
is a bit longer this time:
44f4 <login>
44f4: 3150 f0ff add #0xfff0, sp
44f8: 3f40 7044 mov #0x4470 "Enter the password to continue.", r15
44fc: b012 b045 call #0x45b0 <puts>
4500: 3f40 9044 mov #0x4490 "Remember: passwords are between 8 and 16 characters.", r15
4504: b012 b045 call #0x45b0 <puts>
4508: 3e40 3000 mov #0x30, r14
450c: 3f40 0024 mov #0x2400, r15
4510: b012 a045 call #0x45a0 <getsn>
4514: 3e40 0024 mov #0x2400, r14
4518: 0f41 mov sp, r15
451a: b012 dc45 call #0x45dc <strcpy>
451e: 3d40 6400 mov #0x64, r13
4522: 0e43 clr r14
4524: 3f40 0024 mov #0x2400, r15
4528: b012 f045 call #0x45f0 <memset>
452c: 0f41 mov sp, r15
452e: b012 4644 call #0x4446 <conditional_unlock_door>
4532: 0f93 tst r15
4534: 0324 jz #0x453c <login+0x48>
4536: 3f40 c544 mov #0x44c5 "Access granted.", r15
453a: 023c jmp #0x4540 <login+0x4c>
453c: 3f40 d544 mov #0x44d5 "That password is not correct.", r15
4540: b012 b045 call #0x45b0 <puts>
4544: 3150 1000 add #0x10, sp
4548: 3041 ret
Basically, we are:
- Prompting the user for a password, and warning them about password length.
- Getting the user’s input
- Strcpy-ing that input elsewhere
- Using memset
- Calling
conditional_unlock_door
- Then reporting back to the user if their attempt worked or not.
- Then adding 0x10 to the stack pointer and returning.
Conditional_unlock_door
looks very similar (possibly identical?) to the function in Whitehorse. If you remember from that level, we ignored the conditional_unlock_door
function and focused on the interrupt.
We overwrote the interrupt type to be “7f” which means “unconditionally unlock the door.” For a refresher on the interrupt types, take a look at the manual.
Since we’ve got the “add 0x10 and return” thing going on here, too, let’s try to use a buffer overflow to redirect the program.
Redirecting => Interrupt
From the Whitehorse level, you might remember that we gave an input of:
4141414142424242434343434444444432457f007f00
The ‘3245’ in there refers to the location of the interrupt function in that level. It’s different for Montevideo, though.
We can see that it’s 0x454c, which we need to enter as “4c45” instead.
So, we have:
414141414242424243434343444444444c457f007f00
Let’s give that a shot, with a breakpoint set at the end of conditional_unlock_door
(446e):
And as expected, we get to here:
If we step over this, we see that r14 gets a value of… 44. Wait, what?
We told it to have “7f”. What’s going on?
If we looked at 0x2400 block of memory after the gets
call, we would see:
We sent “414141414242424243434343444444444c457f007f00” and it’s all there. So far, so good.
But after the strcpy
, we see that the last part of our string is truncated.
Why is this happening?
My guess is that strcpy sees a 0x0 and thinks that it’s a null byte, and the string should be terminated. That means we’ll have to use something else instead of “00”.
Buffer Overflow 2: Electric Boogaloo
If we try this again, but we get rid of the 0’s at the end of our string (lest they be mistaken for null bytes), we have:
414141414242424243434343444444444c457f7f7f00
The ending “00” is fine, and in fact, we need it so that the sr
doesn’t get messed up.
If we use our breakpoint and stop at the INT function (after the ret
at the end of login
):
We can see that our memory now looks like this. Two bytes over from the stack pointer is “7f00” instead of “0044” (from before we fixed our null char issue).
If we step a few times, we see that our attempt to overwrite the interrupt type from 7e to 7f worked:
Montevideo Solution
Our payload to redirect the program and overwrite the conditional interrupt type to be conditional, via buffer overflow, is:
414141414242424243434343444444444c457f7f7f00
To solve this level, type solve
and then enter the payload.