MicroCorruption: Montevideo

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 to getsn function:

    • r14: this holds the length of the input buffer; 0x30(48) characters. Clue #1
    • r15: 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 through strcpy. It shall become clear soon.
  • The copied input is then passed to conditional_door_unlock function. This function calls an interrupt INT 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 into SP. 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 0x007fwithout 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..

MicroCorruption: Johannesburg

MicroCorruption: Reykjavik

comments powered by Disqus