stomach
Challenge
Imported from local notes.md.
Solution
Original Notes
stomach
Challenge Summary
- Given: A remote endpoint,
https://stomachbug.umbccd.net, that continuously streams data. - Goal: Recover the meaningful payload hidden inside the spewed network output and extract the flag.
- Constraints: The response is an effectively endless octet-stream, so collection had to be bounded and parsed incrementally.
Initial Recon / Triage
- Observations:
- The service responds with
application/octet-streamand suggests a filename ofspew.txt. - The body alternates between junk printable characters and lines of the form
|NNN|<hex>. - Chunk
000starts with89504e470d0a1a0a, which is the PNG signature. - The indexed hex lines continue until a chunk containing the PNG end marker
49454e44ae426082.
- The service responds with
- File identification:
artifacts/chunks.txt- extracted indexed hex chunk lines from the stream.artifacts/spew.png- first reconstructed PNG from the stream.artifacts/qr_payload.bin- raw binary payload from the first QR decode.artifacts/nested.png- PNG recovered from the first QR payload.artifacts/nested_qr_payload.bin- base64 text recovered from the second QR.
- Entry points:
- The HTTP stream at
https://stomachbug.umbccd.net. - The indexed
|NNN|hexlines embedded in that stream.
- The HTTP stream at
Hypotheses & Approach
- Hypothesis 1: The endless stream contains a complete file encoded as sequential hex chunks.
- Hypothesis 2: The reconstructed image would contain another steganographic or barcode-style layer rather than the flag directly.
Execution Steps (Reproducible)
Stage 1
Commands:
cd /root/dawg2026CTF/stomach
curl -sS --http1.1 https://stomachbug.umbccd.net/ \
| awk '/^\|[0-9][0-9][0-9]\|/ { print; if ($0 ~ /49454e44ae426082/) exit }' \
> artifacts/chunks.txt
python3 - <<'PY'
from pathlib import Path
import re, binascii
pat = re.compile(r'^\|([0-9]{3})\|([0-9a-f]+)$')
hex_parts = []
for line in Path('artifacts/chunks.txt').read_text().splitlines():
m = pat.match(line)
if m:
hex_parts.append(m.group(2))
Path('artifacts/spew.png').write_bytes(binascii.unhexlify(''.join(hex_parts)))
PY
file artifacts/spew.png
Results:
- Captured 162 indexed hex chunks, from
000through161. - Concatenating and decoding the hex produced a valid
625x625grayscale PNG. - That image was a QR code.
Stage 2
Commands:
cd /root/dawg2026CTF/stomach
zbarimg --raw artifacts/spew.png > artifacts/qr_payload.bin
python3 - <<'PY'
from pathlib import Path
utf = Path('artifacts/qr_payload.bin').read_bytes()
raw = utf.decode('utf-8').encode('latin-1')
Path('artifacts/nested.png').write_bytes(raw)
PY
zbarimg artifacts/nested.png
printf 'RGF3Z0NURnsxX0JMNE0zX1RIMFMzX0g0Wk00VF9UUjVDSzNSNX0=' | base64 -d
Results:
- The first QR contained binary data that had been UTF-8-expanded by the decoder.
- Converting that payload from UTF-8 text back to original byte values produced another valid PNG (
205x205). - The second PNG was another QR code containing base64 text.
- Base64-decoding that text yielded the final flag:
DawgCTF{1_BL4M3_TH0S3_H4ZM4T_TR5CK3R5}.
Artifacts Produced
artifacts/chunks.txt- captured hex chunk stream.artifacts/spew.png- first QR image reconstructed from the network spew.artifacts/qr_payload.bin- raw bytes from the first QR decode.artifacts/nested.png- PNG recovered from the first QR payload.artifacts/nested_qr_payload.bin- second QR payload, containing base64 text.
Flag
DawgCTF{1_BL4M3_TH0S3_H4ZM4T_TR5CK3R5}