blog/08-microcorruption

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

Door unlocked

/microcorruption/