blog/01-microcorruption

01 Microcorruption - New Orleans

Completing the tutorial gave us access to New Orleans, so let’s take a look at the lock there.

Manual
Lockitall                                            LOCKIT PRO r a.01
______________________________________________________________________

              User Manual: Lockitall LockIT Pro, rev a.01

---

OVERVIEW

    - This is the first LockIT Pro Lock.
    - This lock is not attached to any hardware security module.

DETAILS

    The LockIT Pro a.01  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---upon receiving
    the LockIT Pro, a new password must be set by connecting it to the
    LockIT Pro  App and  entering a password  when prompted,  and then
    restarting the LockIT Pro using the red button on the back.

    This is Hardware  Version A.  It contains  the Bluetooth connector
    built in, and one available port  to which the LockIT Pro Deadbolt
    should be connected.

    This is Software Revision 01.

(c) 2013 LOCKITALL Page 1/1

We get some information about the setup, and again the lock is not connected to any external modules, so we can assume that the passcode to open the lock will be in the code. This time we will just go straight to the main function.

Enumeration

Main

Without going through each line of code, we will try to get an overview of the flow in the code from when main starts. Let’s take a look at what functions main call.

int main(int argc, char **argv, char **envp);
0x4438      add   #0xff9c, sp
0x443c      call  #create_password
0x4440      mov   #0x44e4, r15
0x4444      call  #puts
0x4448      mov   sp, r15
0x444a      call  #get_password
0x444e      mov   sp, r15
0x4450      call  #check_password
0x4454      tst   r15
│       ╭─< 0x4456      jnz   $+0x000c
│       │   0x4458      mov   #0x4503, r15
│       │   0x445c      call  #puts
│      ╭──< 0x4460      jmp   $+0x000e
│      │╰─> 0x4462      mov   #0x4520, r15
│      │    0x4466      call  #puts
│      │    0x446a      call  #unlock_door
│      ╰──> 0x446e      clr   r15
0x4470      add   #0x0064, sp
  1. create_password - seem like an interesting function to look at
  2. puts - we know this one, just print a string to the screen
  3. get_password - this one is also familiar, guess it takes the password as input
  4. check_password - assume we check the inputted password here
  5. unlock_door - The goal 🏆

In the previous post the secret to a valid password was “hidden” in check_password, but something seems to keep my eyes focused at the create_password function. Let’s have a look.

Create_password

From main we saw that there were no arguments passed to the create_password function.

╭ create_password();
0x447e      mov   #0x2400, r15
0x4482      mov.b #0x0048, 0x0(r15)
0x4488      mov.b #0x0073, 0x1(r15)
0x448e      mov.b #0x004c, 0x2(r15)
0x4494      mov.b #0x0055, 0x3(r15)
0x449a      mov.b #0x0050, 0x4(r15)
0x44a0      mov.b #0x0028, 0x5(r15)
0x44a6      mov.b #0x0060, 0x6(r15)
0x44ac      clr.b 0x7(r15)
0x44b0      ret

The code starts by moving a value into R15, this value is then used as an address and offset by some bytes while different bytes are moved into this place. Let’s try to see what is located at this 0x2400 address.

- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x2400      0000 0000 0000 0000 0000 0000 0000 0000  ................

A bunch of zeroes, so the create_password function is not overwriting anything. Let’s try to figure out what it is writing to this location. If we concatenate the bytes from the code we get 0x48 0x73 0x4C 0x55 0x50 0x28 0x60. All these bytes is in the ASCII range, so we can convert them to ASCII characters, this gives us HsLUP(`

check_password

Lets for completeness look at the check_password function

╭ check_password();
0x44bc      clr   r14
│       ╭─> 0x44be      mov   r15, r13
│       ╎   0x44c0      add   r14, r13
│       ╎   0x44c2      cmp.b @r13, 0x2400(r14)
│      ╭──< 0x44c6      jnz   $+0x000c
│      │╎   0x44c8      inc   r14
│      │╎   0x44ca      cmp   #8, r14
│      │╰─< 0x44cc      jnz   $-0x000e
│      │    0x44ce      mov   #1, r15
│      │    0x44d0      ret
│      ╰──> 0x44d2      clr   r15
0x44d4      ret

And surely enough we can see the address 0x2400 is used here as well. And we compare each byte of the created password with presumably the inputted password.

Door unlocked

/microcorruption/