Follow The Money
Follow The Money is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Follow The Money attack path
Follow The Money 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 OSINT evidence, validation, and reusable operator lessons.
Walkthrough flow
Initial clue set
Cross-source correlation
Identity or asset pivot
Proof captured
Source coverage
High source coverage
Status: complete. This article is generated from 6 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.
- OSINT/Follow-the-Money/writeup.md
- htb-challenge/OSINT/Follow-the-Money/notes.md
- htb-challenge/OSINT/Follow-the-Money/memory-summary.md
- htb-challenge/OSINT/Follow-the-Money/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__OSINT__Follow-the-Money__memory-summary.md.abf462a127.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__OSINT__Follow-the-Money__notes.md.1e2a0caa44.md
Technical Walkthrough
Writeup
Challenge
- Name: Follow-the-Money
- Category: OSINT
- Difficulty: Easy
- Mode: remote
Summary
The challenge is a simulated blockchain-forensics SPA. The React bundle contains deterministic tool datasets, and the live backend accepts six sequential answers through /api/submit-answer. The main trap is that the accepted answer forms are shorter than the descriptive labels shown in the UI, and the backend also expects tool-usage tracking through /api/track-tool-usage.
Artifact Inventory
There are no local source files under files/; the challenge surface is remote. The relevant artifacts are:
analysis/remote/index-<secret redacted>js: React bundle with the simulated investigation datasetsanalysis/remote/start-challenge-response.txt: live question order and answer formatsanalysis/remote/charlie-sum.txt: verified Cluster Charlie totalanalysis/solve-transcript.json: solver transcript from the live run
Analysis
This is not a public-OSINT problem in practice. The bundle itself is the evidence source.
The overview and tool datasets isolate the suspect wallet bc1q7x4a9m2k8j5p3r9s1t6u8v2w7x4z9a1b2c3d4e5. The six investigation questions come from POST /api/start-challenge; the formats are live-confirmed in analysis/remote/start-challenge-response.txt.
The first correction came from live validation against the backend. The descriptive entity label in the bundle is Binance Exchange, but the accepted answer for question 1 is the shorter exchange name Binance. The same pattern applies to question 3: OXT identifies Wasabi CoinJoin, but the accepted protocol answer is Wasabi.
Question 2 is directly recoverable from the Evidence Terminal. The seven <secret redacted> payments sum to 0.01891004 BTC, recorded in analysis/remote/charlie-sum.txt.
For the identity questions, the bundle requires cross-correlation between multiple simulated tools:
- Chainalysis exposes the masked KYC email pattern
j*.crypto.*@proton.me - Crystal identifies the real-world name
James Mitchell Chen (92% match) - Arkham confirms the precise coordinates
37.774929, -122.419416
The remaining unknown was the exact email local-part suffix. Live validation against question 4 proved the accepted digital identity is <email redacted>, which matches both the Chainalysis mask and the campaign naming pattern.
The backend also enforces methodology. Before some answers are accepted, the session must record tool usage through /api/track-tool-usage. Tracking the six tools used by the frontend for the suspect address satisfies that gate.
Solve
The reproducible solver is solve/solve.py.
It performs this sequence:
POST /api/start-challenge- Track the required tools with
/api/track-tool-usagefor the suspect wallet - Submit the six confirmed answers in order
- Call
/api/get-flag - Write the raw flag only to
loot/flag-candidate.txt
Run it through the harness wrapper:
python3 scripts/challenge_exec.py OSINT/Follow-the-Money -- \
python3 OSINT/Follow-the-Money/solve/solve.pyFlag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- In simulated OSINT challenges, inspect the frontend bundle before doing real-world research.
- When the API and UI disagree, validate the exact accepted answer form against the backend instead of trusting the prettified label.
- Signed Flask-style session cookies are often readable even when they are not forgeable; they can still reveal useful execution-state details.
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: Follow-the-Money
- Category: OSINT
- Difficulty: Easy
- Mode: remote
- Remote instance: <TARGET>:32767
- Start time: 2026-06-07T20:56:23Z
- 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 |
|---|---|---|---|---|
| — | 0 | — | remote-only or no provided files | No local artifacts found under files/ |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-07T20:56:23Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T20:56:23Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T20:58:51Z | hypothesis recorded | hypothesis-board.md | Use the recovered SPA bundle and live challenge API to reconstruct the six ordered investigation answers, then submit them sequentially to obtain the final HTB flag. | Medium | Run a harness-gated solver that starts a fresh session, submits the six source-backed answers, and writes only the final flag candidate to loot/flag-candidate.txt. |
| 2026-06-07T20:58:51Z | checkpoint recorded | analysis/checkpoint-triage-20260607T205851165151Z-84331635.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-07T21:00:03Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-07T21:00:03Z | research skip | analysis/research/research-skip.md | Research intentionally skipped with recorded reason | Medium | Gate before exploit |
| 2026-06-07T21:00:14Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T21:00:14Z | evaluator | analysis/evaluator-20260607T210014903255Z-b8b67a13.md | Proceed | High | Run challenge_exec with solve/solve.py, then capture-flag and complete if the solver succeeds. |
| 2026-06-07T21:20:34Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-07T21:20:39Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The target is an nginx-hosted React SPA at
http://<TARGET>:32767/. - Main bundle:
analysis/remote/index-<secret redacted>js. - Live API endpoints:
- /api/start-challenge
- /api/submit-answer
- /api/get-flag
- /api/track-tool-usage
POST /api/start-challengereturns six sequential OSINT questions and asession_id.- The Flask-style signed session cookie is readable and records
tool_usage,answers, andcorrectstate, which helped confirm the methodology gate without exposing the server secret. - The frontend bundle contains deterministic simulated investigation-tool datasets; this is a frontend-evidence OSINT workflow, not external blockchain research.
- Primary suspect wallet evidence:
bc1q7x4a9m2k8j5p3r9s1t6u8v2w7x4z9a1b2c3d4e5. - The backend enforces professional-tool methodology.
POST /api/track-tool-usagemust record the expected tools before some answers are accepted. - Live validation corrected the answer forms for the first three steps:
- Q1 accepted Binance
- Q2 accepted 0.01891004
- Q3 accepted Wasabi
- Cluster Charlie victim payments sum to
0.01891004BTC; seeanalysis/remote/charlie-sum.txt. - Chainalysis provided the masked KYC email pattern
j*.crypto.*@proton.me; Crystal verified the real-world nameJames Mitchell Chen; Arkham confirmed the exact coordinates37.774929, -122.419416. - Live validation confirmed the Q4 digital identity answer is
<email redacted>. - Prepared solver:
solve/solve.py. - Raw final flag must be written to
loot/only and captured withchallenge_harness.py capture-flag.
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: OSINT
- Challenge: Follow-the-Money
- Difficulty: Easy
- Source workspace:
<local workspace>
Validated Solve Chain
Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.
1.
Reusable Lessons
-
Dead Ends
-
Tool Quirks
-
Evidence Paths
-
Ingestion Decision
- Proposed for LightRAG: yes/no
- 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 | Use the recovered SPA bundle and live challenge API to reconstruct the six ordered investigation answers, then submit them sequentially to obtain the final HTB flag. | Root page exposes React bundle; bundle contains tool datasets for primary suspect wallet, funding exchange, victim payment total, Wasabi CoinJoin transaction, KYC identity, and coordinates; /api/start-challenge returns six ordered questions. | Run a harness-gated solver that starts a fresh session, submits the six source-backed answers, and writes only the final flag candidate to loot/flag-candidate.txt. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
Memory Summary
approval_required: true
Sanitized Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: OSINT
- Challenge: Follow-the-Money
- Difficulty: Easy
- Source workspace:
<local workspace>
Validated Solve Chain
Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.
1.
Reusable Lessons
-
Dead Ends
-
Tool Quirks
-
Evidence Paths
-
Ingestion Decision
- Proposed for LightRAG: yes/no
- Requires user approval before ingestion: yes
Notes
Notes
Scope
- Challenge: Follow-the-Money
- Category: OSINT
- Difficulty: Easy
- Mode: remote
- Remote instance: <TARGET>:32767
- Start time: 2026-06-07T20:56:23Z
- 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 |
|---|---|---|---|---|
| — | 0 | — | remote-only or no provided files | No local artifacts found under files/ |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-07T20:56:23Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T20:56:23Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T20: <REDACTED>, then submit them sequentially to obtain the final HTB flag. | Medium | Run a harness-gated solver that starts a fresh session, submits the six source-backed answers, and writes only the final flag candidate to loot/flag-candidate.txt. | |||
| 2026-06-07T20:58:51Z | checkpoint recorded | analysis/checkpoint-triage-20260607T205851165151Z-84331635.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-07T21:00:03Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-07T21:00:03Z | research skip | analysis/research/research-skip.md | Research intentionally skipped with recorded reason | Medium | Gate before exploit |
| 2026-06-07T21:00:14Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T21: <REDACTED>, then capture-flag and complete if the solver succeeds. | |||||
| 2026-06-07T21: <REDACTED> | |||||
| 2026-06-07T21:20:39Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The target is an nginx-hosted React SPA at
http://<TARGET>:32767/. - Main bundle:
analysis/remote/index-<secret redacted>js. - Live API endpoints:
- /api/start-challenge
- /api/submit-answer
- /api/get-flag
- /api/track-tool-usage
POST /api/start-challengereturns six sequential OSINT questions and asession_id.- The Flask-style signed session cookie is readable and records
tool_usage,answers, andcorrectstate, which helped confirm the methodology gate without exposing the server secret. - The frontend bundle contains deterministic simulated investigation-tool datasets; this is a frontend-evidence OSINT workflow, not external blockchain research.
- Primary suspect wallet evidence:
bc1q7x4a9m2k8j5p3r9s1t6u8v2w7x4z9a1b2c3d4e5. - The backend enforces professional-tool methodology.
POST /api/track-tool-usagemust record the expected tools before some answers are accepted. - Live validation corrected the answer forms for the first three steps:
- Q1 accepted Binance
- Q2 accepted 0.01891004
- Q3 accepted Wasabi
- Cluster Charlie victim payments sum to
0.01891004BTC; seeanalysis/remote/charlie-sum.txt. - Chainalysis provided the masked KYC email pattern
j*.crypto.*@proton.me; Crystal verified the real-world nameJames Mitchell Chen; Arkham confirmed the exact coordinates37.774929, -122.419416. - Live validation confirmed the Q4 digital identity answer is
<email redacted>. - Prepared solver:
solve/solve.py. - Raw final flag must be written to
loot/only and captured withchallenge_harness.py capture-flag.
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.
Technical analogy
How to remember this solve
Think of OSINT like building a detective board. Each source is one pinned note; the solve comes from connecting the notes that agree with each other and rejecting the ones that only look plausible.
For Follow The Money, 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.