Challenge / Forensics

Emo

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

EasyPublished 2024-06-18Sanitized local writeup

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.

Emo sanitized attack graph

Walkthrough flow

01

Extract HTB archive to a Word OLE/CFB document.

02

Parse OLE streams and identify WordDocument plus VBA...

03

Decompress VBA modules to confirm Document_open()...

04

Recover the hidden PowerShell command from...

05

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.

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.

  • 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() calls Get4ipjzmjfvp.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.txt
  • analysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txt
  • analysis/macro-transform-decode.txt
  • analysis/solver/stage1-powershell-redacted.txt
  • analysis/solver/xor-config-redacted.txt

Solve

Run the static solver from the challenge workspace:

bash
python3 solve/solve.py

The 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

FileSizeSHA256TypeNotes
files/a12c736b-5e32-4f03-b88d-a27bcf511444.zip99505<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 1 shown in artifact inventory JSON
files/extracted/emo.doc210432<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

TimeActionOutput/FileFindingConfidenceNext
2026-06-09T14:15:06Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-09T14:15:25Zartifact inventoryanalysis/artifact-inventory.json2 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-09T14:15:42Zhypothesis recordedhypothesis-board.mdStatic macro/OLE analysis of emo.doc should reveal the ransomware loader, embedded payload indicators, or the flag.MediumRun 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:42Zresearch skipanalysis/research/research-skip.mdResearch intentionally skipped with recorded reasonMediumGate before exploit
2026-06-09T14:25:18Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-09T14:26:23Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • files/extracted/emo.doc is a Word OLE/CFB document with VBA macro streams and a hidden PowerShell launch command in the WordDocument stream.
  • 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 $FN5ggmsH arrays with 0xdf reveals 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:

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: 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.

  1. Extract HTB archive to a Word OLE/CFB document.
  2. Parse OLE streams and identify WordDocument plus VBA macro streams.
  3. Decompress VBA modules to confirm Document_open() invokes an obfuscated loader.
  4. Recover the hidden PowerShell command from WordDocument by removing ][(s)]w, keeping the first 50 characters, then taking every second following character.
  5. Base64-decode the PowerShell as UTF-16LE.
  6. Extract numeric $FN5ggmsH byte arrays from the PowerShell and XOR each byte with 0xdf.
  7. 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 WordDocument stream; macros may use document text as an obfuscated payload carrier.
  • If olevba is 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 strings behavior differs from GNU strings for UTF-16 scanning; OLE stream extraction was more reliable.

Evidence Paths

  • analysis/artifact-inventory.json
  • analysis/vba_decompressed/007_Dw75ayd2hpcab6.bin.offset_1119.txt
  • analysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txt
  • analysis/macro-transform-decode.txt
  • analysis/solver/stage1-powershell-redacted.txt
  • analysis/solver/xor-config-redacted.txt
  • solve/solve.py
  • loot/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.

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

Closed Branches

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

  1. Extract HTB archive to a Word OLE/CFB document.
  2. Parse OLE streams and identify WordDocument plus VBA macro streams.
  3. Decompress VBA modules to confirm Document_open() invokes an obfuscated loader.
  4. Recover the hidden PowerShell command from WordDocument by removing ][(s)]w, keeping the first 50 characters, then taking every second following character.
  5. Base64-decode the PowerShell as UTF-16LE.
  6. Extract numeric $FN5ggmsH byte arrays from the PowerShell and XOR each byte with 0xdf.
  7. 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 WordDocument stream; macros may use document text as an obfuscated payload carrier.
  • If olevba is 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 strings behavior differs from GNU strings for UTF-16 scanning; OLE stream extraction was more reliable.

Evidence Paths

  • analysis/artifact-inventory.json
  • analysis/vba_decompressed/007_Dw75ayd2hpcab6.bin.offset_1119.txt
  • analysis/vba_decompressed/008_Get4ipjzmjfvp.bin.offset_24229.txt
  • analysis/macro-transform-decode.txt
  • analysis/solver/stage1-powershell-redacted.txt
  • analysis/solver/xor-config-redacted.txt
  • solve/solve.py
  • loot/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

FileSizeSHA256TypeNotes
files/a12c736b-5e32-4f03-b88d-a27bcf511444.zip99505<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 1 shown in artifact inventory JSON
files/extracted/emo.doc210432<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

TimeActionOutput/FileFindingConfidenceNext
2026-06-09T14:15:06Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-09T14:15:25Zartifact inventoryanalysis/artifact-inventory.json2 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-09T14: <REDACTED>, embedded payload indicators, or the flag.MediumRun 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:42Zresearch skipanalysis/research/research-skip.mdResearch intentionally skipped with recorded reasonMediumGate before exploit
2026-06-09T14: <REDACTED>
2026-06-09T14:26:23Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • files/extracted/emo.doc is a Word OLE/CFB document with VBA macro streams and a hidden PowerShell launch command in the WordDocument stream.
  • 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 $FN5ggmsH arrays with 0xdf reveals 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:

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.

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.