HTB: Espresso Challenge
Espresso - HackTheBox Challenge Writeup
Challenge Information
| Field | Value |
|---|---|
| Name | Espresso |
| Category | Misc / Reverse Engineering |
| Difficulty | Very Easy |
| Author | d3vn0mi |
Description
Someone leaked the new Espresso firmware, can you try to figure out what it does?
The challenge ships a firmware image and dares you to reverse it. The name is the first clue: “Espresso” → ESP32.
Solution
The provided archive was password-protected, and the staged firmware.bin initially looked empty. Once properly extracted, it turned out to be a full 4 MiB SPI flash dump for an ESP32 device — bootloader, partition table, and application image all present. Parsing the ESP-IDF image header let me carve out the DROM (read-only data) segment of the factory app, where the firmware’s strings live.
Inside .rodata sat an obvious taunt message claiming the flag depends on per-device eFuse/MAC data and hinting the “real” solve requires actual hardware or an emulator. That framing was a red herring — a short, tightly-clustered non-ASCII byte run elsewhere in .rodata turned out to be the flag, XOR-obfuscated with a single repeating byte key. A brute-force sweep of all 256 possible keys recovered valid ASCII (and the HTB{REDACTED} prefix) at key 0x42`.
Key Steps
1. Recover the real firmware image (the staged file was 0 bytes; the source zip was password-protected):
unzip -P hackthebox firmware.bin# yields the genuine 4,194,304-byte (4 MiB) SPI flash dump2. Fingerprint the target:
file firmware.binmd5sum firmware.bin# "Espresso" == ESP32 — ESP-IDF v6.1-dev-2748-g490691bc61,# project name "espresso", chip ID 0 -> ESP32 Xtensa LX63. Map the flash layout. Only two regions weren’t 0xFF-padded:
0x1000 – 0x9000 2nd-stage bootloader0x10000 – 0x33000 "factory" app imagePartition table (at the standard 0x8000 offset) confirmed nvs, phy_init, and factory partitions.
4. Parse the app image header and segment table to locate DROM:
import struct
d = open('firmware.bin', 'rb').read()base = 0x10000h = d[base:base+24] # esp_image_header_tsegs = h[1] # segment countoff = base + 24
# Walk segment headers (load_addr, data_len) to find the DROM segment# (load address 0x3f400020 identifies it as DROM on ESP32)5. Carve out the DROM segment (file offset 0x10020, length 0x8b68):
python3 -c "d = open('firmware.bin','rb').read()open('drom.bin','wb').write(d[0x10020:0x10020+0x8b68])"6. Search for readable strings — this surfaces the decoy:
strings -n 4 drom.bin | grep -aiE "flag|espresso|coffee|brew|secret|key|pass|htb"Output included:
flag did not generate correctly.It seems you are running the firmware on cloned hadware.Buy the real hardware, or perhaps try to emulate it. ;)…plus a get_efuse_factory_mac symbol reference — designed to send solvers down an eFuse/MAC-derivation or QEMU-emulation rabbit hole.
7. Spot the anomaly. Scanning .rodata for short, non-ASCII byte runs with repeated bytes (the shape of _ and ! characters under a constant XOR key) turned up a 32-byte blob at DROM offset 0x7668:
d = open('drom.bin', 'rb').read()blob = d[0x7668:0x7668+0x20]8. Brute-force single-byte XOR against the blob:
for k in range(256): s = bytes(b ^ k for b in blob) if s.startswith(b'HTB{REDACTED} print(hex(k), s)Key 0x42 produced a clean, printable string starting with HTB{REDACTED} — the flag, embedded directly in .rodata`, with no eFuse math or hardware emulation required.
9. Confirm:
echo 'HTB{REDACTED}' > flag.txtTools Used
unzip— extract the password-protected firmware archivefile,md5sum— basic artifact triage- Python (
struct) — parse the ESP-IDF image header and segment table, carve DROM strings— locate embedded text (taunt message, symbol names)- Python single-byte XOR brute-force — recover the obfuscated flag
Key Learnings
- Trust the name. “Espresso” was a direct pointer to ESP32 — recognizing the chip family upfront made the ESP-IDF image header trivial to locate and parse.
- Watch for staging artifacts that mask real content. A 0-byte firmware file wasn’t the actual challenge — the source archive was password-protected and needed manual extraction before any analysis could begin.
- In-firmware “explanations” are often decoys. The strings about cloned hardware, eFuse MAC derivation, and emulation were designed to push solvers toward a much harder (and unnecessary) hardware-emulation path.
- Repeated-byte runs are a giveaway for XOR-obfuscated ASCII. Scanning for short non-ASCII byte sequences with telltale repetition (matching common characters like
_and!under a constant key) is a fast way to spot XOR’d strings without prior knowledge of the key. - Single-byte XOR brute-force is cheap. With only 256 possible keys, exhaustively trying each and checking for a `HTB{REDACTED} prefix is faster than trying to reverse-engineer the “intended” derivation logic.