Microcorruption (Embedded Security CTF): Montevideo

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:  

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:  


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:  


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:  


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:  


To solve this level, type solve and then enter the payload.