Reverse Engineering My Home Security System: Decompiling Firmware Updates

Update: A few people were kind enough to correct me on some of my terminology. Where appropriate, 'decompiling' has been replaced with 'extracting'. My apologies if that confused or mislead anybody :) Updated post is here

A few weeks ago I got a home security system installed. The package included a 7-inch tablet called the Honeywell Tuxedo that mounts on the wall. It’s basically a primary controller for the security system. Given what’s been going on in the IoT space and just my pure curiosity, it didn’t take long before the poking and prodding began. My first approach was to treat it like a standard penetration test, identifying network services, lighting testing the web application and enumerating the attack surface. After the first two days of testing in my spare time, the thought occurred that it would suck to ruin the device by testing it too heavily. Nothing like breaking your system and telling support it’s because you fuzzed it to death.

Instead of investigating from the outside in, I decided to take a different approach and start looking at reverse engineering the firmware. However, as a penetration tester I’m completely out of my comfort zone; but there’s a first time for everything so bear with me.

Reading through the documentation of the Tuxedo there is a capability to install software updates via SD card. I also found where you can download the latest software update for the device. I couldn’t find any available source code on the web so perhaps this avenue is a good first step. At the time of this writing the latest software update is v5.3.9.0.

firmware download

The software downloads as a ZIP, and when extracted reveals an executable. Extracting the .exe shows the HDR files mentioned on the website, but what is an HDR file? I was expecting something like a .bin, and running file just shows they are data files. Not a lot of help.

bullz3ye@ubuntu:~/honeywell$ unrar x TUXW_V5.3.9.0_CN.exe

UNRAR 5.30 beta 2 freeware      Copyright (c) 1993-2015 Alexander Roshal


Extracting from TUXW_V5.3.9.0_CN.exe

Extracting  ProgCV.hdr                                                OK 
Extracting  seconboot.hdr                                             OK 
Extracting  app1.hdr                                                  OK 
Extracting  app2.hdr                                                  OK 
Extracting  app3.hdr                                                  OK 
Extracting  MCU.hex                                                   OK 
All OK
bullz3ye@ubuntu:~/honeywell$ ls
app1.hdr  app2.hdr  app3.hdr  honeywell.log  MCU.hex  ProgCV.hdr  seconboot.hdr  TUXW_V5.3.9.0_CN.exe  TUXW_V5.3.9.0_CN.zip
bullz3ye@ubuntu:~/honeywell$ file *.hdr
app1.hdr:      data
app2.hdr:      data
app3.hdr:      data
ProgCV.hdr:    data
seconboot.hdr: data

I spend entirely too much time googling what an HDR file is and how to decompress/extract/open it. Apparently an HDR is a high-dynamic-range image used for photography or something. I’m thinking, maybe Honeywell has some proprietary packaging tool that uses actual images for software updates?

funny-meme1

What really reinforced this thought pattern was when using strings I get tons of references to a Linux environment.

bullz3ye@ubuntu:~/honeywell$ strings *.hdr | grep Linux
Linux-2.6.31-207-g7286c01
Uncompressing Linux...
        Welcome to Freescale Semiconductor Embedded Linux Environment
No Linux %s Ramdisk Image
Linux
bullz3ye@ubuntu:~/honeywell$ strings *.hdr | grep bash
bash
bash
Ubashbug
bashbug
dabash
.bash_history
.bash_history
getopt-parse.bash
&getopt-test.bash
getopt-parse.bash
getopt-test.bash
bullz3ye@ubuntu:~/honeywell$ strings *.hdr | grep passwd
passwd
passwd
bullz3ye@ubuntu:~/honeywell$ strings *.hdr | grep Freescale
Freescale Semiconductor, Inc.
        Welcome to Freescale Semiconductor Embedded Linux Environment
CPU:   Freescale i.MX35 at1 %d MHz

How did an embedded linux environment get packaged/compiled into a literal image file? I was getting somewhere though using strings to grep for more keywords. Perhaps there really is a file system in all this. At the very least I know I’m dealing with an embedded linux environment, know the kernel version, and can later read up on Freescale to get an idea of my target and the build process. I continue to use strings in order to try and put the pieces together.

At the same time, I couldn’t find a single reference point between files with extension HDR and embedded linux or Honeywell. I started looking for any references regarding Honeywell Tuxedo code at all to see if I could get any indication as to what these files are and how they are used. I didn’t find much at all, but finally doing a search for honeywell app2.hdr I run across a repo in Github that saved the day.

Two shell scripts exists, yitiaolong.sh and vam_dailybuild.sh, both appear to have something to do with the compilation process.

github description

VAM apparently stands for VISTA Automation Module and is related to the Tuxedo. A youtube video shows the same interface that is on my Tuxedo device. Long story short these scripts had a wealth of useful information, but I’ll try to highlight some of the key points.

yitiaolong.sh

The code above shows project path to the Tuxedo source code and a project called Barracuda (which I’ve yet to dig into). A separate search shows that Barracuda is the web server of choice for the device, and is a separate task all together. Of course the first thing I do it try to access the source code but apparently the acssvn.honeywell.com site no longer exists. There were other past references to the Tuxedo project path online, leading me to think that at one point this repository was publicly available. Either way I can’t access it now.

Later I come across a slideshow with a reference to the subdomain above and it reads:

slideshow

Here is what we have: acssvn.honeywell.com is their internal link to their version control system, which must mean that the github scripts are intended for internal usage. Are these the scripts used to compile their internal software updates? If so, why is it publicly available? It doesn’t seem to come from a formal Honeywell github repo, just a normal user…perhaps an employee?

funny-meme2

I read through both scripts, and at the end of yitiaolong.sh it shows the files that I’ve extracted from the .exe being copied to an ftp.

update-references

Okay so these scripts definitely have something to do with the software updates. Going up a bit in the code I see this the following:

jffs2 reference

It looks like the source code is pushed into a root JFFS2 file system (perhaps that Freescale embedded environment), and the file system is generated into a binary. We now know that app2.jffs2 exists somewhere within the app2.hdr file, which is a JFFS2 file system compiled with Freescale tool ‘sumtool’. However, there is a bit of a grey area between how app2.jffs2 turns into app2.hdr and where the rest of the files come from. Lines 55 through 59 shows a python script named header.py that appends a string somewhere in app.jffs2? Let’s take a look at the actual app2.hdr.

bullz3ye@ubuntu:~/honeywell$ head -10 app2.hdr 
appl000�����w�Fri Oct 07 13:09:51 2016app2.jffs2TUXW_V5.3.9.0APPTUXEDOPLUSVA��2�v7P6R�W
���i'�Drop_Cache�����d5�����6R�W6R�W6R�W����w^x^�UMlU�u����ր�O[E{((����B(���(EQ���ec/�
{��nR[BJJT����P�!H�
                        R�������!�J���|�?��6�<3o�ͼ�yo2���

Objdump wasn’t recognizing the file format so I just used head and less to see if that header does exists. At least we can draw the conclusion that some form of header is being prepended to the data file using header.py, is responsible for changing the extension. Still the question remains, is HDR some custom file type?

I decide to step away for a bit since I don’t have access to header.py, and that extension is really sending me for a loop. About an hour later it occurs to me that what if the .hdr extension stands for ‘header’ and wasn’t the name of any valid file type?! What if it’s just a JFFS2 file system renamed to indicate that a header has been included for the sake of installation?

bullz3ye@ubuntu:~/honeywell$ binwalk app2.hdr

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
128           0x80            JFFS2 filesystem, little endian

What the f###…I should have done that to begin with.

funny-meme3

Well, at least we know what we are dealing with here. JFFS2 is a popular file system, and we can use dd to extract it out.

bullz3ye@ubuntu:~/honeywell$ dd bs=1 skip=128 if=app2.hdr of=app2.jffs2
130211540+0 records in
130211540+0 records out
130211540 bytes (130 MB, 124 MiB) copied, 119.978 s, 1.1 MB/s
bullz3ye@ubuntu:~/honeywell$ file app2.jffs2 
app2.jffs2: Linux jffs2 filesystem data little endian

Now that we’ve got the file system, let’s mount it. You can’t mount it like a standard loopback device, but have to create a fake flash device first.

bullz3ye@ubuntu:~/honeywell$ sudo modprobe mtdram total_size=32768 erase_size=256
bullz3ye@ubuntu:~/honeywell$ sudo modprobe mtdblock
bullz3ye@ubuntu:~/honeywell$ sudo mkdir -p /mnt/disk
bullz3ye@ubuntu:~/honeywell$ sudo dd if=app2.jffs2 of=/dev/mtdblock0
dd: writing to '/dev/mtdblock0': No space left on device
65537+0 records in
65536+0 records out
33554432 bytes (34 MB, 32 MiB) copied, 0.211631 s, 159 MB/s
bullz3ye@ubuntu:~/honeywell$ sudo mount -t jffs2 /dev/mtdblock0 /mnt/disk

Let’s mount and cd into /mnt/disk…

show_fs

Yes! The first thing I go for now is /etc/shadow or some credentials but it turns out that the Linux environment folders are empty.

bullz3ye@ubuntu:/mnt/disk$ ls -ldh */
drwxr-xr-x 2 root root 0 Oct  7  2016 bin/
drwxr-xr-x 2 root root 0 Oct  7  2016 dev/
drwxr-xr-x 6 root root 0 Oct  7  2016 etc/
drwxr-xr-x 4 root root 0 Oct  7  2016 home/
drwxr-xr-x 5 root root 0 Oct  7  2016 lib/
drwxr-xr-x 2 root root 0 Oct  7  2016 mdns/
drwxr-xr-x 8 root root 0 Oct  7  2016 mnt/
drwxr-xr-x 5 root root 0 Oct  7  2016 opt/
drwxr-xr-x 2 root root 0 Oct  7  2016 proc/
drwxr-xr-x 2 root root 0 Oct  7  2016 root/
drwxr-xr-x 2 root root 0 Oct  7  2016 sbin/
drwxr-xr-x 2 root root 0 Oct  7  2016 sys/
drwxrwxrwt 2 root root 0 Oct  7  2016 tmp/
drwxr-xr-x 2 root root 0 Oct  7  2016 usr/
drwxr-xr-x 2 root root 0 Oct  7  2016 var/
drwxr-xr-x 2 root root 0 Oct  7  2016 vidrec/

This leaves the executables, which are apparently ELF 32-bit LSB ARM executables. Based on the file names, these are definitely the executables that facilitate the processes running on the Tuxedo tablet, specifically the files tuxedo, TotalConnect, and SDCardStatus are interesting. tuxedo has to be the core binary, and TotalConnect must be used to interface with the product’s Honeywell Total Connect 2.0 application. Between this and the empty folders, I assume (at least in this case) that the software update doesn’t replace the entire file system but just the proprietary ELF binaries.

show arm binaries

Taking a step back, I repeat this process of binwalk-ing the hdr files; extracting it’s contents to gather as much info as I can. Through this I discover a ton of useful information for going forward, including certificates, Makefiles, and some CRC32 polynomial tables. The next step is to figure out how to reverse engineer and decompile the binaries, starting with tuxedo for further analysis. That will likely be a part 2 to this post, but I’ve got a lot of work cut out for me.

Conclusion:

Starting from a software update, and some critical thinking, I was able to decompile the firmware update for my Honeywell Tuxedo. As a result, I have access to the proprietary binaries, and additional components that make up the device. My next two approaches are:

  1. Reverse engineer the binaries in an attempt to discovery exploitable vulnerabilities, and learn more about the device.
  2. Set up a test environment to execute the binaries so I can actively identify the attack surface, fuzz where possible, and really dig into it.

I hit a few bumps in the road along the way but hey that’s how you learn. Thanks for taking the time to read and definitely feel free to give feedback! Below are some good links that were extremely helpful along the way.

https://blog.bramp.net/post/2012/01/24/hacking-linksys-e4200v2-firmware/ https://wiki.securityweekly.com/Reverse_Engineering_Firmware_Primer