You find a manual:
- This lock is attached to HSM-2 module. This means, no unlock door function in the lock firmware. This reminds you of a while back in WhiteHorse.
- The code follows internal secure development process. mmh.
The main
function just calls login
.
The prompt states for an input range of
8 - 16
characters. However, from the input togetsn
function:r14
: this holds the length of the input buffer;0x30(48)
characters. Clue #1r15
: this holds the address to the input buffer;#0x2400
.
The input is copied to an address. This is what is new from the Whitehorse challenge and you put a note here:
NB:
strcpy
function operates on null-ended strings. What this means is that whenever it encounters a null in a string, this marks the end of the string. It copies until there.Note to self: Do not use null bytes in the middle of the input here!
memset
function is called. From the parameters pass into it, you can tell the input(at#0x2400
) is being replaced by zeros(cleared). There is a hunch here that clearing the input is to prevent things like jumping to instructions injected at the input that might not pass throughstrcpy
. It shall become clear soon.- The copied input is then passed to
conditional_door_unlock
function. This function calls an interruptINT 7E
that handles the validation of the password and unlocking of the door. - Notice the return address is the value in the address
add 0x10, sp
. Clue #2
A look at the conditional_door_unlock
function:
You do a quick run with a test input aaaaaaaaaaaaaaaaaa
of 18 characters. This is observed:
- The
17th -18th
bytes of the input overflow intoSP
. The return address is in these bytes. You can now jump to another address and execute instructions at that address. You know what this means.. can be shellcoded!
You would want to jump to the beginning of the injected shellcode.
From the manual, INT7F
actually triggers the unlock. If this is pushed instead of 7E
and an interrupt is called, the door should unlock.
Payload final draft #1:
Null byte.. big no no. Want to see it?
Because of the null byte, the copy will be unfinished therefore the payload incomplete thus plan fails.
Why not remove the null byte? Why is it there anyway? Answer: The lock’s microprocessor(MPS430) has a mandatory memory alignment of 2-bytes. This means instructions, values etc, have to follow this alignment. Therefore,
0x7f
has to be written as#0x007f
. Also, because the microprocessor follows little-endian ordering, thus,#0x007f
is eventually inputted as#0x7f00
.Read more here.
The null has to be done away with, but hooow? You need to find a way to push 0x007f
without there being a null byte in the payload? We can calculate it.
Find two numbers whose addition/subtraction results in #0x007f
. You decide to use 0x0212
and 0x0193
. Substracting the latter from the former results in 0x7f
. Sweet!
Now to assemble the payload.
Payload final final draft:
This should work. You input:
and the door opens for you!
Onwards to Novosibirsk..