Microcorruption
Microcorruption CTF is a capture the flag (CTF) competition designed to teach low-level reverse engineering by pitting the user against a lock mechanism running on a simulated MSP430 controller. The user exploits MSP430 assembly to gain access to the device and unlock the door.
Microcorruption (Johannesburg)
- This is Software Revision 04. We have improved the security of the lock by ensuring passwords that are too long will be rejected.
Long Passwords
Let's test a long input: 0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
This stores the input starting at 0x2400 and allows input up to 0x243E (62 bytes) and copies the input to 0x43EC-0x442F (43 bytes)
<main>
call #0x452c <login><login>
add #0xffee, sp
mov.b #0xec, 0x11(sp) ; Move 0xEC to SP + 0x11
;
call #0x4624 <strcpy> ; Copy the input string from 0x2400
mov sp, r15
call #0x4452 <test_password_valid> ; Check the validity of the password
tst r15
jz $+0xc <login+0x44> ; If not valid jump over this line
call #0x4446 <unlock_door> ; If valid, unlock th door
cmp.b #0xec, 0x11(sp) ; Is 0xEC still at SP + 0x11?
jz $+0xe <login+0x60> ; Jump if 0xEC hasn't been overwritten
mov #0x44ff "Invalid Password Length: password too long.", r15
call #0x45f8 <puts>
br #0x443c <__stop_progExec__>
add #0x12, sp ; Jump here if 0xEC isn't overwritten
retThe login function is storing a guard value 0xEC at 0x43FD and using it to check that the copied input string is under 16 bytes (in theory; it actually only triggers if you write 18 bytes). If the password has overwritten the 0xEC it will print the error to the user and exit.
If it's not overwritten, the <login> function returns to the address stored in the stack pointer 0x43FE. Since this is within our buffer overflow range, at byte 18, we can write an address in our password as long as the 0xEC value is still at byte 17.
<unlock_door>
push #0x7f
call #0x4594 <INT>
incd sp
retThis function will pass the 0x7F argument that will open the door for us.
Solution
0102030405060708090A0B0C0D0E0F1011EC4644