Challenge / GamePwn

LightningFast

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

MediumPublished 2024-08-10Sanitized local writeup

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.

LightningFast sanitized attack graph

Walkthrough flow

01

Treat the downloadable game as a Unity IL2CPP client...

02

Use metadata strings to identify /ack, /endpoints,...

03

Confirm with IL2CPP recovery that getScore and...

04

Request /endpoints from the live backend to get the...

05

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.

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.

  • 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.exe
  • GameAssembly.dll
  • UnityPlayer.dll
  • LightningFast_Data/il2cpp_data/Metadata/global-metadata.dat
  • LightningFast_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:

  • OptionsHandler validates a user-supplied http://<ipv4>:<port> server and checks /ack.
  • MenuHandler requests /endpoints, parses the JSON response, and stores the returned getter and setter values in PlayerPrefs.
  • ScoreHandler reads the saved getter route and fetches the current score.
  • Player.OnTriggerEnter2D submits a JSON body shaped like {"score": <score>} to the saved setter route when the game ends.
  • ShopMenuHandler calls /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:

bash
cd <local workspace>
python3 solve/solve.py --base-url http://<TARGET>:31741 --output loot/flag-candidate.txt

Then capture it through the harness:

bash
cd <local workspace>
python3 scripts/challenge_harness.py capture-flag GamePwn/LightningFast --from loot/flag-candidate.txt

The 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; getScore and setScore were 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

FileSizeSHA256TypeNotes
files/a12c736e-ef69-45db-a6ee-58168a4b1281.zip20165876<hash redacted>Zip archive data, at least v1.0 to extract, compression method=storezip entries: 46 shown in artifact inventory JSON
files/extracted/gamepwn_lightningfast/GameAssembly.dll11098112<hash redacted>PE32+ executable (DLL) (GUI) x86-64, for MS Windows
files/extracted/gamepwn_lightningfast/LightningFast.exe653824<hash redacted>PE32+ executable (GUI) x86-64, for MS Windows
files/extracted/gamepwn_lightningfast/LightningFast_Data/Resources/unity default resources4849280<hash redacted>data
files/extracted/gamepwn_lightningfast/LightningFast_Data/RuntimeInitializeOnLoads.json13<hash redacted>JSON data
files/extracted/gamepwn_lightningfast/LightningFast_Data/ScriptingAssemblies.json2648<hash redacted>JSON data
files/extracted/gamepwn_lightningfast/LightningFast_Data/app.info27<hash redacted>ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/boot.config51<hash redacted>ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/data.unity3d1667048<hash redacted>data
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/Metadata/global-metadata.dat2488964<hash redacted>data
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/Resources/mscorlib.dll-resources.dat337563<hash redacted>data
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/Browsers/Compat.browser1627<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.aspx62476<hash redacted>HTML document text, ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/2.0/machine.config29399<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.map2670<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.config11840<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.browser1627<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.aspx62476<hash redacted>HTML document text, ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.0/machine.config33958<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.map2670<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.config19101<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.browser1627<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.aspx62476<hash redacted>HTML document text, ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/4.5/machine.config34419<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.map2670<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.config19110<hash redacted>XML 1.0 document text, ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/browscap.ini328963<hash redacted>Generic INItialization configuration [DefaultProperties]
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/config3319<hash redacted>ASCII text, with CRLF line terminators
files/extracted/gamepwn_lightningfast/LightningFast_Data/il2cpp_data/etc/mono/mconfig/config.xml26433<hash redacted>XML 1.0 document text, ASCII text, with very long lines (334), with CRLF line terminators
files/extracted/gamepwn_lightningfast/UnityCrashHandler64.exe1125768<hash redacted>PE32+ executable (GUI) x86-64, for MS Windows
files/extracted/gamepwn_lightningfast/UnityPlayer.dll28011400<hash redacted>PE32+ executable (DLL) (console) x86-64, for MS Windows
files/extracted/gamepwn_lightningfast/baselib.dll498176<hash redacted>PE32+ executable (DLL) (console) x86-64, for MS Windows

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-13T04:51:36Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-13T04:51:36Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-13T04:51:51Zhypothesis recordedhypothesis-board.mdAnalyze 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.MediumExtract the archive, identify engine/runtime and network endpoints, then inspect scripts/assets/source before live interaction.
2026-06-13T04:51:51Zcheckpoint recordedanalysis/checkpoint-triage-20260613T045151720809Z-29ba213b.mdCheckpoint for TRIAGEHighUse checkpoint to drive next decision
2026-06-13T04:52:21ZRAG queryanalysis/rag/rag-query-20260613T045211216384Z-52872daf.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-13T04:52:21Zartifact inventoryanalysis/artifact-inventory.json32 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-13T04:57:09Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-13T04:57:09ZRAG recordanalysis/rag-records.mdRetrieved memory tagged GENERICMediumValidate or reject with live evidence
2026-06-13T04:57:09Zinstrumentation plananalysis/instrumentation-plan.mdReproduce the Unity client score/flag flow directly over HTTP using only client-derived routes and body fields.HighStop 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:31Zlocal memory searchanalysis/research/local-memory-search-20260613T045731968086Z-dd8af0d8.mdFound 8 safe prior-note result(s)MediumRecord useful result or skip
2026-06-13T04:58:01Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-13T04:58:14Zevaluatoranalysis/evaluator-20260613T045814508809Z-43c11d34.mdProceedHighUse challenge_exec or gated solver probes for /ack score-shape validation.
2026-06-13T05:15:00Zsolve scriptsolve/solve.pyReproducible HTTP solver added for dynamic endpoint discovery, trusted score update, and buyflag retrievalHighCapture flag through harness
2026-06-13T05:15:32Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-13T05:17:19Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional 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.
  • /endpoints returns 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, /buyflag returns the challenge flag.

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

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.

  1. Treat the downloadable game as a Unity IL2CPP client and recover metadata/code flow before guessing routes.
  2. Use metadata strings to identify /ack, /endpoints, /buyflag, getScore, and setScore.
  3. Confirm with IL2CPP recovery that getScore and setScore are PlayerPrefs keys populated from the /endpoints JSON response.
  4. Request /endpoints from the live backend to get the dynamic getter/setter route names.
  5. POST a JSON score body to the returned setter route with the required threshold value.
  6. Call /buyflag after 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 /ack query/body score guesses did not change score state.
  • Treating getScore and setScore as 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.json
  • analysis/metadata-literals-interesting.txt
  • analysis/il2cppdump/dump.cs
  • analysis/il2cppdump/menu-core-disasm.txt
  • analysis/il2cppdump/missing-methods-disasm.txt
  • analysis/endpoints-probe.txt
  • analysis/score-set-buyflag-probe.txt
  • solve/solve.py
  • loot/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.

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus
1Analyze 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.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit 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.