There’s a manual:
- Passwords that are too long are rejected. There is additional mechanisms to verify password length.
- The lock is attached to LockIT Pro HSM-1.
The main
function just calls login
.
login
function is quite long:
Authentication requires a username and password input. The prompt states that these inputs together may not be more than 32 characters. :D
The
gets
function for getting the username:- length of input buffer: held at
r14
->0xff(255)
characters. Mmmh, interesting considering the rule provided earlier. - address to the input buffer: held at
r15
->0x2402
.
- length of input buffer: held at
There is a length check on the username input:
r15 = 0x2402
for *r15 != 0{
r15++
}
r11 = r15
r11 -= 0x2402 ; this gives the length of the username input.
cmp.b(0x21, r11) ; this compares if the input is less than 0x21(33) characters.
; checks the carry flag. jnc implies the input length less than 0x21.
- Call to
strcpy()
. The username input copied to0x3ff2
.(this is the address the stack pointer points to). - The
gets
function for getting password:- length of input buffer: at
r14
->0x1f(31) - r11(length of username input) & 0x1ff
characters. Capped at 31 characters. (This is maximum input, in case username was empty.) - address to input buffer: at
r15
->0x2402
.
- length of input buffer: at
An interesting discovery on calculating the length of input passed to
getsn
on the password input.If the username input is maximum length, a buffer underflow occurs! :D
- Call to
strcpy()
. The password input copied to0x3ff2 + length of username input
. - Another length check is done. This once checks the total length of username + the password inputs. Address to the copied content is passed for a call to
test_username_and_password_valid
. - A byte set at
r15
is checked if zero and this determines the call tounlock_door
.
Time to get down and dirty!
You run a test input with the maximum username input and follow the progression:
This will cause an underflow as you observed earlier;
Sweet! You can now have long password input. However, there is still a barrier that you need to bypass: the cmp.b #0x21, r15
. The total length of username + password is checked to ensure it is not more than 0x21
.
Looking at
cmp.b
instruction from the user guide: this operation compares the last byte of the source operand from the destination operand.
You just need to ensure that the last byte of r15
(the total length of user + pass) is less than 0x21
. The minimum value for this would be 0x100(256)
chars. Since the username length is already 0x20
, the password length needs to be 0x100 - 0x20 = 0xe0(224) characters
.
Authentication fails as expected(this was a test run). You notice though, that the return address is now overwritten by the copied content.
Can almost see the victory now…
You need to modify the 5th and 6th byte of the password input to the call to unlock_door
address at 0x461c
. You try a 32 char username input and this password input:
You cracked it! :D
Santa Cruz is your oyster now.