Document scan
🧠Challenge Text¶
TODO
🎨 Solution¶
We get document_scan.pcapng, reference_scan.pcapng and reference_scan.png (4960x7015, 1-bit).
Most of the traffic in both captures is a single TCP stream 10.10.255.11 <-> 10.10.1.9:8610. That port is Canon MFNP, the network scanner protocol, which wraps PIXMA ImageCLASS commands.
Every frame has a 16-byte header:
"MFNP" | type(2) | 0000 | seq(2) | 0001 | len(4) | payload
The scan parameter command (de20) is identical in both captures:
... 1258 1258 ... 00001360 00001b67 04 08 ...
600dpi x/y width=4960 height=7015, 8-bit gray
The scanner answers the read requests (d420) with data frames (8220). Each payload is 0606 xx 00 <len32> followed by raw grayscale pixels.
Joining all chunks gives 34,794,400 bytes, which is exactly 4960 x 7015. Script: mfnp.py.
tshark -r document_scan.pcapng -q -z follow,tcp,raw,13 > follow.txt
python3 mfnp.py document_scan.pgm < follow.txt
As a sanity check, the reference capture rebuilds into a black circle, the same image as reference_scan.png.
The document capture rebuilds into an invitation to the NREN-TCC Annual Ball, with a QR code in the bottom-left corner.
I sampled the QR into a 25x25 grid and decoded it with a small pure-Python reader, qrdec.py. It is version 2, EC level L, mask 2, ECI 26 (UTF-8), byte mode:
EC L mask 2 version 2
mode 0111
ECI 26
mode 0100
25 b'FLAG{GOTO-NREN-BALL-BABY}'
The rest of the traffic (QUIC/TLS, ESET and Windows Update, MFNP UDP status packets) holds nothing else of interest.
Flag: FLAG{GOTO-NREN-BALL-BABY}
I found the flag: FLAG{GOTO-NREN-BALL-BABY}
How it was hidden: 1. Almost all the traffic is one TCP stream to 10.10.1.9:8610. That's a network scanner (Canon MFNP protocol), and the raw scanned image travels inside it, split into chunks. 2. Putting the chunks back together gives an 8-bit grayscale image of 4960×7015 pixels. The reference files are there to check the method: the reference capture rebuilds into the same black circle as reference_scan.png. 3. The document capture rebuilds into an invitation to the "NREN-TCC Annual Ball". It has a QR code in the bottom-left corner. 4. No QR decoder was installed, so I read the code's grid of squares off the image and decoded it with a small Python script. It decodes to the flag.
I also checked the rest of the traffic (Google, update services, scanner status packets) and the near-white pixels of the scan, and found nothing else that looks like a flag.
I added a writeup in your repo's usual format at docs/thecatch/2026/document_scan/. It has two scripts: mfnp.py rebuilds the image from the capture and qrdec.py decodes the QR grid. I re-ran both and got the same image and the same flag. The challenge text, category and points are left as TODO because I don't have them. Nothing has been committed.
Files are in docs/thecatch/2026/document_scan/: - document_scan.md - mfnp.py - qrdec.py