Partial Encryption
Partial Encryption is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Partial Encryption attack path
Partial Encryption 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 Reversing evidence, validation, and reusable operator lessons.
Walkthrough flow
Extracted the HTB ZIP with the standard archive...
Static triage identified a small AES-NI runtime...
Reimplemented the narrow AES-NI decryptor locally...
Decrypted .data chunks into analysis/decrypted/ and...
Found validator stubs that compare individual argv[1]...
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.
- Reversing/Partial-Encryption/writeup.md
- htb-challenge/Reversing/Partial-Encryption/notes.md
- htb-challenge/Reversing/Partial-Encryption/memory-summary.md
- htb-challenge/Reversing/Partial-Encryption/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Reversing__Partial-Encryption__memory-summary.md.9392879455.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Reversing__Partial-Encryption__notes.md.f5a4260fe1.md
Technical Walkthrough
Writeup
Challenge
- Name: Partial-Encryption
- Category: Reversing
- Difficulty: Easy
- Mode: file
Summary
The program hides most of its validation logic in encrypted .data chunks. The static body contains a small AES-NI-based decryptor that allocates executable memory, decrypts selected chunks at runtime, and calls them. Reimplementing that decryptor reveals validator stubs that compare each flag character by index.
Artifact Inventory
Reference analysis/artifact-inventory.json and summarize the relevant files or remote surface.
partialencryption.exe: PE32+ x86-64 Windows console executable.- Imports include memory-permission APIs and anti-debug/runtime helpers, consistent with dynamically decrypted code.
Analysis
The static disassembly identified two important routines:
0x140001000: decrypts one 16-byte block usingaeskeygenassist,pxor, andaesdeclast.0x140001050: loops across encrypted chunks, uses the block decryptor, then callsVirtualProtectbefore returning an executable buffer.
After reproducing the decryptor, the decrypted payloads in analysis/decrypted/ disassembled as normal x64 stubs. The large stubs load argv[1], compare fixed character positions, and set a failure flag when any comparison fails.
Solve
Run:
python3 solve/solve.pyThe script reads the PE file, decrypts the runtime chunks, extracts the (index, character) comparisons, and prints the reconstructed HTB flag.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- When static strings and control flow are sparse but the binary imports memory-permission APIs, inspect runtime unpacking/decryption first.
- AES-NI instructions can be reimplemented for the narrow operation used by the binary; full Windows execution was not required.
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: Partial-Encryption
- Category: Reversing
- Difficulty: Easy
- Mode: file
- Remote instance: none
- Start time: 2026-06-10T08:53:40Z
- 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/a12c7378-617d-418e-8f57-5b462527b7bc.zip | 6067 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
files/extracted/rev_partialencryption/partialencryption.exe | 13312 | <hash redacted> | PE32+ executable (console) x86-64, for MS Windows |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-10T08:53:40Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-10T08:54:04Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-10T08:54:21Z | hypothesis recorded | hypothesis-board.md | Windows PE performs partial/runtime decryption; inspect imports/strings first, then run under Wine or emulate/decrypt transformed data dynamically. | Medium | Run file/strings/imports, then attempt controlled execution under Wine or equivalent to capture behavior and generated/decrypted data. |
| 2026-06-10T08:54:32Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-10T08:59:57Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-10T08:59:57Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
| 2026-06-10T09:00:09Z | evaluator | analysis/evaluator-20260610T090009280414Z-6c88eb10.md | Proceed | High | Solved locally with solve/solve.py and captured the recovered flag. |
Key Findings
- The binary is a PE32+ Windows console executable that imports
VirtualAlloc,VirtualProtect,VirtualFree,IsDebuggerPresent, and CRT output routines. - Static triage showed AES-NI instructions in the unpacking helper:
aeskeygenassistandaesdeclast. - The runtime decryptor at
0x140001050decrypts.datachunks block-by-block, allocates executable memory, marks it executable, and calls the decrypted code. - Reproduced the AES-NI decryptor locally and wrote decrypted payloads under
analysis/decrypted/. - The decrypted payloads are validation stubs that compare individual
argv[1]character positions and OR mismatches into a failure variable. solve/solve.pyreconstructs the expected flag from the decrypted validator comparisons without requiring Wine or a Windows debugger.
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: Reversing
- Challenge: Partial-Encryption
- 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.
- Extracted the HTB ZIP with the standard archive password and inventoried a single PE32+ x86-64 Windows console executable.
- Static triage identified a small AES-NI runtime decryptor using
aeskeygenassist,aesdeclast,VirtualAlloc, andVirtualProtect. - Reimplemented the narrow AES-NI decryptor locally instead of requiring Wine or a Windows debugger.
- Decrypted
.datachunks intoanalysis/decrypted/and disassembled them as raw x64 code. - Found validator stubs that compare individual
argv[1]character positions against constants and OR mismatch bits into a failure flag. - Wrote
solve/solve.pyto decrypt the chunks, extract the(index, character)comparisons, reconstruct the HTB flag, and support harness capture.
Reusable Lessons
- When a reversing prompt says static analysis is weak and the binary imports memory-permission APIs, look for runtime-decrypted executable chunks before spending time on string hunting.
- AES-NI instruction usage can often be reproduced narrowly; a full emulator is not always required.
- For validator stubs, direct comparison extraction from decrypted code can be faster and more reliable than attempting to run the original Windows PE.
Dead Ends
- Raw static strings did not reveal the flag.
- Direct local execution was not used because Wine was unavailable; the decryptor path was sufficient.
Tool Quirks
capstone,pefile, Wine, Ghidra, radare2/rizin, and gdb were not available locally.x86_64-w64-mingw32-objdumpwas available and sufficient for PE and raw x64 disassembly.Cryptowas installed but the final solver uses a pure-Python AES table implementation for portability.
Evidence Paths
analysis/disasm-mingw.txtanalysis/decrypted/manifest.txtanalysis/decrypted/*.asmsolve/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 | Windows PE performs partial/runtime decryption; inspect imports/strings first, then run under Wine or emulate/decrypt transformed data dynamically. | Challenge prompt says static analysis did not reveal much; extracted artifact is a small Windows PE executable. | Run file/strings/imports, then attempt controlled execution under Wine or equivalent to capture behavior and generated/decrypted data. | 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: Reversing
- Challenge: Partial-Encryption
- 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.
- Extracted the HTB ZIP with the standard archive password and inventoried a single PE32+ x86-64 Windows console executable.
- Static triage identified a small AES-NI runtime decryptor using
aeskeygenassist,aesdeclast,VirtualAlloc, andVirtualProtect. - Reimplemented the narrow AES-NI decryptor locally instead of requiring Wine or a Windows debugger.
- Decrypted
.datachunks intoanalysis/decrypted/and disassembled them as raw x64 code. - Found validator stubs that compare individual
argv[1]character positions against constants and OR mismatch bits into a failure flag. - Wrote
solve/solve.pyto decrypt the chunks, extract the(index, character)comparisons, reconstruct the HTB flag, and support harness capture.
Reusable Lessons
- When a reversing prompt says static analysis is weak and the binary imports memory-permission APIs, look for runtime-decrypted executable chunks before spending time on string hunting.
- AES-NI instruction usage can often be reproduced narrowly; a full emulator is not always required.
- For validator stubs, direct comparison extraction from decrypted code can be faster and more reliable than attempting to run the original Windows PE.
Dead Ends
- Raw static strings did not reveal the flag.
- Direct local execution was not used because Wine was unavailable; the decryptor path was sufficient.
Tool Quirks
capstone,pefile, Wine, Ghidra, radare2/rizin, and gdb were not available locally.x86_64-w64-mingw32-objdumpwas available and sufficient for PE and raw x64 disassembly.Cryptowas installed but the final solver uses a pure-Python AES table implementation for portability.
Evidence Paths
analysis/disasm-mingw.txtanalysis/decrypted/manifest.txtanalysis/decrypted/*.asmsolve/solve.pyloot/flag.txt
Ingestion Decision
- Proposed for LightRAG: yes
- Requires user approval before ingestion: yes
Notes
Notes
Scope
- Challenge: Partial-Encryption
- Category: Reversing
- Difficulty: Easy
- Mode: file
- Remote instance: none
- Start time: 2026-06-10T08:53:40Z
- 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/a12c7378-617d-418e-8f57-5b462527b7bc.zip | 6067 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
files/extracted/rev_partialencryption/partialencryption.exe | 13312 | <hash redacted> | PE32+ executable (console) x86-64, for MS Windows |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-10T08:53:40Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-10T08:54:04Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-10T08:54:21Z | hypothesis recorded | hypothesis-board.md | Windows PE performs partial/runtime decryption; inspect imports/strings first, then run under Wine or emulate/decrypt transformed data dynamically. | Medium | Run file/strings/imports, then attempt controlled execution under Wine or equivalent to capture behavior and generated/decrypted data. |
| 2026-06-10T08:54:32Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-10T08: <REDACTED> | |||||
| 2026-06-10T08:59:57Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
| 2026-06-10T09: <REDACTED> |
Key Findings
- The binary is a PE32+ Windows console executable that imports
VirtualAlloc,VirtualProtect,VirtualFree,IsDebuggerPresent, and CRT output routines. - Static triage showed AES-NI instructions in the unpacking helper:
aeskeygenassistandaesdeclast. - The runtime decryptor at
0x140001050decrypts.datachunks block-by-block, allocates executable memory, marks it executable, and calls the decrypted code. - Reproduced the AES-NI decryptor locally and wrote decrypted payloads under
analysis/decrypted/. - The decrypted payloads are validation stubs that compare individual
argv[1]character positions and OR mismatches into a failure variable. solve/solve.pyreconstructs the expected flag from the decrypted validator comparisons without requiring Wine or a Windows debugger.
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 taking apart a small appliance on a workbench. You do not need every screw at once; you trace the control path and rebuild just enough logic to make it reveal the answer.
For Partial Encryption, 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.