Reversing ESP8266 Firmware (Part 2)
Initial analysis
As with any unknown binary, our initial analysis will help to uncover any strings that may allude to what we’re looking at, as well as any signatures within the file that could present a point of further analysis. Lastly, we want to look at the hexadecimal representation of the file, in order to identify padding or other blocks of interest.
File output:
recovered_file: , code offset 0x1+3, Bytes/sector 26688, sectors/cluster 5, FATs 16, root entries 16, sectors 20480 (volumes <=32 MB), Media descriptor 0xf5, sectors/FAT 16400, sectors/track 19228, FAT (12 bit by descriptor)
BinWalk output:
josh@ioteeth:/tmp/reversing$ binwalk -v recovered_file Scan Time: 2018-05-24 11:51:24 Target File: /tmp/reversing/recovered_file MD5 Checksum: 7e11dd07846ecfe2502df7ad0c75952a Signatures: 344 DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 251942 0x3D826 Unix path: /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h 292925 0x4783D Unix path: /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/abi.cpp
We can see from the output above that we’re potentially looking at an ESP8266 firmware image. I’ll disregard the results of file as they’re clearly a false positive, based on the challenge pre-text.
Strings output:
[...] /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _pos <= _streamPos /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h cb == stream_rem /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _pos + size <= _size /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _buffer /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _pos <= _streamPos /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h cb == stream_rem /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _pos + size <= _size /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _send_waiting == 0 /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/ClientContext.h _datasource == nullptr /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/ClientContext.h _connect_pending /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/ClientContext.h pcb == _pcb /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/ClientContext.h buffer == _data + _pos /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h _pos + size <= _size /tmp/esp8266/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/include/DataSource.h [...] AConnecting to WiFi connected IP address: Port knocking failed /get_secrets Requesting URL: GET HTTP/1.1 Host: Connection: close >>> Client Timeout ! closing connection services.ioteeth.com AjT32156 PCSL_GUEST
Based on the strings above, in particular:
IP address: Port knocking failed
It would appear our firmware is potentially performing a form of port knocking, before connecting to services.ioteeth.com to retrieve the aforementioned secrets. Port knocking is a means of instructing a firewall to open a predefined TCP/UDP port if the correct sequence of ports are ‘knocked’ on, which is usually performed via sending a TCP SYN packet to the required ports. The firewall would recognise the sequence and permit access to the defined resources.
We can perform a fast port scan to check for any filtered ports across a limited number of popular ports:
josh@ioteeth:/tmp$ nmap -n -PN -F -v services.ioteeth.com -oN services.ioteeth.com.out Warning: The -PN option is deprecated. Please use -Pn Starting Nmap 7.40 ( https://nmap.org ) at 2018-05-25 11:29 BST Initiating Connect Scan at 11:29 Scanning services.ioteeth.com (192.168.1.69) [100 ports] Discovered open port 22/tcp on 192.168.1.69 Completed Connect Scan at 11:29, 1.20s elapsed (100 total ports) Nmap scan report for services.ioteeth.com (192.168.1.69) Host is up (0.00059s latency). Not shown: 98 closed ports PORT STATE SERVICE 22/tcp open ssh 445/tcp filtered microsoft-ds Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 1.23 seconds
We can see that port 445 is filtered, so this could be our target port and equally, this would explain why the service couldn’t be reached by the originator of this challenge. It’s also possible another port is the one being used to obtain/upload secrets and ultimately, we’ll find that port through investigation, we note this however as a passive observation.
Continuing with our analysis, let’s take a look at the hexdump of our firmware image:
josh@ioteeth:/tmp/reversing$ hexdump -v -C recovered_file | head 00000000 e9 01 00 00 9c f2 10 40 00 f0 10 40 68 05 00 00 |.......@...@h...| 00000010 10 10 00 00 50 f5 10 40 1c 4b 00 40 cc 24 00 40 |....P..@.K.@.$.@| 00000020 ff ff ff 3f ff ff 0f 40 ff 7f 10 40 ff ff ff 5f |...?...@...@..._| 00000030 f0 ff ff 3f 00 10 00 00 1c e2 00 40 00 4a 00 40 |...?.......@.J.@| 00000040 4c 4a 00 40 00 07 00 60 00 00 00 80 e8 2b 00 40 |LJ.@...`.....+.@| 00000050 f0 30 00 40 a0 2f 00 40 b7 1d c1 04 00 12 00 60 |.0.@./.@.......`| 00000060 00 10 00 eb 7c 12 00 60 12 c1 d0 09 b1 f9 a1 fd |....|..`........| 00000070 01 29 4f 38 4f 21 e6 ff 2a 23 4b 3f 0c 44 01 e6 |.)O8O!..*#K?.D..| 00000080 ff c0 00 00 8c 52 0c 12 86 07 00 00 00 21 e1 ff |.....R.......!..| 00000090 29 0f 28 0f 28 02 29 2f 28 0f 28 12 29 3f 38 1f |).(.(.)/(.(.)?8.|
We also note that further into the file is what appears to be padding, followed by more data:
00000570 68 f5 10 40 00 00 00 00 00 00 00 00 00 00 00 2d |h..@...........-| 00000580 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 00000590 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 000005a0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 000005b0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| [...] 00000fd0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 00000fe0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 00000ff0 aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa |................| 00001000 e9 04 00 00 30 64 10 40 10 10 20 40 c0 ed 03 00 |....0d.@.. @....| 00001010 43 03 ab 83 1c 00 00 60 00 00 00 60 1c 0f 00 60 |C......`...`...`| 00001020 00 0f 00 60 41 fc ff 20 20 74 c0 20 00 32 24 00 |...`A.. t. .2$.| 00001030 30 30 75 56 33 ff 31 f8 ff 66 92 08 42 a0 0d c0 |00uV3.1..f..B...|
This padding is potentially useful, as it could be indicative of multiple files or formats being present within our target firmware image.
At this point, we have a number of questions we need to answer before we can continue. We can theorise that our long-term goal, based on the strings observed within the file, is to uncover the port knocking sequence performed by the firmware, which will hopefully allow us to access the external service that’s communicated with. But how do we go about doing that?
It’s worth noting that IDA doesn’t recognise our file, so let’s pause and do some research first.
Questions we need to answer
As with any firmware image, a good starting point prior to reverse engineering is to understand the following:
- What is the device in question?
- What processor does it operate on?
- What is the format of the firmware image in question?
- What tools exist to process the type of firmware image we have, if any?
- What is the boot process of the device?
- What does the physical memory layout look like?
Throughout the course of this section, we’ll work towards learning the answers to the above and understanding how they can help us.
Our penultimate goal will be to load the firmware into IDA for analysis, in a way that allows us to make some sense of what’s happening.