#!/usr/bin/env python3 """CodeShell.kr — fried-egg: locate the CSSTEG2 payload(s). zsteg showed the RGB-LSB plane of fried-egg-stego.png starting with the magic `CSSTEG2` followed by `FLAG{FAKE}` -- a decoy. The hint ("should there not be only one sun in the world?") points at the second image, fried-egg-pan.png. Scan both images across channel/bit/order combinations for the CSSTEG2 magic and dump whatever follows it. """ import sys from pathlib import Path
#!/usr/bin/env python3 """CodeShell.kr — Fried Egg (Stegano, 6400p) solver. Both images carry the challenge's own container format in the RGB-LSB plane: "CSSTEG2" || BE32(payload_length) || payload * fried-egg-stego.png : length 0, followed by the decoy text "FLAG{FAKE}". * fried-egg-pan.png : length 14305, payload is JSON with a base64 JPEG. The hint "should there not be only one sun in the world?" is the giveaway: the stego image is the fake sun, the pan image holds the real one. Decoding the embedded JPEG yields the actual flag. """ import base64 import hashlib import json import sys from pathlib import Path
deflsb_bytes(path): a = np.array(Image.open(path).convert('RGB')) return np.packbits((a & 1).reshape(-1).astype(np.uint8)).tobytes()
defcontainer(blob): """magic(7) || version(1) || BE32(payload_length) || payload.""" assert blob.startswith(MAGIC), "magic missing" ver = blob[len(MAGIC)] off = len(MAGIC) + 1 n = int.from_bytes(blob[off:off + 4], 'big') return ver, n, blob[off + 4:off + 4 + n]
defmain(): OUT.mkdir(parents=True, exist_ok=True) for name in ('fried-egg-stego.png', 'fried-egg-pan.png'): for sub in ('challenge-files', 'challenge-images'): p = ROOT / 'assets' / sub / name ifnot p.exists(): continue ver, n, payload = container(lsb_bytes(p)) print(f"{name}: version {ver}, declared length {n}, " f"payload {len(payload)} bytes") print(f" head {payload[:64]!r}") ifnot payload.startswith(b'{'): print(" not JSON -- decoy payload, skipping") continue meta = json.loads(payload.decode()) print(f" json keys {list(meta)}") for key, val in meta.items(): ifnotisinstance(val, str): continue try: raw = base64.b64decode(val, validate=True) except Exception: # noqa: BLE001 continue dest = OUT / f"{name}.{key}.bin" dest.write_bytes(raw) print(f" wrote {dest} ({len(raw)} bytes, magic {raw[:4]!r})")