08 Microcorruption - Johannesburg
We now travel to South Africa, Johannesburg
Manual
Lockitall LOCKIT PRO r b.04
______________________________________________________________________
User Manual: Lockitall LockIT Pro, rev b.04
______________________________________________________________________
OVERVIEW
- A firmware update rejects passwords which are too long.
- This lock is attached the the LockIT Pro HSM-1.
DETAILS
The LockIT Pro b.04 is the first of a new series of locks. It is
controlled by a MSP430 microcontroller, and is the most advanced
MCU-controlled lock available on the market. The MSP430 is a very
low-power device which allows the LockIT Pro to run in almost any
environment.
The LockIT Pro contains a Bluetooth chip allowing it to
communiciate with the LockIT Pro App, allowing the LockIT Pro to
be inaccessable from the exterior of the building.
There is no default password on the LockIT Pro HSM-1. Upon
receiving the LockIT Pro, a new password must be set by first
connecting the LockitPRO HSM to output port two, connecting it to
the LockIT Pro App, and entering a new password when prompted, and
then restarting the LockIT Pro using the red button on the back.
LockIT Pro Hardware Security Module 1 stores the login password,
ensuring users can not access the password through other means.
The LockIT Pro can send the LockIT Pro HSM-1 a password, and the
HSM will return if the password is correct by setting a flag in
memory.
This is Hardware Version B. It contains the Bluetooth connector
built in, and two available ports: the LockIT Pro Deadbolt should
be connected to port 1, and the LockIT Pro HSM-1 should be
connected to port 2.
This is Software Revision 04. We have improved the security of the
lock by ensuring passwords that are too long will be rejected.
(c) 2013 LOCKITALL Page 1/1
This lock has the HSM-1, and should be rejected passwords that are too long, let’s see how they do that.
Enumeration
Let’s check main
Main
╭ int main(int argc, char **argv, char **envp);
╰ 0x4438 call #login
The pattern continues
Login
╭ login();
│ 0x452c add #0xffee, sp
We make room on the stack, so we calculate the stack pointer 0x4400 - 0x2 + 0xffee = 0x143ec
, the new stack pointer is 0x43ec
this give us 18 byte stack space for login
and the return address would then be on byte 19 and 20
│ 0x4530 mov.b #0x00da, 0x11(sp)
This one is new, we write the value 0xda
to 0x11+0x43ec = 0x43fd
, at the bottom of the stack space we just allocated. This is a trick known as a stack canary, it is a way to protect the stack from overflows. Of course this way of doing it is quite easy to bypass because we just need our payload to have the value 0xda
at the same place. But ideally you would create a random value on the stack that you then check after to see that the stack has not been overflown.
│ 0x4536 mov #0x447c, r15
│ 0x453a call #puts
│ 0x453e mov #0x449c, r15
│ 0x4542 call #puts
This part we know, two print statements
│ 0x4546 mov #0x003f, r14
│ 0x454a mov #0x2400, r15
│ 0x454e call #getsn
Then we have a getsn
, reading 63 bytes this time, that is a lot.
│ 0x4552 mov #0x2400, r14
│ 0x4556 mov sp, r15
│ 0x4558 call #strcpy
We have the strcpy
as before, so we need to avoid null bytes again
│ 0x455c mov sp, r15
│ 0x455e call #test_password_valid
│ 0x4562 tst r15
│ ╭─< 0x4564 jeq $+0x000c
│ │ 0x4566 call #unlock_door
│ │ 0x456a mov #0x44d1, r15
│ ╭──< 0x456e jmp $+0x0006
│ │╰─> 0x4570 mov #0x44e1, r15
│ ╰──> 0x4574 call #puts
We have the password validation and door unlock
│ 0x4578 cmp.b #0x00da, 0x11(sp)
│ ╭─< 0x457e jeq $+0x000e
│ │ 0x4580 mov #0x44ff, r15
│ │ 0x4584 call #puts
│ │ 0x4588 br #__stop_progExec__
│ ╰─> 0x458c add #0x0012, sp
╰ 0x4590 ret
Here we have the stack check, to see if the value 0xda
was change, if it was, we do a print and exit the program.
Exploit
This lock is using the HSM-1, so we can go back and use the method where we just jump to the unlock_door
function. So our payload is 17 random bytes (not null bytes) then 0xda
followed by the address of unlock_door