A while ago I did reverse engineering challenge that pushed me to learn more about the Arduino toolchain.
I am a big fan of Platformio and switched to that a long time ago but most people will still use Arduino and the Arduino IDE. Also, even in Platformio you will most times use the Arduino SDK as a base for your firmware. For ESP32/ESP8266 you can also use the ESP-IDF and other vendors have their own toolkits. That being said, let’s jump in.
As with most challenges, I had to get a flag. I was only given a a file called something.ino.elf
( I will try not to give away any challenge specific details and focus only on the technologies).
The big hint here was the .ino -> this means the binary was generated using the Arduino toolchain.
At this point I wanted to run the firmware to see what it does and how. This is the first step in any RE challenge I would say.
I also looked at the binary with some decompilers (Ghidra, Radare2-Cutter) and noticed it had some hard-coded WiFi credentials. Cool. But I still needed to run the firmware first.
It took me a while to figure out how to make a .bin(a full firmware file) from just the ELF binary(the user part of the application) and I am still not sure of the process but I just googled stuff about elf and bin and found out there is a binary called “elf2bin.py” in the Arduino toolchain
From there it was a matter of finding the right params to run it, which were:
python ~/.arduino15/packages/esp8266/hardware/esp8266/2.7.1/tools/elf2bin.py -e ~/.arduino15/packages/esp8266/hardware/esp8266/2.7.1/bootloaders/eboot/eboot.elf -m dio -f 26 -s 4M -o something.bin -a something.ino.elf -p ~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin
I used the toolchain in an existing Arduino installation I had on disk(thus the funky paths). The big takeway from here is that you need to append eboot.bin to the firmware to do anything useful, I tried to do this with esptool.py as well but I always got a corrupted firmware.
It turns out that the Arduino toolchain has its own bootloader that then bootstraps user code. This is what that eboot.elf file is for.
Some of the other parameters are specific to the board I wanted to run on, like 4M of flash, “dio” flash mode(for nodemcu cheapo boards) etc.
At this point I had a “something.bin” file to be flashed onto an esp8266 board.
esptool.py -p /dev/ttyUSB0 -b 115200 write_flash -fm dio 0x0 something.bin
Notice the -fm dio which is specific to my board. 0x0 is the address at which to flash the image – in this case it starts at flash address 0x0 because it contains a bootloader.
Analyzing the firmware itself it seems to be based off this Arduino forum post:
Or something to that effect.
The rest was a matter of patching it to do what I wanted, this involved making a WiFi hotspot with the credentials it wanted and eventually patching out the auth because I couldn’t figure out the password 🙂
That’s it; I hope I did not give away too much, I really liked learning more about how Arduino builds a firmware.