NoMap3d
NoMap3d is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
NoMap3d attack path
NoMap3d 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 GamePwn evidence, validation, and reusable operator lessons.
Walkthrough flow
Extract the file-only GamePwn archive and inspect the...
Parse assets.dmp: section type 1 stores player...
Use x-major map indexing from the binary: offset =...
Render the first byte of each map cell as the...
Decode the banner into the HTB-format proof,...
Source coverage
High source coverage
Status: complete. This article is generated from 4 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.
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.
- GamePwn/NoMap3d/writeup.md
- htb-challenge/GamePwn/NoMap3d/notes.md
- htb-challenge/GamePwn/NoMap3d/memory-summary.md
- htb-challenge/GamePwn/NoMap3d/hypothesis-board.md
Technical Walkthrough
Writeup
Challenge
- Name: NoMap3d
- Category: GamePwn
- Difficulty: Medium
- Mode: file
Summary
NoMap3d is a file-only GamePwn challenge built around a small native raycaster-style ELF and an assets.dmp blob. The solve path was not runtime patching or manual gameplay. The flag was embedded as a bitmap banner in the map wall/collision plane.
Artifact Inventory
files/a12c735f-0ef9-4098-a5bb-56c2f1db0657.zip: original challenge archive.files/extracted/gamepwn_nomap3d/nomap3d: 64-bit Linux PIE ELF, dynamically linked, not stripped.files/extracted/gamepwn_nomap3d/assets.dmp: asset blob containing the player section, map section, skybox, and texture data.
Analysis
The useful symbols in the ELF included load_assets, load_assets_texture, player_init, input, and raycast, which made asset parsing cheaper than dynamic gameplay.
The asset blob starts with a player section and then a map section. The map section has type 2, width 259, height 12, and three bytes per cell. The important implementation detail is that the binary indexes the map as x-major:
offset = map_start + (x * height + y) * 3Using row-major indexing produced misleading output. Rendering the first byte of each x-major cell as the wall/collision plane revealed a readable 7-row bitmap banner inside the maze.
Evidence:
analysis/disasm-load-assets.txtanalysis/map-index-xrefs.txtanalysis/map-decoding.mdanalysis/map-wall-white.pnganalysis/map-wall-annotated.png
RAG was checked, but it returned no NoMap3d-specific answer. The solve is based on direct local artifact evidence.
Solve
The reproducible decoder is solve/solve.py.
It performs these checks:
- Opens
files/extracted/gamepwn_nomap3d/assets.dmp. - Validates the map section header and expected dimensions.
- Extracts the x-major wall/collision plane.
- Validates invariant glyph shapes from the hidden banner.
- Reconstructs the HTB-format flag and writes it to
loot/flag-candidate.txt.
The harness accepted the generated candidate and stored the final flag in loot/flag.txt.
One correction was needed after platform submission: the visible wall banner uses a block font, but the exact HTB flag casing is mixed case. The decoder now preserves the intended lowercase glyphs instead of normalizing the whole banner to uppercase.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- For native GamePwn/raycaster challenges, parse the asset format before trying to play or patch the binary.
- Map orientation matters. If a map render looks nonsensical, validate how the binary indexes cells before closing the branch.
- HTB flags are case-sensitive. A readable bitmap phrase can still require exact mixed-case transcription.
- RAG/community memory can be useful, but for this challenge it was not specific enough; direct artifact evidence was decisive.
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: NoMap3d
- Category: GamePwn
- Difficulty: Medium
- Mode: file
- Remote instance: none
- Start time: 2026-06-13T02:15:51Z
- 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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c735f-0ef9-4098-a5bb-56c2f1db0657.zip | 6070285 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 3 shown in artifact inventory JSON |
files/extracted/gamepwn_nomap3d/assets.dmp | 10158080 | <hash redacted> | data | |
files/extracted/gamepwn_nomap3d/nomap3d | 22816 | <hash redacted> | ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=<hash redacted>, for GNU/Linux 3.2.0, not stripped |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-13T02:15:51Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-13T02:16:10Z | artifact inventory | analysis/artifact-inventory.json | 3 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-13T02:16:28Z | hypothesis recorded | hypothesis-board.md | Reverse the native 3D maze/raycaster and assets.dmp to recover the hidden map, exit condition, or encoded flag path; likely solve through asset parsing rather than manual play. | Medium | Run strings/file/disassembly, parse assets.dmp sections, identify map dimensions/textures/collision bytes, and compare against prior raycaster asset patterns. |
| 2026-06-13T02:16:29Z | checkpoint recorded | analysis/checkpoint-triage-20260613T021629027622Z-3752c3b3.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-13T02:17:44Z | RAG query | analysis/rag/rag-query-20260613T021737525922Z-b4521a03.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-13T02:28:00Z | RAG record | analysis/rag-records.md | Retrieved memory tagged MISSING | Medium | Validate or reject with live evidence |
| 2026-06-13T02:28:00Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-13T02:28:00Z | instrumentation plan | analysis/instrumentation-plan.md | Recover the NoMap3d flag from the asset map without manual gameplay. | High | Stop if map dimensions, glyph invariants, or HTB flag format validation fail instead of guessing visually. |
| 2026-06-13T02:28:20Z | evaluator | analysis/evaluator-20260613T022820020322Z-0072e8d9.md | Proceed | High | Run exploit gate, capture the flag candidate, then complete. |
| 2026-06-13T02:28:20Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-13T02:29:49Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
| 2026-06-13T03:37:54Z | branch closed | hypothesis-board.md | HTB platform rejected the all-uppercase interpretation; hidden bitmap content was right but exact flag casing was wrong. | High | Rerank hypotheses |
| 2026-06-13T03:37:54Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-13T03:38:05Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-13T03:38:05Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The ELF is a small native raycaster-style binary with useful exported symbols for asset loading, input, and raycasting.
assets.dmpcontains a259 x 12map section with three bytes per cell.- The binary indexes the map x-major, not row-major:
(x height + y) 3. - Rendering the first map byte as a wall/collision plane reveals a bitmap banner in the maze.
solve/solve.pydecodes the banner and writes the HTB-format flag candidate intoloot/; the harness captured it successfully.
RAG / Advisory Memory
RAG output is advisory only. Record evaluated retrievals with:
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
Metadata
- Platform: HackTheBox Challenges
- Category: GamePwn
- Challenge: NoMap3d
- Difficulty: Medium
- Source workspace:
<local workspace>
Validated Solve Chain
Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.
- Extract the file-only GamePwn archive and inspect the native ELF symbols before runtime work.
- Parse
assets.dmp: section type1stores player coordinates; section type2stores a259 x 12map with three bytes per cell. - Use x-major map indexing from the binary:
offset = map_start + (x height + y) 3. - Render the first byte of each map cell as the wall/collision plane. Rows
2..8form a 7-row bitmap banner. - Decode the banner into the HTB-format flag, preserving exact mixed-case glyph intent, and keep the raw flag only in
loot/.
Reusable Lessons
- For raycaster-style GamePwn challenges, asset parsing can be faster and safer than manual play or binary patching.
- If a rendered map looks wrong, confirm row-major versus column/x-major indexing from code references.
- Hidden text can be embedded in collision/wall planes rather than texture strings.
- Case matters for HTB submission; block-font banners may visually look uppercase even when the intended flag has lowercase characters.
- Treat RAG as advisory; direct asset evidence outranks unrelated retrieved memories.
Dead Ends
- Row-major map rendering produced misleading/noisy output.
- OCR over the rendered map was unreliable for leetspeak glyphs; direct bitmap validation was more reliable.
- The initial all-uppercase transcription was rejected by the platform. Mixed-case transcription fixed the issue.
Tool Quirks
- Tesseract misread the blocky bitmap font, especially digits and repeated glyphs.
- Missing Ghidra/rizin/radare2 did not block this solve because exported symbols and objdump were sufficient.
Evidence Paths
analysis/artifact-inventory.jsonanalysis/disasm-load-assets.txtanalysis/map-index-xrefs.txtanalysis/map-decoding.mdanalysis/map-wall-white.pnganalysis/map-wall-annotated.pnganalysis/research/nomap3d-ctfbase-casing.mdsolve/solve.pyloot/flag.txt
Ingestion Decision
- Proposed for LightRAG: yes
- Requires user approval before ingestion: yes
Hypothesis Board
Keep no more than 3 active hypotheses on Easy/Medium and 5 on Hard unless the user explicitly asks for breadth.
| Rank | Path | Evidence | Missing Proof | Cheapest Validation | Confidence | Status |
|---|---|---|---|---|---|---|
| 1 | Reverse the native 3D maze/raycaster and assets.dmp to recover the hidden map, exit condition, or encoded flag path; likely solve through asset parsing rather than manual play. | Archive contains a native executable named nomap3d plus assets.dmp, and the scenario says the player is lost without a map. | Run strings/file/disassembly, parse assets.dmp sections, identify map dimensions/textures/collision bytes, and compare against prior raycaster asset patterns. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|---|---|---|---|
| all-uppercase wall-bitmap casing | analysis/map-decoding.md | loot/flag-candidate.txt | HTB platform rejected the all-uppercase interpretation; hidden bitmap content was right but exact flag casing was wrong. | Use direct bitmap evidence plus community writeup only for casing disambiguation, then regenerate loot with mixed-case glyph mapping. |
Technical analogy
How to remember this solve
Think of the game like an arcade cabinet with a score counter behind the glass. The solve is finding where the game stores state and reading or changing it at the right moment.
For NoMap3d, 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.