Pivot Easy
Pivot Easy is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Pivot Easy attack path
Pivot Easy 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 Coding evidence, validation, and reusable operator lessons.
Walkthrough flow
Fingerprinted the remote as the standard HTB Coding...
Captured the prompt from the root page and identified...
Chose Dijkstra because edge weights are non-uniform...
Implemented host-name-to-ID mapping, adjacency lists,...
Submitted the Python solution through /run.
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.
- Coding/Pivot-Easy/writeup.md
- htb-challenge/Coding/Pivot-Easy/notes.md
- htb-challenge/Coding/Pivot-Easy/memory-summary.md
- htb-challenge/Coding/Pivot-Easy/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Coding__Pivot-Easy__memory-summary.md.fcd9210e11.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Coding__Pivot-Easy__notes.md.a7330e1a22.md
Technical Walkthrough
Writeup
Challenge
- Name: Pivot-Easy
- Category: Coding
- Difficulty: Easy
- Mode: remote
Summary
Pivot Easy is a remote HTB Coding runner. The prompt describes a directed weighted graph of hosts and pivot risks, then asks for the minimum cumulative detection risk from a compromised host to the Core Administration Server. The correct solution is Dijkstra's shortest-path algorithm with a host-name-to-ID map and a heap.
Artifact Inventory
Reference analysis/artifact-inventory.json and summarize the relevant files or remote surface.
analysis/remote/root-http.txt: captured the full challenge prompt and frontend runner.analysis/remote/prompts.js: captured the default language templates.analysis/remote/initial-nc-probe.txt: confirmed the port accepts TCP but the useful interface is HTTP.solve/solution.py: submitted algorithm implementation.solve/solve.py: reproducible submitter for/run.analysis/remote/run-response.json: saved runner response from the successful submission.
Analysis
The prompt states that each pivot path is unidirectional and has a detection risk. The required output is a single integer: the minimum cumulative risk from the starting host to the target host. Since edge weights are non-uniform and the constraints are large (N up to 150000 and M up to 1000000), BFS and adjacency matrices are inappropriate.
The implementation maps each host name to an integer ID as it is encountered, stores outgoing edges in adjacency lists, and runs Dijkstra with heapq. The algorithm exits as soon as the target is popped from the heap, which avoids unnecessary work on large hidden cases.
Solve
The submitted code is in solve/solution.py. It supports both likely first-line formats:
N M start targetN Mfollowed by a second line containingstart target
The submitter in solve/solve.py posts the solution to /run as Python, saves the raw JSON response to analysis/remote/run-response.json, and writes any returned flag candidate to loot/flag-candidate.txt. The harness then validates and stores the flag in loot/flag.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- For weighted graph routing problems, confirm whether edges are directed before choosing the algorithm.
- Large constraints rule out adjacency matrices and all-pairs algorithms.
- Treat host labels as opaque strings; map them to integer IDs for performance.
- Save the
/runresponse so failed hidden tests can be debugged without rerunning blindly.
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: Pivot-Easy
- Category: Coding
- Difficulty: Easy
- Mode: remote
- Remote instance: <TARGET>:30290
- Start time: 2026-06-07T23:43:27Z
- 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-07T23:43:27Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T23:43:38Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T23:43:38Z | hypothesis recorded | hypothesis-board.md | Remote Coding service likely exposes an HTTP runner or challenge API; identify protocol and problem format before submitting code. | Medium | Probe HTTP root and raw TCP banner, then inspect page JavaScript/API endpoints if HTTP is present. |
| 2026-06-07T23:43:54Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T23:43:54Z | checkpoint recorded | analysis/checkpoint-triage-20260607T234354500083Z-2c1efa2a.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-07T23:45:02Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T23:45:02Z | hypothesis recorded | hypothesis-board.md | Submit heap-based Dijkstra solution for directed weighted graph with host-name mapping. | Medium | Run solution against sample, then submit through /run and capture flag if all tests pass. |
| 2026-06-07T23:45:12Z | evaluator | analysis/evaluator-20260607T234512105821Z-4b01b905.md | Proceed | High | Run solve/solve.py, capture flag through harness, then complete if successful. |
| 2026-06-07T23:45:53Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-07T23:46:33Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- Remote service is the standard HTB Coding HTTP runner.
- Useful endpoint is
POST /run, as shown inanalysis/remote/root-http.txt. - The challenge is a directed weighted shortest-path problem over host names.
- Constraints require an efficient single-source shortest-path algorithm.
solve/solution.pyuses Dijkstra with a heap, adjacency lists, and host-name ID mapping.- The solver supports both
N M start targetandN Mplus a secondstart targetline. solve/solve.pysubmitted the code and stored the successful response inanalysis/remote/run-response.json.- The harness captured the validated flag into
loot/flag.txt.
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: Coding
- Challenge: Pivot-Easy
- 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.
- Fingerprinted the remote as the standard HTB Coding HTTP runner.
- Captured the prompt from the root page and identified a directed weighted shortest-path problem.
- Chose Dijkstra because edge weights are non-uniform and constraints are large.
- Implemented host-name-to-ID mapping, adjacency lists, and a
heapqpriority queue. - Submitted the Python solution through
/run. - Captured the returned flag through the harness without printing it.
Reusable Lessons
- Use Dijkstra for single-source shortest path when weights are non-negative and non-uniform.
- Map arbitrary string node labels to compact integer IDs before building large graphs.
- Support minor input-format variation when the prompt wording and example differ slightly.
Dead Ends
- Raw TCP probe was not the useful interface; HTTP
/runwas the correct runner path. - BFS was rejected because risks are weighted.
Tool Quirks
- The frontend JavaScript posts JSON to
/runwith fieldscodeandlanguage. - The runner returns JSON; successful responses can contain the flag inside the response body.
Evidence Paths
analysis/remote/root-http.txtanalysis/remote/prompts.jsanalysis/remote/run-response.jsonsolve/solution.pysolve/solve.py
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 | Remote Coding service likely exposes an HTTP runner or challenge API; identify protocol and problem format before submitting code. | Challenge provides only remote host <TARGET>:30290 and a graph/pathfinding scenario. | Probe HTTP root and raw TCP banner, then inspect page JavaScript/API endpoints if HTTP is present. | Medium | Active | |
| 1 | Submit heap-based Dijkstra solution for directed weighted graph with host-name mapping. | Problem statement in analysis/remote/root-http.txt specifies lowest cumulative detection risk over unidirectional weighted paths and large graph constraints. | Run solution against sample, then submit through /run and capture flag if all tests pass. | 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: Coding
- Challenge: Pivot-Easy
- 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.
- Fingerprinted the remote as the standard HTB Coding HTTP runner.
- Captured the prompt from the root page and identified a directed weighted shortest-path problem.
- Chose Dijkstra because edge weights are non-uniform and constraints are large.
- Implemented host-name-to-ID mapping, adjacency lists, and a
heapqpriority queue. - Submitted the Python solution through
/run. - Captured the returned flag through the harness without printing it.
Reusable Lessons
- Use Dijkstra for single-source shortest path when weights are non-negative and non-uniform.
- Map arbitrary string node labels to compact integer IDs before building large graphs.
- Support minor input-format variation when the prompt wording and example differ slightly.
Dead Ends
- Raw TCP probe was not the useful interface; HTTP
/runwas the correct runner path. - BFS was rejected because risks are weighted.
Tool Quirks
- The frontend JavaScript posts JSON to
/runwith fieldscodeandlanguage. - The runner returns JSON; successful responses can contain the flag inside the response body.
Evidence Paths
analysis/remote/root-http.txtanalysis/remote/prompts.jsanalysis/remote/run-response.jsonsolve/solution.pysolve/solve.py
Ingestion Decision
- Proposed for LightRAG: yes
- Requires user approval before ingestion: yes
Notes
Notes
Scope
- Challenge: Pivot-Easy
- Category: Coding
- Difficulty: Easy
- Mode: remote
- Remote instance: <TARGET>:30290
- Start time: 2026-06-07T23:43:27Z
- 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-07T23:43:27Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T23:43:38Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T23:43:38Z | hypothesis recorded | hypothesis-board.md | Remote Coding service likely exposes an HTTP runner or challenge API; identify protocol and problem format before submitting code. | Medium | Probe HTTP root and raw TCP banner, then inspect page JavaScript/API endpoints if HTTP is present. |
| 2026-06-07T23:43:54Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T23:43:54Z | checkpoint recorded | analysis/checkpoint-triage-20260607T234354500083Z-2c1efa2a.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-07T23:45:02Z | artifact inventory | analysis/artifact-inventory.json | 0 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T23: <REDACTED>, then submit through /run and capture flag if all tests pass. | |||||
| 2026-06-07T23: <REDACTED>, capture flag through harness, then complete if successful. | |||||
| 2026-06-07T23: <REDACTED> | |||||
| 2026-06-07T23:46:33Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- Remote service is the standard HTB Coding HTTP runner.
- Useful endpoint is
POST /run, as shown inanalysis/remote/root-http.txt. - The challenge is a directed weighted shortest-path problem over host names.
- Constraints require an efficient single-source shortest-path algorithm.
solve/solution.pyuses Dijkstra with a heap, adjacency lists, and host-name ID mapping.- The solver supports both
N M start targetandN Mplus a secondstart targetline. solve/solve.pysubmitted the code and stored the successful response inanalysis/remote/run-response.json.- The harness captured the validated flag into
loot/flag.txt.
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 it like turning a word problem into a repeatable calculator. Once the rule is clear, the solve is making the computer do the boring part consistently.
For Pivot Easy, 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.