Hacker Holidays — Day 4: Packed Light
A PCAP shows a covert channel exfiltrating one byte per HTTP request inside a Cookie header — base64 plus a single-byte XOR, broken instantly with a known-plaintext crib on the flag format.

Event: Hacker Holidays — The Byte Lotus Hotel · Day 4 · Forensics (Network / PCAP) File:
traffic.pcapng
The Setup
A short capture from the guest network. Something beacons out to an odd :8080 host
“every second like clockwork,” and the data is dribbled out one byte at a time
(“packed light”), base64-encoded and XOR-obscured. Objective: find the covert channel,
reassemble the bytes, decode the flag.
Covert channel: data exfiltrated inside an HTTP Cookie header, one byte per request.
Step 1 — Overview
capinfos traffic.pcapng # 1,348 pkts, 41s capture
tshark -r traffic.pcapng -q -z io,phs
The protocol hierarchy shows only 62 HTTP frames in a sea of TLS/QUIC/SSDP noise — the plaintext HTTP is where to look.
Step 2 — Isolate the Beacon
tshark -r traffic.pcapng -Y "http.request && tcp.port==8080" \
-T fields -e frame.time_relative -e http.request.uri -e http.host
2.60 /temp/updates.py byte-lotus-hotel.thm:8080
15.95 / byte-lotus-hotel.thm:8080
16.07 / byte-lotus-hotel.thm:8080
... (30 × GET / on a tight loop)
- The first request pulls
/temp/updates.py— the exfil script fetching itself. - Then a steady loop of
GET /to the same host. Regular, low-volume — the “quiet little errand.”
Step 3 — Find Where the Data Hides
Dump full headers of those requests:
tshark -r traffic.pcapng -Y "http.request && tcp.port==8080" -O http
Two tells stand out on every beacon:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ByteLotusClient/1.1
Cookie: hotel_sess_state=HA==
- The bogus
ByteLotusClient/1.1User-Agent = @0xMia’s “not a real app.” hotel_sess_statechanges every request:HA==,AA==,BQ==,Mw==,Hg==,ew==… Each is base64 of a single byte. That’s the smuggled payload — one char per beacon.
Step 4 — Reassemble + Decode
Base64-decoding the cookies gives non-printable bytes → 1C 00 05 33 1E 7B .... That
points to a single-byte XOR. Use the known flag prefix THM{ as a crib:
| cipher byte | plaintext | key |
|---|---|---|
0x1C | T (0x54) | 0x48 |
0x00 | H (0x48) | 0x48 |
0x05 | M (0x4D) | 0x48 |
0x33 | { (0x7B) | 0x48 |
Key is constant = 0x48 ('H'). Applying it to all 30 bytes recovers the flag.
One-liner
tshark -r traffic.pcapng -Y 'http.cookie contains "hotel_sess_state"' -T fields -e http.cookie \
| sed 's/.*hotel_sess_state=//' \
| python3 -c 'import sys,base64; print("".join(chr(base64.b64decode(l.strip())[0]^0x48) for l in sys.stdin))'
THM{redacted}
Takeaways
- Exfil doesn’t need a weird protocol — it hides in normal-looking HTTP. Here it was
a legit-looking
Cookieheader on a beacon loop; nothing about the packets screamed “malware” except the fake User-Agent and the metronomic timing. - Timing is a signal. Perfectly regular, low-byte requests to a single host = beaconing.
Sort by
frame.time_relativeand the pattern jumps out. - Layered obfuscation is shallow here: base64 (to survive the header) → single-byte XOR (to hide from a casual grep). A crib on the known flag format breaks the XOR instantly.
- Detection idea: flag outbound HTTP with non-standard User-Agents + high-regularity intervals + monotonically changing cookies. Blue-team calls this beacon analysis.
Flag
THM{redacted}