$ cat writeup.md…
$ cat writeup.md…
sekai2026
Task: recover a message hidden with a Claude-generated custom PNG steganography scheme. Solution: decode the provided Claude Code API transcript, reconstruct the generated Python stego source tree from logged Write/Edit tool calls, then run the recovered extractor on flag.png.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
i rolled my own stego and made sure to make it wayyyyy too hard for someone to guess how it works...
er, i mean claude did. i totally read the code tho.
The provided archive contains only two files:
misc_impossible-stego/flag.png misc_impossible-stego/messages.log
flag.png is an RGBA PNG image. messages.log is much more important: it is a JSONL log of API requests and responses to an Anthropic/Claude-compatible gateway.
The challenge text says Claude wrote the stego code, so the right first step is not to guess the pixel algorithm. Instead, inspect the log and recover what Claude generated.
Each line of messages.log is a JSON object. The interesting fields are req_body and resp_body; both are base64-encoded. Decoding request bodies reveals Claude Code conversation state, including tool calls such as Write, Edit, Read, and Bash.
A quick parser confirms the late conversation contains the whole source tree creation history:
import json, base64 from pathlib import Path p = Path("misc_impossible-stego/messages.log") last = None for line in p.open(): rec = json.loads(line) s = rec.get("req_body") or "" if not s: continue try: body = json.loads(base64.b64decode(s)) except Exception: continue if "messages" in body: last = body for msg in last["messages"]: for c in msg.get("content") or []: if isinstance(c, dict) and c.get("type") == "tool_use": print(c.get("name"), c.get("input", {}).get("file_path"))
The log shows writes for files like:
stego/secret.py stego/crypto/kdf.py stego/crypto/chacha20.py stego/crypto/csprng.py stego/coding/frame.py stego/image/scatter.py stego/image/embed.py stego/pipeline.py stego/__main__.py
So messages.log effectively leaks the exact steganography implementation.
Reconstruct the final source tree by replaying logged Write and Edit operations. The following script extracts the last full Claude request body, then applies all file writes/edits whose paths are under /home/claude/projects/impossible-stego/:
#!/usr/bin/env python3 import base64 import json import shutil from pathlib import Path ...
$ grep --similar