Reversing the Trendnet TS-402

Share

The Trendnet TS-S402 is a discontinued network storage enclosure that was sold to individuals for personal data storage. Like every Internet-of-Things (IoT) device, it runs on software programmed and/or configured by the manufacturer before shipping it to the end-user, i.e. the firmware. Firmware versions 2.00.10 and below of this particular device have a serious vulnerability allowing remote root access . This target thus provides an excellent exercise for reverse engineering while providing an example of a vulnerability that is unfortunately way too common in IoT: backdoors by design. In this post, we will introduce Binwalk and provide the background necessary to do the same on a large variety of firmware for consumer-level devices, using the TS-S402 as a practical example. A video of this post is also available.

Trendnet TS-S402
The Trendnet TS-S402 Network Storage Enclosure (from trendnet.com)

The Trendnet TS-S402

Before reversing any device, it’s important to actually understand its functionalities, components and any other piece of information that may help along the analysis of its firmware. The webpage of the product highlights the following features:

  • Access your data from the Internet (FTP) and on your local network
  • Microprocessor: Marvell 88F5182
  • IDE Controller: ITE IT8211F
  • Real Time OS: Embedded Linux (Kernel Version 2.4.25)
  • File Protocols: Microsoft Networks (CIFS / SMB) Internet (HTTP 1.1) FTP, FTPS (SSL FTP)

Why are these facts important? Not all of the will be useful, but some may provide you with an overall idea of what to expects once you start analyzing the firmware file. In many cases, especially with consumer-level devices, reversing firmware is fairly straightforward and common open-source tools will do the heavy lifting for you. But if you move on to industrial firmware, awareness of the device is important as you will be faced with unheard operating systems, libraries and unknown file formats. In this case, we can expect to see a Linux-based Operating System (OS) hosting a HTTP and FTP server, along with Samba compatibility. The manufacturer is even generous enough to provide the underlying microprocessor, which can be helpful when conducting even deeper analysis for vulnerabilities in the binaries.

Reversing the Firmware

The vulnerability we are looking for is present only in versions 2.00.10 and below of the firmware, which you can download from the repository of the company. Unzip the archive and you’ll to obtain the following files:

  • TS-S402_FW_2_00_10.bin
  • readme.txt
  • release_TS-S402.txt
  • REMOTE_PACKAGE_2_20.bin

It’s always a good idea to read the release notes and README files. Doing so may save you time and headaches trying to figure things out. If you’re into bug hunting, the release notes can be useful to list the changes and patches included in this version, providing potential hints to patched vulnerabilities of previous versions.

The two “.bin” files contain the programs and OS of the device. In this case, based on the filename, the TS-S402_FW_2_00_10.bin is the main firmware file and thus, the focus of this post. The first step is always to check if we can determine the file type by using the file command. If we are lucky, it is a known file type and some application exists to extract the relevant files/information out of it.

However we are not so lucky. The file command returns “data”, which means it found the file to be binary data without any specific structure or format. So we will need to use a more powerful tool: binwalk. Binwalk is very useful reverse engineering toolkit which can analyze and extract files from unknown binary files. However note that it can also return quite a few false positives. The only way to recognize them is with experience and trial-and-error. If not already done, install binwalk with apt using  sudo apt-get install binwalk and run the following command:

The command above asks binwalk to check out the TS-S402_FW_2_00_10.bin file and try to find interesting files or structures inside it. We use the “-x lzma” argument to eXclude any findings about LZMA-compressed data: these are false positives in this case. You will obtain the following result:

In other words, there seems to be a 32-bytes header followed by a GZip-compressed file. At this point, we want to carve this gzip file out of the binary file for further investigation. You can use the dd command to do so, but binwalk provides the -e option to Extract files for you.

The carved files will be outputted to a directory labelled _TS-S402_FW_2_00_10.bin.extracted, in which you will find a single file called 20, which is the offset of the file in the larger firmware. Using the file command again, we now get a more interesting result:

This time, the file command clearly recognized a TAR archive, meaning we can simply untar the file with the command below:

This archive contained even more files: a uImage and a filesystem:

  • uImage
  • rootfs.armeb.squashfs

The uImage is the boot loader of the firmware and you will often find this file or something similar in most Linux-based firmware. Analysis of the uImage will be left for another post. For now, we are interested in the filesystem contained in rootfs.armeb.squashfs, which as its name implies, is a SquashFS. To access the files it contains, we can normally use the unsquashfs tool, however in this case doing so won’t work:

Depending on how the file system was created and the development software used, it may have incompatibilities with the way unsquashfs expects the file system to be structured. As a workaround, we will use Sasquatch, which is more flexible when it comes to extracting file from non-standard Squash file systems. Clone the project and build the code by following the instructions n the README.md file, or you can download a pre-compiled binary for Ubuntu and variants. Now let’s try again carving out the files, but with Sasquatch this time by typing  ./sasquatch rootfs.armeb.squashfs . After a while, Sasquatch will extract all files in the squashfs-root directory, at which point you can finally access the files hosted on the targeted device.

Find the Backdoor

There is a fairly obvious backdoor hidden in the file system. Go ahead and explore the files and configuration and see if you can find it. When you are ready read on.

Most commercial devices are accessible remotely via a web interface. The web server and its contents are therefore a good starting point to hunt down potential vulnerabilities. On the TS-S402, the web application is located in the /home/httpd directory. The partial listing of the contents of this directory is included below:

As you can see, one of the web page is named “backdoor.html”; quite an obvious indicator that something is wrong. If you look at the webpage, you’ll notice that it seems to enable the telnetd daemon, thus allowing Telnet connections to the device. Unless specially configured to be blocked in the network firewall, this web page should be accessible to anyone on the network, potentially anyone if facing the Web. All that is missing right now is credentials to access the device. Let’s look at /etc/shadow to see if we can potentially figure out the default password for the root account:

Well, there isn’t any password setup for the root account. So in other words, anyone who can access the backdoor.html page on the device can enabled remote Telnet connections, and then login as root. While I haven’t tested it as I do not own this device. this vulnerability was previously confirmed and reported.

Conclusion

This post provided an example of reversing the firmware of a consumer-level IT appliance to locate vulnerabilities allowing remote access to the device. Such vulnerabilities may seem trivial an unimportant until a botnet such as the Mirai botnet comes along and use tens of thousands of these vulnerable devices – which are rarely updated – to DDoS websites across the web. Hence the need to understand the techniques and skills require to pwn these devices in order to defend them.

See Also

Learn More

 

 

Reversing the Parrot SkyController Firmware

Share

Introduction

The Parrot SkyController is a remote control sold for long range flights with the Parrot Bebop drone, sometimes used in the real estate sector. It enables integration of smartphones and tablets for flight control via Wifi connection, allowing transmission of real-time data from the drone. In other words, the SkyController acts as an intermediate between the flight management software (smartphone/tablet) and the actual drone. In this post, we explain how to reverse the firmware of the SkyController to be able o view the contents of the internal operating system and understand its inner workings. A lot of the information provided is based on [1] and is applied on this specific firmware. Code is provided along this post that will extract files and information from the SkyController firmware.

The Parrot SkyController Device
The Parrot SkyController Device (taken from the Parrot Store)

Contents

The firmware of the Parrot Skycontroller appears to be a well-defined format which is reused across multiple products from the company. The firmware contains 2 types of structures the header and a sequence of “data entries”. The header is located at the beginning of the file and is followed by multiple entries which contains configuration and file system information. We will look at both structures in the following sections.

Header

The firmware header starts with four magic bytes which spells out “PLF!”. These can therefore be used to identify valid Parrot firmware files. A quick Python snippet is included below as an example.

Immediately after the magic bytes, a sequence of thirteen 32-bit unsigned integers provides additional information about the firmware. Defined as a C structure, the header would look something like this:

The header version specify the type of format used for the firmware header. Within the SkyController firmware, the value for this field was “0x0D”, possibly indicating that there are 14 variations of header formats. The header size provides the number of bytes included in the header while the entry header size specifies the number of bytes in headers of entries within the firmware. The next 5 integers are undefined at the moment, as is the before-last integer. One of them is likely a CRC32 checksum. The dwVersionMajor, dwVersionMinor and dwVersionRevision defines the version of the firmware. Lastly, the header contains the size of the file in bytes.

Entries

Each entry has a header of constant size, which is specified within the firmware header by the dwEntrySize value. In the SkyController, each entry is composed of 20 bytes used as follows:

 

The section type specify the type of data contained within the entry. This can be configuration data, partition details or file information. These will be explained in further details in the sections below. The entry size contains the number of bytes within the entry, without consideration for null-byte padding. This field is followed by a CRC32 value. It’s unclear at this point how this value is calculated. The last known integer is the size of the data once uncompressed. If this value is 0, then the contents are not compressed. Each type of entry have further fields defined, and these are explained below.

Firmware Entries

There are multiple types of entries within the firmware. In this section we will describes the one we came across in the file we have analyzed.

Bootloader and Boot Configuration (0x03, 0x07)

Entry 0x03 contains a binary file which appears to be the bootloader of the system based on strings contained within, however more analysis will be required to understand how it actually works. In the SkyController, a PLF file was observed, but within that PLF file, this entry had binary data. Similarly, entry 0x07 also appears to be related to the boot process as shown by the string “ecos-bootloader-p7-start-246-ge30badf”, “ecos” referring to the eCos operating system.

File System Data (0x09)

There is a  “File System Data” entry for each file contained in the firmware. As such, this entry is the most common one. Depending on whether the file is compressed or not, the structure of this entry is slightly different: when its contents are uncompressed, this entry starts with the filename (or directory name), which is a zero-terminated string. The name is then followed by 3 unsigned integers.

The first integer contains flags specifying the type of file, which can be a directory, a normal file or a symbolic link. This is specified by reading the bits 12 to 15. The 12 other bits contains the permissions of the file. Converted into octal form, the last 12 bits will provide the same format as the one used in Linux. For example:

Extracting File Permissions from the Firmware Entry
Extracting File Permissions from the Firmware Entry

When compressed, the flags are within the Gzip-compressed data. The data must therefore be first uncompressed and then, the same procedure applies: the filename will be a null-terminated string right at the beginning, followed 3 unsigned integers, the first containing the type and permissions. The remaining bytes are the content of the file. In the example below, the filename is system/pulsar/etc/boxinit.hosted. The flags are 0x000081A0 (little-endian) and the contents of the file starts at 0x32. 

Partition Data (0x0B)

The 0x0B entry contains information about partitions on the device.The header of this entry is composed of 10 values. The first 4 integers are version information, the next 5 ones are unknown and the last unsigned integer is the number of partitions defined within the entry.

For each partition defined within the entry, a sub entry is available which contains further information about the partition: the device ID, volume data and the mount point on the target device. The defining structure for this entry are:

Volume type can be either RAW, STATIC and DYNAMIC. A raw partition contains no file systems, for example swap partitions. Static partitions are read-only, such as the boot partition and finally, the dynamic partitions are read-write and contains modifiable files.

Installation Data (0x0C)

This entry was included early in the file and contained another PLF file within its data. This PLF file contained a 0x00 entry, which is unknown, a 0x03 entry and a 0x07 entry. The 0x07 entry contained boot options:

Conclusion

I have upload a Python program [2] which will extract information and files from the SkyController firmware here. It also successfully extracted files for a Bebop2 firmware and I suspect it will work for other recent firmware. With additional work, it may reverse older ones. Repacking an unpacked firmware should be doable, but I do not have any of the device to test it out. Before doing so, determining how the CRC value for the header and each entry is calculate is required. Future work would include testing additional firmware files and implementing the program to repack an unpacked and modified firmware. Finally, reading the eCos documentation may clarify many of the unidentified values.

References

[1] “PLF File Format”, E/S and I, https://embedded-software.blogspot.ca/2010/12/plf-file-format.html (accessed 2016-12-13)

[2] Racicot, J. “Vulture”, https://github.com/InfectedPacket/vulture (accessed 2017-01-03)