Finally, Canada! Looks like we’ve got some hardware updates in the Whitehorse level…
Some more details:
The LockIT Pro c.01 is the first of a new series of locks. ... This is Hardware Version C. It contains the Bluetooth connector built in, and two available ports: the LockIT Pro Deadbolt should be connected to port 1, and the LockIT HSM-2 should be connected to port 2.
We’ve got the usual
login setup that we’ve seen in other levels.
We once again see that there’s a notice about password length. Let’s remember to try that out later.
There’s also a conditional_unlock_door function, unlike the previous levels that had an (unconditional) function that we could jump to.
Testing Password Length
Let’s put a pin in that for now and test out the password length. I entered in “AAAABBBBCCCCDDDDEEEE” because I’m not very creative.
Here, we can see that the entire thing got copied into at least this part of memory, even though it has 20 chars (instead of a max of 16 chars).
I’m not sure if it gets used later, because I forgot to set a breakpoint.
But, something interesting happened:
insn address unaligned
Oooooh. 👀 Okay, so it tried to jump to “EE” (4545), thinking it was an address. Can we use this for something? Lol of course we can.
We’re already getting to 0x4446, albeit with the wrong information. Maybe we can try going somewhere else instead? Like the interrupt function.
Getting to the Interrupt
The interrupt’s address is 0x4532. So if we want to add that to our buffer overflow input, we need to write “3245”.
Also, set an interrupt the end of
login… this is where we’re rerouting program flow from.
If we enter in this as our password (that’s 4 A’s, 4 B’s, 4 C’s , 4D’s, and then our new address)
After you hit your breakpoint,
step once and you should be in the interrupt function (again). I didn’t set a breakpoint here because you’ll hit it a bajillion times (for printing, etc.).
What we’re going to do is look two bytes over from the stack pointer, and stuff that into r14. That gets moved into r15 (which has its bytes swapped) and then that gets moved into the status register. Why?
If we look at the manual, we’ll see that we need to pass some kind of code in so that the program knows what type of interrupt this is.
If we were to look at this process earlier on in program execution, when we were in interrupt for legitimate purposes, it’d look like this:
That “7e” is 2 bytes over from the sp, which means that this is going to be put into r14, then r15, and then the status register.
If we look at the manual again, we see that 7e corresponds to this type of interrupt:
Except that’s a problem, because we don’t have the password. Oooh, that’s bad. Okay, what’s our other option? Scroll down to the next page and you’ll see an interrupt type that takes no parameters, it just unlocks the door. Amazing.
If we can make the interrupt think it needs to execute a “7F” type interrupt, the door will unlock!
7F Interrupt Coming Right Up!
So back to where we were… we passed in the address of the interrupt so that we could redirect the program there at the end of the
login. We’re at the top of the interrupt function, let’s see what our memory view shows:
Two bytes over is… nothing. Oop. The program won’t like this.
But that’s not a big deal, because we know what we need to send: 7F.
I’ll admit that it still took me a minute to get the alignment of this right, but you need to tack on “7f00” at the end. You also need two bytes of filler space… I just repeated x7f00 twice. That gives you:
Stop at our
ret breakpoint once again, and then
step into the interrupt, and our memory looks like:
We now have “7f” in the correct place, so if we step through the interrupt, we’ll see the value transferred into r14, then r15, and then executed as a type of interrupt.
And the door unlocks!
To solve this level, type
solve and then enter in:
This uses a buffer overflow to redirect the program execution to 0x4532 (interrupt) and then execute a “7F” type interrupt, which unlocks the door.