In this manual, you notice that:
- This lock is attached to HSM-1 module.
- The conditional flag that accidentally gets set when very long passwords are put in, has been removed.
After a fast fail using a test input: aaaaaaaaaaaaaaaa
, turns out the program does not exit. It instead, loops back to the start of the program.
This is interesting. Why? Because it is a clue that at some point at the end of a failed password verification; instead of a program exit, the return address points to the beginning instruction to jump to. This shall become clear soon.
You do a slow step through the program. The main
function just calls the login
function.
- Written in the prompt display, passwords required to be
8 -16
characters. - the
getsn
function takes two params:
// length limits input buffer length
void gets(char *buf, unsigned int length)
r15
holds the address that points to the input buffer(where the input would be stored) =sp
.
r14
holds the input length0x30
. This is 48; which is waay more than the specified range limit of8 - 16 bytes
. This definitely smells like an exploitable clue :)
test_valid_password
gets called after input. This function basically, makes a call toINT 0x7D
to test password validity and sets flag value.
With the input you used, the password validation fails. Observe.
:D… :D
The return address is in the value of the next bytes after a 16 byte
input; which with the initial clue of input length, can be overwritten. Another input test can be done.
The return address now gets set to 6161
(aa
<- 17-18th
input bytes). This time the program exits because 0x6161
is an invalid address.
Now that this is known, what needs to be done is to manipulate the 17 -18th
input bytes; so that PC
gets loaded with a valid address that will jump to where you want it: call to unlock_door
.
Following through the login
function code, this call to unlock_door
is at address 0x4528
. What’s next?
Note on endianness. This processor uses
little endian
byte ordering.
Aaaand..
Unlocked and unloaded!!