Microcorruption 0x05 - Johannesburg

Prev: 0x04 Cusco
Next: 0x06 Reykjavik

This level’s manual explains that passwords which are too long will be rejected. If we test this by entering a long password, we can see that we receive an additional “Invalid Password Length: password too long” error message. Let’s check to see what’s going on here – set a breakpoint in “login” after the “strcpy,” which we know copies the password retrieved from the “getsn” call into memory (though we can confirm this by referencing the assembly and finding the loop of "mov.b" instructions). Enter a long password when prompted.


Once we hit our break, we can see that all 0x3f bytes of our password string was copied from address 2400 onto the stack at address 43ec. And, naturally the “test_password_valid” function rejects our password and thus does not place a value into r15. We exit that function, fail the following “tst r15” instruction, and get the “That password is not correct” string that we are familiar with. After this function, however, are some new instructions:


There's now a “cmp.b” instruction which compares the value “0xd8” with “0x11(sp).” Sp is currently set at 43ec, which is the address of our password, so “0x11(sp)” is 17 bytes from the password buffer. This “0xd8” value is similar to a stack canary: the function expects this value to be here after the “strcpy,” and if it can’t find it, it surmises that the intended boundary of the password buffer (16 bytes) has been overflowed. As a result, it throws the “password too long” error message and immediately exits.

In modern programs, stack canaries are generated randomly at runtime so that they cannot be found in a debugger, and are often larger than one byte so that they cannot be brute-forced easily.

Here, however, the “canary” is in plain sight. If we want to use a long password to overflow the 16-byte buffer and change the “ret” address within the “login” function, we’ll need to make sure that the 11th byte of our password is “0xd8” (or technically the 12th byte, as the value will be interpreted as little-endian and “swapped” into the 11th position). After that, we can include the address of “unlock_door” which will overwrite “ret.”

Here’s what I used as my password: “4141414141414141414141414141414141d84644”

Prev: 0x04 Cusco
Next: 0x06 Reykjavik