Challenge / Pwn

You Know 0xDiablos

You Know 0xDiablos is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

EasyPublished 2025-05-09Sanitized local writeup

Scenario

You Know 0xDiablos attack path

You Know 0xDiablos is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

Objective

Challenge walkthrough focused on Pwn evidence, validation, and reusable operator lessons.

You Know 0xDiablos sanitized attack graph

Walkthrough flow

01

Extract the AES-encrypted ZIP with the standard HTB...

02

Identify vuln as a 32-bit i386 ELF, dynamically...

03

Use nm/disassembly to find proof at 0x080491e2, vuln,...

04

In vuln(), observe gets() writes to a buffer at...

05

Calculate saved EIP offset as 0xb8 + 4 = 188.

Source coverage

High source coverage

Status: complete. This article is generated from 5 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.

100% coverage
Evidence verdict

High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.

  • Pwn/You-know-0xDiablos/writeup.md
  • htb-challenge/Pwn/You-know-0xDiablos/notes.md
  • htb-challenge/Pwn/You-know-0xDiablos/memory-summary.md
  • htb-challenge/Pwn/You-know-0xDiablos/hypothesis-board.md
  • HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Pwn__You-know-0xDiablos__notes.md.60727f8c15.md

Technical Walkthrough

Writeup

Challenge

  • Name: You-know-0xDiablos
  • Category: Pwn
  • Difficulty: Easy
  • Mode: hybrid

Summary

The challenge is a classic 32-bit ret2win. The binary exposes a flag() function but never calls it through the normal path. The vulnerable function uses gets() into a stack buffer, allowing the saved return address to be overwritten. Returning into flag() with the two required cdecl arguments makes the remote service print the flag.

Artifact Inventory

  • files/a12c73af-45ce-498f-9aa6-1dde6ccb7cc7.zip: original AES-encrypted challenge archive.
  • analysis/extracted/vuln: extracted 32-bit i386 ELF.
  • analysis/nm.txt: symbol listing showing flag, vuln, and main.
  • analysis/function-disassembly.txt: focused disassembly used for the exploit.
  • Remote endpoint: <TARGET>:30838.

Analysis

analysis/extracted-file-types.txt identifies the extracted artifact as a 32-bit Intel ELF. The symbol listing in analysis/nm.txt shows flag at 0x080491e2 and vuln at 0x08049272.

The focused disassembly in analysis/function-disassembly.txt shows vuln() using gets() on a stack buffer loaded from [ebp-0xb8]. The saved return address sits at [ebp+4], so the offset from the buffer start to saved EIP is:

text
0xb8 bytes to saved EBP + 4 bytes saved EBP = 188 bytes

The same disassembly shows flag() opening flag.txt, reading it, and printing it only after checking:

text
arg1 == 0xdeadbeef
arg2 == 0xc0ded00d

Because this is 32-bit cdecl, the payload places a dummy return address after the flag() address, followed by those two arguments.

Solve

Run:

bash
cd <local workspace>
python3 solve/solve.py --host <TARGET> --port 30838

The script builds:

text
"A" * 188 + p32(0x080491e2) + "BBBB" + p32(0xdeadbeef) + p32(0xc0ded00d)

It sends the payload to the remote service, stores the raw service transcript under loot/, and writes the extracted HTB-format flag candidate to loot/flag-candidate.txt without printing the flag by default.

Flag

Raw flag is stored in loot/flag.txt and intentionally not reproduced here.

Lessons

For Easy Pwn ret2win binaries, symbol tables and focused function disassembly can be enough: identify the win function, determine the calling convention and arguments, calculate the overwrite offset from the stack frame, then run a single bounded remote attempt.

Source-Backed Dossier

The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.

Notes

Scope

  • Challenge: You-know-0xDiablos
  • Category: Pwn
  • Difficulty: Easy
  • Mode: hybrid
  • Remote instance: <TARGET>:30838
  • Start time: 2026-06-10T13:33:36Z
  • Operator: harness
  • State file: challenge-state.json

Harness Status

  • Current phase: see challenge-state.json
  • Next allowed actions: see next-action.json
  • Raw flags and sensitive material stay in loot/ only. Do not paste them here.

Artifact Inventory

FileSizeSHA256TypeNotes
files/a12c73af-45ce-498f-9aa6-1dde6ccb7cc7.zip3058<hash redacted>Zip archive data, at least v5.1 to extract, compression method=AES Encryptedzip entries: 1 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-10T13:33:36Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-10T13:33:36Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-10T13:33:36Zhypothesis recordedhypothesis-board.mdExploit a local binary memory-corruption bug and adapt the payload to the remote service at <TARGET>:30838 to retrieve the HTB-format flag.MediumExtract the binary, inspect protections, identify flag-printing or win function, calculate overflow offset locally, then gate and run a remote exploit script.
2026-06-10T13:33:36Zresearch skipanalysis/research/research-skip.mdResearch intentionally skipped with recorded reasonMediumGate before exploit
2026-06-10T13:36:13Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-10T13:36:13Zcheckpoint recordedanalysis/checkpoint-analysis-20260610T133613447031Z-ef70e929.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-10T13:36:32Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-10T13:36:54Zevaluatoranalysis/evaluator-20260610T133654328629Z-af6dc0c6.mdProceedHighRun solve/solve.py against <TARGET>:30838 and store output under analysis/ and loot/.
2026-06-10T13:37:10Zremote exploitanalysis/solve-remote-run.txt, analysis/remote-exploit-output-redacted.txt, loot/remote-exploit-output.binValidated ret2win payload against the provided remote endpoint; raw service transcript moved to loot/ because it contains the flag.HighCapture flag with harness
2026-06-10T13:37:14Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-10T13:40:03Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The extracted vuln artifact is a 32-bit i386 ELF, dynamically linked and not stripped.
  • Symbols expose flag, vuln, and main; flag is at 0x080491e2.
  • vuln() calls gets() with a stack buffer at ebp-0xb8; the saved return address is reached after 188 bytes.
  • flag() opens flag.txt and prints it only if its first two cdecl arguments are 0xdeadbeef and 0xc0ded00d.
  • The exploit payload is 188 bytes padding || flag address || dummy return || 0xdeadbeef || 0xc0ded00d.
  • Raw remote output and raw flag are kept under loot/ only.

RAG / Advisory Memory

RAG output is advisory only. Record evaluated retrievals with:

bash
scripts/challenge_harness.py rag-record <workspace> --query "..." --tag MATCHED|PARTIAL|MISSING|<secret redacted>|GENERIC --validation "..."

Secrets/Flags

Raw flags and sensitive material stay in loot/ only. Use scripts/challenge_harness.py capture-flag to validate and record flag capture without printing the value.

Memory Summary

You-know-0xDiablos was an Easy Pwn ret2win challenge.

The useful path was:

  1. Extract the AES-encrypted ZIP with the standard HTB password.
  2. Identify vuln as a 32-bit i386 ELF, dynamically linked and not stripped.
  3. Use nm/disassembly to find flag at 0x080491e2, vuln, and main.
  4. In vuln(), observe gets() writes to a buffer at ebp-0xb8.
  5. Calculate saved EIP offset as 0xb8 + 4 = 188.
  6. In flag(), observe the checks for 0xdeadbeef and 0xc0ded00d before printing flag.txt.
  7. Send a 32-bit cdecl ret2win payload:

padding(188) || flag_addr || dummy_ret || 0xdeadbeef || 0xc0ded00d.

  1. Capture the remote HTB-format flag and keep raw output under loot/.

Reusable lesson: for non-stripped 32-bit ret2win challenges, avoid unnecessary fuzzing. Symbols plus stack-frame disassembly give the win function address, offset, and required cdecl argument layout.

Hypothesis Board

Keep no more than 3 active hypotheses on Easy/Medium and 5 on Hard unless the user explicitly asks for breadth.

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus
1Exploit a local binary memory-corruption bug and adapt the payload to the remote service at <TARGET>:30838 to retrieve the HTB-format flag.Challenge is Pwn/Easy with scenario 'I missed my flag' and provides both a downloadable artifact and remote TCP endpoint.Extract the binary, inspect protections, identify flag-printing or win function, calculate overflow offset locally, then gate and run a remote exploit script.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition

Notes

Notes

Scope

  • Challenge: You-know-0xDiablos
  • Category: Pwn
  • Difficulty: Easy
  • Mode: hybrid
  • Remote instance: <TARGET>:30838
  • Start time: 2026-06-10T13:33:36Z
  • Operator: harness
  • State file: challenge-state.json

Harness Status

  • Current phase: see challenge-state.json
  • Next allowed actions: see next-action.json
  • Raw flags and sensitive material stay in loot/ only. Do not paste them here.

Artifact Inventory

FileSizeSHA256TypeNotes
files/a12c73af-45ce-498f-9aa6-1dde6ccb7cc7.zip3058<hash redacted>Zip archive data, at least v5.1 to extract, compression method=AES Encryptedzip entries: 1 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-10T13:33:36Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-10T13:33:36Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-10T13: <REDACTED>, inspect protections, identify flag-printing or win function, calculate overflow offset locally, then gate and run a remote exploit script.
2026-06-10T13:33:36Zresearch skipanalysis/research/research-skip.mdResearch intentionally skipped with recorded reasonMediumGate before exploit
2026-06-10T13:36:13Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-10T13:36:13Zcheckpoint recordedanalysis/checkpoint-analysis-20260610T133613447031Z-ef70e929.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-10T13:36:32Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-10T13:36:54Zevaluatoranalysis/evaluator-20260610T133654328629Z-af6dc0c6.mdProceedHighRun solve/solve.py against <TARGET>:30838 and store output under analysis/ and loot/.
2026-06-10T13: <REDACTED>, analysis/remote-exploit-output-redacted.txt, loot/remote-exploit-output.binValidated ret2win payload against the provided remote endpoint; raw service transcript moved to loot/ because it contains the flag.HighCapture flag with harness
2026-06-10T13: <REDACTED>
2026-06-10T13:40:03Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The extracted vuln artifact is a 32-bit i386 ELF, dynamically linked and not stripped.
  • Symbols expose flag, vuln, and main; flag is at 0x080491e2.
  • vuln() calls gets() with a stack buffer at ebp-0xb8; the saved return address is reached after 188 bytes.
  • flag() opens flag.txt and prints it only if its first two cdecl arguments are 0xdeadbeef and 0xc0ded00d.
  • The exploit payload is 188 bytes padding || flag address || dummy return || 0xdeadbeef || 0xc0ded00d.
  • Raw remote output and raw flag are kept under loot/ only.

RAG / Advisory Memory

RAG output is advisory only. Record evaluated retrievals with:

bash
scripts/challenge_harness.py rag-record <workspace> --query "..." --tag MATCHED|PARTIAL|MISSING|<secret redacted>|GENERIC --validation "..."

Secrets/Flags

Raw flags and sensitive material stay in loot/ only. Use scripts/challenge_harness.py capture-flag to validate and record flag capture without printing the value.

Technical analogy

How to remember this solve

Think of the challenge as a small system with one rule that matters more than the rest. The solve is finding that rule, validating it, and using it carefully enough to reach the final proof.

For You Know 0xDiablos, keep the mental model simple: identify the trusted assumption, prove it with the smallest safe test, then automate or repeat only the part that directly leads to the flag.