Nice! Here is a lock. This is the manual:
- Passwords that are too long are rejected.
There is not much clues from the manual.
The main
function just calls the login
function:
Authentication requires a username and password input. The prompt states that these inputs should be between 8 and 16 chars. :D
Bytes
0x0, 0x8 and 0x10
are set into the addresses atr4 - (0x6, 0x19,0x18)
respectively. This will probably make sense soon.The
getsn
function for getting the username:- length of input buffer: held at
r14
->0x63(99)
characters. :D - address to the input buffer: held at
r15
->0x2404
.
- length of input buffer: held at
Call to
strcpy()
for username input to address0x43a2
(this gets evident while running the program.)The
getsn
function for getting the password:- length of input buffer: held at
r14
->0x63(99)
characters. - address to the input buffer: held at
r15
->0x2404
.
- length of input buffer: held at
Call to
strcpy()
for username input to address0x43b5
(this gets evident while running the program.)
The address where the password input is copied to by the
strcpy()
is interesting. It is only0x43b5 - 0x43a2 = 0x13(19)
bytes apart.What this means is: for a username input > 19, the extra bytes get overriden by the password copy. This aaalso means that it is possible to write well beyond the password content copy if there’s is any constraint on the password input buffer. :D
Smells and definitely quacks like a clue!!
You run a test run to get a feel on the program. Since the provisioned length of the input buffer is greater than the prompted one:
The program proceeds…
there is a
cmp
operation done between the length of the copied username input and the value atr4(0x43cc) - 0x18 = 0x43b4
: this was originally set to0x10
.This value gets overwritten by the
19th
username input byte:0x61
(remember that thestrcpy
dest address for username input is0x43a2
from earlier).Since
r15(0x61) > r11(0x18)
, no carry flag is set.(For more on this, refer to previous notes. The program continues.
- there is another
cmp
operation between length of copied username input and value atr4(0x43cc) - 0x19 = 0x43b3
: this was originally set to0x8
. This value is now0x61
(the 18th byte of username input).- The program advances only when the carry flag is set. This means,
r15
value has to be less thanr11
. - The
18th
byte of the username has to be less than the length!
- The program advances only when the carry flag is set. This means,
You run a test to bypass this:
The authentication check fails, but the program proceeds:
Can the return address be modified?
- Probably, but first, there is a
tst.b
that happens before.- The byte at address
-0x6(r4) = 0x43c6
has to be zero for the program to proceed to fetch the return address to jump to. - This byte being checked is the
18th
byte of the password input. You can have the password terminate with zero byte on the 18th byte.
- The byte at address
You rerun a test with these steps:
The return address is at
0x43c8
. If you can find a way to modify this, you can jump to the call tounlock_door
at address0x463a
.- Cannot use password input for this; because of
strcpy()
. The zero byte will terminate the copy and the bytes after will not be copied.
- Cannot use password input for this; because of
- You can use the username input for this. If you recall from earlier: it is possible to write well beyond the password content copy and the extra bytes get overriden by the password copy.
Basically, have a username input extend enough to modify the return value.
You give this a try with the following input:
username:
password:
This is what you observe:
Another one down!
Onwards and Algiers. _0/