pages/blog/break-the-ice.md (view raw)
1---
2template: text.html
3---
4
5# Break the Ice — Hardware CTF
6
7## SecureLayer7’s hardware CTF at Nullcon ’19, Goa
8
9Earlier this month at Nullcon Goa, we had the chance to attempt a hardware CTF challenge designed by the folks at [SecureLayer7](https://securelayer7.net). We weren’t able to solve it during the period of 2 days that we had (we had talks and parties to be at), but the SL7 guys were kind enough to let us keep the hardware and solve it back at home. Which we did, otherwise this write-up wouldn’t have happened :)
10
11### The Hardware
12
13So what’s this cryptic “hardware” I keep mentioning, you wonder? It’s an ESP8266 board — better known as a **NodeMCU**. Here’s a picture.
14
15![](1*cWpvtbXan4LjdJBldelW-g.jpeg)
16
17Oh, and it came with a pretty OLED display too. So the obvious task at hand was to connect the display to the board. A quick search, and we found an (ever helpful) [Instructables](https://www.instructables.com/id/Interface-LCD-Using-NodeMCU/) link with the image down below.
18
19![Not the same display, but it works](1*1avLAYsHDTGU-JS3e6oVrA.jpeg)*Not the same display, but it works*
20
21Mind you, we struggled quite a bit at this seemingly trivial step, but hey we’re CS students ;)
22
23On connecting the device via USB, the board spins up a wireless hotspot called “Device-6”.
24
25![](1*wJ3ZY2EskoSSfvCjliP_jQ.png)
26
27We tried to connect to this, but it was password protected. We’ll get back to it later.
28
29### Flash dump analysis
30
31During one of the many web searches I made with regard to this board, an interesting tool showed up — [esptool](https://github.com/espressif/esptool). A Python utility to communicate with the ESP8266. Wonderful.
32
33This tool allows us to do a bunch of operations on the board, but what we’re actually interested in is reading the flash. After looking up the syntax for it, we arrived at:
34
35```
36› sudo ./esptool.py -p /dev/ttyUSB0 -b 460800 read_flash 0 0x400000 flash_contents.bin
37Serial port /dev/ttyUSB0
38Connecting....
39Detecting chip type... ESP8266
40Chip is ESP8266EX
41Features: WiFi
42MAC: 84:f3:eb:05:83:1e
43Uploading stub...
44Running stub...
45Stub running...
46Changing baud rate to 460800
47Changed.
484194304 (100 %)
494194304 (100 %)
50Read 4194304 bytes at 0x0 in 100.8 seconds (333.0 kbit/s)...
51Hard resetting via RTS pin...
52```
53
54
55The command is fairly easy to understand, the `-p` flag denotes the serial port of our device, `-b` specifies the Baud rate and `read_flash`, well, reads the flash starting at `0` till `0x400000` which is 4MB.
56We faced a lot of trouble here, since we kept reading only upto 2MB. Why? Because that’s what the command on the Internet said.
57
58Anyway, we have our flash dumped into a file `flash_contents.bin`.
59
60We then decided to run `strings` on the flash binary and peruse through the thousands of lines it had. Brilliant right? It was, actually. We found a bunch of interesting strings, along with what we guessed to be the wireless hotspot’s password. Spoiler alert: it was.
61
62![The entire dump was 6000+ lines. Did we actually do this D:](1*5Hc-_XYFw-4_hw3iZpfqkQ.png)*The entire dump was 6000+ lines. Did we actually do this D:*
63
64The go-to utility to (actually) analyze binaries is `binwalk`. The `-e` flag extracts the known file types it recognizes within the binary.
65
66```
67› binwalk -e flash_contents.bin
68
69DECIMAL HEXADECIMAL DESCRIPTION
70--------------------------------------------------------------------------------
71283960 0x45538 Unix path: /root/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/include/DataSource.h
72289387 0x46A6B HTML document footer
73291156 0x47154 HTML document header
74291296 0x471E0 Unix path: /root/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/abi.cpp
753145728 0x300000 Squashfs filesystem, little endian, version 4.0, compression:gzip, size: 139733 bytes, 10 inodes, blocksize: 131072 bytes, created: 2019-02-25 09:14:19
76```
77
78
79We see a squashfs filesystem here. `binwalk` creates a directory in your current path containing all the files and folders it managed to extract. `cd`ing into our squashfs folder, we see this:
80
81![:O](1*VsEzd8PSYMIUwjBLNFFetA.png)*:O*
82
83Oooh yes. `cat`ting the file, we see:
84
85```
86› cat 1/Hidden.txt
87
88######################################### Hints :) ########################################
89
90---telnet server on esp
91
92--Hunt the key to get MQTT creds
93 --
94--MQTT box
95
96--Publish the correct message to get ^FLAG^
97
98<<<<<<<<<<<<<<<< PUBLISH..... DISPLAY.... SUBMIT.... :) >>>>>>>>>>>>>>>>>>>>>>
99```
100
101
102Looking inside the directory named `2`, we see another dir `3` containing a JPEG image and a file telling us about steganography.
103
104![](1*68k1Y6IoK0XTCPTQRn_0fw.png)
105
106And the final directory `4` had nothing in it but a file with the string `flag`. Probably to show up as a false positive in the `strings` output of the flash dump.
107
108### Connecting to “Device-6”
109
110The first file we came across, containing the hints, mentioned a `telnet` server running on the board. But how do we reach it? Yep, via the wireless hotspot it exposes — “Device-6”. We authenticated using the PSK we found earlier.
111On doing so, we’re prompted with a captive portal:
112
113![](1*XelmAgITUw-9aZc26meUDQ.png)
114
115A few things can be done here, configure WiFi on the board, view some info about the board, and reset it. Let’s connect the ESP to our own SSID — like a mobile hotstpot.
116
117![](1*oQcTNKOFGphPbX50K2pmlg.png)
118
119Once that’s done, we should see the “Device-6” SSID disappear, indicating that the board is now connected to our own wireless hotstpot. Another thing we notice is the board lights up, and so does our display!
120
121![That’s so sad. Alexa play Despacito.](1*lzKOxEkzJqo8TNI4WckmOg.png)*That’s so sad. Alexa play Despacito.*
122
123### The telnet server
124
125Once our host machine and the ESP are on the same network, we can `nmap` our subnet to find our ESP’s IP.
126
127![nmap scan report](1*lPNqoIFmNfxfabdt4sqYSQ.png)*nmap scan report*
128
129We see an `http` server running, which was obviously the captive portal, and our `telnet` server on port 23.
130
131```
132› telnet 192.168.43.223
133Trying 192.168.43.223...
134Connected to 192.168.43.223.
135Escape character is '^]'.
136Press Enter & sumbit your key :)
137somekey
138Wrong Key!!!
139```
140
141
142On connecting, we see a prompt asking for a key. And no, ‘sumbit’ was spelt that way ;)
143
144Where could this key possibly be? Well, the only unexplored part of this CTF so far is the image file we came across before. So… steganography.
145
146Although you won’t need it, I downloaded this Docker image for cracking stego — [stego-toolkit](https://hub.docker.com/r/dominicbreuker/stego-toolkit/). We then tossed the image under a bunch of steganography detection and breaking tools, but to no avail.
147
148After a good while `steghide` gave us something:
149
150```
151› steghide extract -sf 10071856.jpg
152Enter passphrase:
153```
154
155
156This took *really* long for us to figure but the password was the name of the image file itself. Urgh. On entering the password, we get a `keys.txt` file. Here’s what it looked like:
157
158```
159So you guessed the password i think...
160
161Nice!!!
162
163Key is somewhere hidden in this strings ...
164
165XH}<
166TJJ*
167Y#pU
168<g?/N
169gr[i}5
170>+h1
171...snip...
172jlW8B
173yjbm
174M4%'
175tx;ZzL
1763 k]
177wPUf'rc
178)Pz#
1790AwN\
180Lgr:J2
181!H9u
1824bSVy
183(*-C
184nOf2E\
185
186Aaaaaand key is not guessable ....
187
188WARNING:Manual checking for correct key might take you 2 days to complete the challange!!
189```
190
191
192Nearly 600 lines of gibberish. We guessed that one of these strings had to be they key for our `telnet` session. We tried to automate it, but the `telnet` session was very unstable. So being the madmen we were, we did it manually. We had all the time in the world. Off we went, copy/pasting the keys in batches of 5… and it worked.
193
194![yeet](1*vY84DrSpJU1H4c9pSvoB5Q.png)*yeet*
195
196As the hint file mentioned, we had to connect to an MQTT instance somewhere and publish something for the flag. So this is what they were talking about.
197
198For those out-of-the-loop, [MQTT](https://en.wikipedia.org/wiki/MQTT) is the protocol used in IoT basec client-server interactions, among other things. Go read about it if you want to understand the next bit.
199
200### Capturing the flag
201
202To interact with the MQTT server, we’ll be using the [Mosquitto](https://mosquitto.org) client. We then use the credentials and attempt to “publish” a message:
203
204```
205› mosquitto_pub -h 'm16.cloudmqtt.com' -p 17551 -t 'inTopic/web/test' -u 'hchzbuhr' -P 'Sz4plHnlVnHc' -m '(^.^)'
206```
207
208
209![UwU](1*W_iVf3vDf4UaelycMbvPvw.png)
210
211After messing around with this for quite a bit (as is evident from the screen behind), we tried sending the string ‘flag’ as our message and… *dramatic pause* we got what you’d expect.
212
213![We were 10 days late, mind you](1*sO9vDtGgGjejxklF46gTlg.jpeg)*We were 10 days late, mind you*
214
215### Conclusion
216
217This was our first time playing a hardware CTF, and to be honest, there wasn’t *much* of “hacking” involved — at least by the word’s textbook definition. A lot of guesswork too, which made some parts of it excruciatingly painful to figure out. But all things considered, it was probably the most fun CTF I’ve played yet. Here’s a shoutout to the folks at SL7 for making this CTF *and* letting us keep the ESP :)
218
219That’s it. The end.