LightningFast
LightningFast is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
LightningFast attack path
LightningFast 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
Treat the downloadable game as a Unity IL2CPP client...
Use metadata strings to identify /ack, /endpoints,...
Confirm with IL2CPP recovery that getScore and...
Request /endpoints from the live backend to get the...
POST a JSON score body to the returned setter route...
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/LightningFast/writeup.md
- htb-challenge/GamePwn/LightningFast/notes.md
- htb-challenge/GamePwn/LightningFast/memory-summary.md
- htb-challenge/GamePwn/LightningFast/hypothesis-board.md
Technical Walkthrough
Writeup
Challenge
- Name: LightningFast
- Category: GamePwn
- Difficulty: Medium
- Mode: hybrid
Summary
LightningFast is a Unity IL2CPP game that stores the player's score on the supplied self-hosted backend. The client hides the current score routes behind /endpoints, but the backend trusts the score value submitted by the client. Once the dynamic setter route is recovered, submitting the required score and then calling /buyflag returns the challenge flag.
Artifact Inventory
The archive contains a Windows x64 Unity IL2CPP build:
LightningFast.exeGameAssembly.dllUnityPlayer.dllLightningFast_Data/il2cpp_data/Metadata/global-metadata.datLightningFast_Data/data.unity3d
The remote service is an Express-style HTTP backend at <TARGET>:31741. Local probes confirmed /ack, /endpoints, a dynamic getter route, a dynamic setter route, and /buyflag. The full inventory is in analysis/artifact-inventory.json.
Analysis
Static strings showed the obvious client routes /ack, /buyflag, and /endpoints, plus the PlayerPrefs names getScore and setScore. Those PlayerPrefs names are not the actual score routes; they are local keys used after the client retrieves dynamic route names from /endpoints.
IL2CPP recovery with Il2CppDumper identified the relevant classes: MenuHandler, OptionsHandler, Player, ScoreHandler, and ShopMenuHandler. The recovered flow showed:
OptionsHandlervalidates a user-suppliedhttp://<ipv4>:<port>server and checks/ack.MenuHandlerrequests/endpoints, parses the JSON response, and stores the returnedgetterandsettervalues in PlayerPrefs.ScoreHandlerreads the saved getter route and fetches the current score.Player.OnTriggerEnter2Dsubmits a JSON body shaped like{"score": <score>}to the saved setter route when the game ends.ShopMenuHandlercalls/buyflag.
The important correction was that Anti-Cheat Toolkit obfuscation only protects the local integer representation. The submitted HTTP body contains the decrypted score string, so defeating or patching the obfuscation was unnecessary. Live validation in analysis/endpoints-probe.txt and analysis/score-set-buyflag-probe.txt confirmed the backend accepts a direct score update and then allows /buyflag.
Solve
Run the reproducible solver:
cd <local workspace>
python3 solve/solve.py --base-url http://<TARGET>:31741 --output loot/flag-candidate.txtThen capture it through the harness:
cd <local workspace>
python3 scripts/challenge_harness.py capture-flag GamePwn/LightningFast --from loot/flag-candidate.txtThe solver asks /endpoints for the current getter and setter route names, posts a score of 1000000 to the setter route, calls /buyflag, and writes the result to loot/flag-candidate.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- For Unity IL2CPP GamePwn challenges, metadata strings are useful but must be tied back to code flow;
getScoreandsetScorewere storage keys, not remote routes. - Dynamic backend configuration routes are high-value targets because they often reveal hidden API paths without needing client patching.
- Client-side anti-cheat does not matter if the server accepts trusted plaintext state from the client.
- Keep live probes small and client-derived. The successful path came from reversing the Unity flow, not broad fuzzing.
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: LightningFast
- Category: GamePwn
- Difficulty: Medium
- Mode: hybrid
- Remote instance: none
- Start time: 2026-06-13T04:51: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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c736e-ef69-45db-a6ee-58168a4b1281.zip | 20165876 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 46 shown in artifact inventory JSON |
files/extracted/gamepwn_lightningfast/GameAssembly.dll | 11098112 | <hash redacted> | PE32+ executable (DLL) (GUI) x86-64, for MS Windows | |
files/extracted/gamepwn_lightningfast/LightningFast.exe | 653824 | <hash redacted> | PE32+ executable (GUI) x86-64, for MS Windows | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/Resources/unity default resources | 4849280 | <hash redacted> | data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/RuntimeInitializeOnLoads.json | 13 | <hash redacted> | JSON data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/ScriptingAssemblies.json | 2648 | <hash redacted> | JSON data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/app.info | 27 | <hash redacted> | ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/boot.config | 51 | <hash redacted> | ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/data.unity3d | 1667048 | <hash redacted> | data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/Metadata/global-metadata.dat | 2488964 | <hash redacted> | data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/Resources/mscorlib.dll-resources.dat | 337563 | <hash redacted> | data | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/Browsers/Compat.browser | 1627 | <hash redacted> | exported SGML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/DefaultWsdlHelpGenerator.aspx | 62476 | <hash redacted> | HTML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/machine.config | 29399 | <hash redacted> | XML 1.0 document text, ASCII text, with very long lines (541), with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/settings.map | 2670 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/web.config | 11840 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/Browsers/Compat.browser | 1627 | <hash redacted> | exported SGML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/DefaultWsdlHelpGenerator.aspx | 62476 | <hash redacted> | HTML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/machine.config | 33958 | <hash redacted> | XML 1.0 document text, ASCII text, with very long lines (541), with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/settings.map | 2670 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/web.config | 19101 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/Browsers/Compat.browser | 1627 | <hash redacted> | exported SGML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/DefaultWsdlHelpGenerator.aspx | 62476 | <hash redacted> | HTML document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/machine.config | 34419 | <hash redacted> | XML 1.0 document text, ASCII text, with very long lines (541), with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/settings.map | 2670 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/web.config | 19110 | <hash redacted> | XML 1.0 document text, ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/browscap.ini | 328963 | <hash redacted> | Generic INItialization configuration [DefaultProperties] | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/config | 3319 | <hash redacted> | ASCII text, with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/mconfig/config.xml | 26433 | <hash redacted> | XML 1.0 document text, ASCII text, with very long lines (334), with CRLF line terminators | |
files/extracted/gamepwn_lightningfast/UnityCrashHandler64.exe | 1125768 | <hash redacted> | PE32+ executable (GUI) x86-64, for MS Windows | |
files/extracted/gamepwn_lightningfast/UnityPlayer.dll | 28011400 | <hash redacted> | PE32+ executable (DLL) (console) x86-64, for MS Windows | |
files/extracted/gamepwn_lightningfast/baselib.dll | 498176 | <hash redacted> | PE32+ executable (DLL) (console) x86-64, for MS Windows |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-13T04:51:36Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-13T04:51:36Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-13T04:51:51Z | hypothesis recorded | hypothesis-board.md | Analyze the self-hosted game package and remote service to identify a deterministic client/server state, protocol weakness, or game-speed/timing bypass that allows flag retrieval. | Medium | Extract the archive, identify engine/runtime and network endpoints, then inspect scripts/assets/source before live interaction. |
| 2026-06-13T04:51:51Z | checkpoint recorded | analysis/checkpoint-triage-20260613T045151720809Z-29ba213b.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-13T04:52:21Z | RAG query | analysis/rag/rag-query-20260613T045211216384Z-52872daf.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-13T04:52:21Z | artifact inventory | analysis/artifact-inventory.json | 32 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-13T04:57:09Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-13T04:57:09Z | RAG record | analysis/rag-records.md | Retrieved memory tagged GENERIC | Medium | Validate or reject with live evidence |
| 2026-06-13T04:57:09Z | instrumentation plan | analysis/instrumentation-plan.md | Reproduce the Unity client score/flag flow directly over HTTP using only client-derived routes and body fields. | High | Stop after two route/body families fail without a new client-derived symbol or server response difference; do not broad fuzz unrelated routes. |
| 2026-06-13T04:57:31Z | local memory search | analysis/research/local-memory-search-20260613T045731968086Z-dd8af0d8.md | Found 8 safe prior-note result(s) | Medium | Record useful result or skip |
| 2026-06-13T04:58:01Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-13T04:58:14Z | evaluator | analysis/evaluator-20260613T045814508809Z-43c11d34.md | Proceed | High | Use challenge_exec or gated solver probes for /ack score-shape validation. |
| 2026-06-13T05:15:00Z | solve script | solve/solve.py | Reproducible HTTP solver added for dynamic endpoint discovery, trusted score update, and buyflag retrieval | High | Capture flag through harness |
| 2026-06-13T05:15:32Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-13T05:17:19Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The archive is a Unity IL2CPP game client with network logic in custom classes recovered through metadata and Il2CppDumper output.
/endpointsreturns dynamic getter/setter routes that the client stores under local PlayerPrefs keys.- The setter route accepts a plaintext JSON score value from the client.
- Once the required score is set,
/buyflagreturns the challenge 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: GamePwn
- Challenge: LightningFast
- 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.
- Treat the downloadable game as a Unity IL2CPP client and recover metadata/code flow before guessing routes.
- Use metadata strings to identify
/ack,/endpoints,/buyflag,getScore, andsetScore. - Confirm with IL2CPP recovery that
getScoreandsetScoreare PlayerPrefs keys populated from the/endpointsJSON response. - Request
/endpointsfrom the live backend to get the dynamic getter/setter route names. - POST a JSON score body to the returned setter route with the required threshold value.
- Call
/buyflagafter the accepted score update and capture the HTB-format flag through the harness.
Reusable Lessons
- In Unity GamePwn challenges, do not assume visible strings are direct remote routes; distinguish storage keys, literal routes, and dynamically populated fields.
- Anti-cheat integer obfuscation can be irrelevant when the network request serializes the decrypted value.
- A small client-derived HTTP solver is preferable to broad fuzzing once the Unity flow identifies exact request shapes.
- Dynamic backend endpoint discovery routes are a strong target when a game is described as self-hosted.
Dead Ends
- Broad
/ackquery/body score guesses did not change score state. - Treating
getScoreandsetScoreas literal remote paths was incomplete; they are local key names. - Defeating Anti-Cheat Toolkit internals was unnecessary for the final solve.
Tool Quirks
- Il2CppDumper required a local .NET runtime setup under
analysis/tools/dotnet. - UnityPy helped inspect serialized scene objects, but the route fields were populated at runtime from
/endpoints.
Evidence Paths
analysis/artifact-inventory.jsonanalysis/metadata-literals-interesting.txtanalysis/il2cppdump/dump.csanalysis/il2cppdump/menu-core-disasm.txtanalysis/il2cppdump/missing-methods-disasm.txtanalysis/endpoints-probe.txtanalysis/score-set-buyflag-probe.txtsolve/solve.pyloot/flag.txt
Ingestion Decision
- Proposed for LightRAG: yes, after user approval
- 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 | Analyze the self-hosted game package and remote service to identify a deterministic client/server state, protocol weakness, or game-speed/timing bypass that allows flag retrieval. | Medium GamePwn hybrid challenge with downloadable archive and remote service at <TARGET>:31741; scenario emphasizes very fast gameplay and self-hosted game. | Extract the archive, identify engine/runtime and network endpoints, then inspect scripts/assets/source before live interaction. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
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 LightningFast, 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.