Emo
Emo is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Emo attack path
Emo 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 Forensics evidence, validation, and reusable operator lessons.
Walkthrough flow
Extract HTB archive to a Word OLE/CFB document.
Parse OLE streams and identify WordDocument plus VBA...
Decompress VBA modules to confirm Document_open()...
Recover the hidden PowerShell command from...
Base64-decode the PowerShell as UTF-16LE.
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.
- Forensics/Emo/writeup.md
- htb-challenge/Forensics/Emo/notes.md
- htb-challenge/Forensics/Emo/memory-summary.md
- htb-challenge/Forensics/Emo/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Forensics__Emo__memory-summary.md.90437b0caa.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Forensics__Emo__notes.md.334b95fbd2.md
Technical Walkthrough
Writeup
Challenge
- Name: Emo
- Category: Forensics
- Difficulty: Easy
- Mode: file
Summary
The supplied archive contains a single Word OLE document with obfuscated VBA. Static analysis recovered a hidden PowerShell launcher from the WordDocument stream. The decoded PowerShell builds a ransomware-style config from numeric byte arrays XORed with 0xdf; that decoded config contains the flag.
Artifact Inventory
files/a12c736b-5e32-4f03-b88d-a27bcf511444.zip: HTB archive, extracted with the standard challenge password.files/extracted/emo.doc: Word OLE/CFB document with VBA macro streams and an obfuscated PowerShell command stored in document text.analysis/artifact-inventory.json: harness-generated file inventory with hashes and file types.
Analysis
The document was handled with static analysis only. Initial file and string checks showed an OLE Word document with VBA indicators and an obfuscated Powershell -windowstyle hidden -ENCOD command. A local OLE stream parser identified the WordDocument stream and the macro modules under analysis/ole_streams/.
The decompressed macro sources show this control flow:
Document_open()callsGet4ipjzmjfvp.X8twf_cydt6.- The loader reads
Dw75ayd2hpcab6.StoryRanges.Item(1). - It removes the marker string
][(s)]w. - It applies a character-skipping transform: keep the first 50 characters, then take every second character.
- The result is a Base64 PowerShell command.
The decoded PowerShell stage creates a working directory under the user profile, prepares an executable/config path, lists several .htb download URLs, and builds a byte array named $FN5ggmsH. The numeric $FN5ggmsH arrays decode cleanly when each byte is XORed with 0xdf, yielding a config string with the embedded flag.
Key evidence:
analysis/vba_decompressed/007_Dw75ayd2hpcab6.bin.offset_1119.txtanalysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txtanalysis/macro-transform-decode.txtanalysis/solver/stage1-powershell-redacted.txtanalysis/solver/xor-config-redacted.txt
Solve
Run the static solver from the challenge workspace:
python3 solve/solve.pyThe solver parses the OLE file from files/extracted/emo.doc, reads WordDocument, applies the macro deobfuscation transform, decodes the PowerShell stage, XOR-decodes the $FN5ggmsH numeric config arrays, and writes the recovered flag to loot/flag.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- For macro-based Word forensics, the payload may be in document body text rather than only in VBA streams.
- Obfuscated PowerShell launchers can have layered transforms: marker removal, character skipping, Base64, then a second byte-level decode.
- Keep raw flags in
loot/only; analysis files should be redacted after exploratory extraction.
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: Emo
- Category: Forensics
- Difficulty: Easy
- Mode: file
- Remote instance: none
- Start time: 2026-06-09T14:15:06Z
- 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/a12c736b-5e32-4f03-b88d-a27bcf511444.zip | 99505 | <hash redacted> | Zip archive data, at least v2.0 to extract, compression method=deflate | zip entries: 1 shown in artifact inventory JSON |
files/extracted/emo.doc | 210432 | <hash redacted> | Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 1252, Subject: Handmade Argentina Handcrafted Frozen Towels yellow Frozen virtual Guatemala array Lesotho JBOD, Template: Normal.dotm, Revision Number: 1, Name of Creating Application: Microsoft Office Word, Create Time/Date: Sat Oct 31 00:48:00 2020, Last Saved Time/Date: Tue Nov 3 03:14:00 2020, Number of Pages: 1, Number of Words: 9339, Number of Characters: 53237, Security: 8 |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-09T14:15:06Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-09T14:15:25Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-09T14:15:42Z | hypothesis recorded | hypothesis-board.md | Static macro/OLE analysis of emo.doc should reveal the ransomware loader, embedded payload indicators, or the flag. | Medium | Run file/strings/OLE stream inventory, extract VBA streams without executing macros, then search decoded macro/payload content for HTB-format or staged script data. |
| 2026-06-09T14:15:42Z | research skip | analysis/research/research-skip.md | Research intentionally skipped with recorded reason | Medium | Gate before exploit |
| 2026-06-09T14:25:18Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-09T14:26:23Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
files/extracted/emo.docis a Word OLE/CFB document with VBA macro streams and a hidden PowerShell launch command in theWordDocumentstream.- The macro chain is static and was not executed:
- Document_open() calls Get4ipjzmjfvp.X8twf_cydt6.
- The loader removes the marker ][(s)]w from document text.
- It keeps the first 50 characters, then every second character after that, recovering a Powershell -windowstyle hidden -ENCOD ... command.
- The decoded PowerShell stage builds a config byte array named
$FN5ggmsH. - XORing the numeric
$FN5ggmsHarrays with0xdfreveals the ransomware config and embedded flag. - Reproducible solver:
solve/solve.py. - Sanitized solver artifacts:
- analysis/solver/ole-inventory.json
- analysis/solver/stage0-command-redacted.txt
- analysis/solver/stage1-powershell-redacted.txt
- analysis/solver/xor-config-redacted.txt
- Raw flag captured by the harness and stored only in
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: Forensics
- Challenge: Emo
- 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.
- Extract HTB archive to a Word OLE/CFB document.
- Parse OLE streams and identify
WordDocumentplus VBA macro streams. - Decompress VBA modules to confirm
Document_open()invokes an obfuscated loader. - Recover the hidden PowerShell command from
WordDocumentby removing][(s)]w, keeping the first 50 characters, then taking every second following character. - Base64-decode the PowerShell as UTF-16LE.
- Extract numeric
$FN5ggmsHbyte arrays from the PowerShell and XOR each byte with0xdf. - Search the decoded config for the HTB-format flag and store it only in
loot/flag.txt.
Reusable Lessons
- In malicious Word documents, inspect both VBA streams and the
WordDocumentstream; macros may use document text as an obfuscated payload carrier. - If
olevbais unavailable, a small OLE/CFB parser plus VBA stream decompression or stream/string inspection is enough for many Easy Forensics macro challenges. - PowerShell stagers often build config strings from numeric arrays; evaluate array-level transforms statically instead of executing malware.
Dead Ends
- No external research was needed after local static analysis revealed the full chain.
- Dynamic execution of the macro or downloaded payload was unnecessary and avoided.
Tool Quirks
- macOS did not provide the usual Office-analysis helpers (
olevba,oleid,mraptor) in this environment, so the solver includes a minimal OLE parser. - macOS
stringsbehavior differs from GNU strings for UTF-16 scanning; OLE stream extraction was more reliable.
Evidence Paths
analysis/artifact-inventory.jsonanalysis/vba_decompressed/007_Dw75ayd2hpcab6.bin.offset_1119.txtanalysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txtanalysis/macro-transform-decode.txtanalysis/solver/stage1-powershell-redacted.txtanalysis/solver/xor-config-redacted.txtsolve/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 | Static macro/OLE analysis of emo.doc should reveal the ransomware loader, embedded payload indicators, or the flag. | Challenge scenario says initial access was a phishing Word document with macros; extracted artifact is files/extracted/emo.doc. | Run file/strings/OLE stream inventory, extract VBA streams without executing macros, then search decoded macro/payload content for HTB-format or staged script 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: Forensics
- Challenge: Emo
- 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.
- Extract HTB archive to a Word OLE/CFB document.
- Parse OLE streams and identify
WordDocumentplus VBA macro streams. - Decompress VBA modules to confirm
Document_open()invokes an obfuscated loader. - Recover the hidden PowerShell command from
WordDocumentby removing][(s)]w, keeping the first 50 characters, then taking every second following character. - Base64-decode the PowerShell as UTF-16LE.
- Extract numeric
$FN5ggmsHbyte arrays from the PowerShell and XOR each byte with0xdf. - Search the decoded config for the HTB-format flag and store it only in
loot/flag.txt.
Reusable Lessons
- In malicious Word documents, inspect both VBA streams and the
WordDocumentstream; macros may use document text as an obfuscated payload carrier. - If
olevbais unavailable, a small OLE/CFB parser plus VBA stream decompression or stream/string inspection is enough for many Easy Forensics macro challenges. - PowerShell stagers often build config strings from numeric arrays; evaluate array-level transforms statically instead of executing malware.
Dead Ends
- No external research was needed after local static analysis revealed the full chain.
- Dynamic execution of the macro or downloaded payload was unnecessary and avoided.
Tool Quirks
- macOS did not provide the usual Office-analysis helpers (
olevba,oleid,mraptor) in this environment, so the solver includes a minimal OLE parser. - macOS
stringsbehavior differs from GNU strings for UTF-16 scanning; OLE stream extraction was more reliable.
Evidence Paths
analysis/artifact-inventory.jsonanalysis/vba_decompressed/007_Dw75ayd2hpcab6.bin.offset_1119.txtanalysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txtanalysis/macro-transform-decode.txtanalysis/solver/stage1-powershell-redacted.txtanalysis/solver/xor-config-redacted.txtsolve/solve.pyloot/flag.txt
Ingestion Decision
- Proposed for LightRAG: yes
- Requires user approval before ingestion: yes
Notes
Notes
Scope
- Challenge: Emo
- Category: Forensics
- Difficulty: Easy
- Mode: file
- Remote instance: none
- Start time: 2026-06-09T14:15:06Z
- 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/a12c736b-5e32-4f03-b88d-a27bcf511444.zip | 99505 | <hash redacted> | Zip archive data, at least v2.0 to extract, compression method=deflate | zip entries: 1 shown in artifact inventory JSON |
files/extracted/emo.doc | 210432 | <hash redacted> | Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 1252, Subject: Handmade Argentina Handcrafted Frozen Towels yellow Frozen virtual Guatemala array Lesotho JBOD, Template: Normal.dotm, Revision Number: 1, Name of Creating Application: Microsoft Office Word, Create Time/Date: Sat Oct 31 00:48:00 2020, Last Saved Time/Date: Tue Nov 3 03:14:00 2020, Number of Pages: 1, Number of Words: 9339, Number of Characters: 53237, Security: 8 |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-09T14:15:06Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-09T14:15:25Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-09T14: <REDACTED>, embedded payload indicators, or the flag. | Medium | Run file/strings/OLE stream inventory, extract VBA streams without executing macros, then search decoded macro/payload content for HTB-format or staged script data. | |||
| 2026-06-09T14:15:42Z | research skip | analysis/research/research-skip.md | Research intentionally skipped with recorded reason | Medium | Gate before exploit |
| 2026-06-09T14: <REDACTED> | |||||
| 2026-06-09T14:26:23Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
files/extracted/emo.docis a Word OLE/CFB document with VBA macro streams and a hidden PowerShell launch command in theWordDocumentstream.- The macro chain is static and was not executed:
- Document_open() calls Get4ipjzmjfvp.X8twf_cydt6.
- The loader removes the marker ][(s)]w from document text.
- It keeps the first 50 characters, then every second character after that, recovering a Powershell -windowstyle hidden -ENCOD ... command.
- The decoded PowerShell stage builds a config byte array named
$FN5ggmsH. - XORing the numeric
$FN5ggmsHarrays with0xdfreveals the ransomware config and embedded flag. - Reproducible solver:
solve/solve.py. - Sanitized solver artifacts:
- analysis/solver/ole-inventory.json
- analysis/solver/stage0-command-redacted.txt
- analysis/solver/stage1-powershell-redacted.txt
- analysis/solver/xor-config-redacted.txt
- Raw flag captured by the harness and stored only in
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 the challenge as a small system with one rule that matters more than the rest. The solve is finding that rule, validating it, and using it carefully enough to reach the final proof.
For Emo, 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.