Hintru Tip ENES ← All labs

Tanuki: Flashcard Backup Restore

EN medium CTF challenge XXEXML External Entityin-band exfiltrationJS bundle reconAPI enumerationDTD injectionarbitrary file read
Original

Tanuki is a flashcard web app with an XML-based deck export and a JSON-driven restore endpoint. The server secretly round-trips your JSON through an XML template with DTD processing enabled — giving you a path to read arbitrary files off the server without any out-of-band channel. Your goal is to exfiltrate the flag at /app/flag.txt entirely in-band.

0/7
solved
Step 1 Step 2 Step 3 Step 4 Step 5 Step 6 Step 7
loot

Step 7 · Execute the full in-band file read and retrieve the flag

Objective: Send the final exploit payload to read /app/flag.txt via the XXE entity and retrieve its contents in-band from the newly created deck's name field.

Context: All pieces are now in place: the restore endpoint accepts JSON, the dtd field injects into the DOCTYPE internal subset, and &xxe; in name resolves to the file contents in-band. No out-of-band server or DNS callback is needed.

Progressive hints

Only reveal the ones you need. Claude tracks how many you used to calibrate the feedback.

Hint 1 — directional nudge

You have everything you need. Send the complete payload in a single request and read the flag back from the API response for the new deck.

Hint 2 — technique / vuln class

Combine dtd (entity definition pointing to /app/flag.txt), name (&xxe; reference), and the other required fields into one JSON restore request. The flag will be in the name property of the returned deck object.

Hint 3 — near solution

POST {"dtd":"<!ENTITY xxe SYSTEM \"file:///app/flag.txt\">","name":"&xxe;","description":"d","category":"c","cards":[]} to /api/decks/1/restore, capture the new deck ID, then GET /api/decks/<id> and read the name field.

Ask the tutor

Chat with a spoiler-safe tutor for this step. It uses only this lab spec and gives the smallest useful nudge first.

Tell the tutor what you tried, where you got stuck, or paste the response/error you are seeing.

Your attempt

Spotted something to improve?

Polish the wording, sharpen a hint, add missing context, fix a payload — your version stays separate from the original and other learners can choose it.

⚠ Report this lab

Enjoying Hintru? Buy me a coffee ☕ ☕