← Back to Writeups
CUSTOMEasySteganography

Office Document Stego (e73e49dc)

XESXOR9/2/20263 min read
#steganography#custom#easy#docx-file-structure-analysis-(#xml-metadata-inspection#hidden-data-in-document-proper#linux

Office Document Stego (e73e49dc)

Platform: hackerlab.pro | Category: Steganography | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-23 | Status: Solved Techniques: DOCX file structure analysis (ZIP-based format), XML metadata inspection, Hidden data in document properties (sectPr/pgMar)

Summary

Provided file task.zip containing document.docx.

Office Document Stego — hackerlab.pro

Description

"Действительно ли Вы всё знаете о документах для офисных приложений?" (Do you really know everything about office application documents?)

Provided file task.zip containing document.docx.

Analysis

1. Understanding the DOCX Format

DOCX is an Office Open XML (OOXML) format, which is essentially a ZIP archive with XML files inside. This is the key knowledge for solving this challenge.

The flag name REDACTED (word file is archive) directly points to this feature. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

2. DOCX File Structure

Extract the DOCX as a ZIP:

bash
unzip document.docx -d docx_extracted/

Typical structure:

docx_extracted/
├── [Content_Types].xml
├── _rels/
│   └── .rels
├── docProps/
│   ├── app.xml
│   └── core.xml
└── word/
    ├── document.xml      # Main document content
    ├── styles.xml        # Styles
    ├── settings.xml      # Settings
    ├── fontTable.xml     # Font table
    └── _rels/
        └── document.xml.rels

3. Searching for Hidden Data

Search for the flag in XML files: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

bash
grep -r "CODEBY" docx_extracted/

The flag was found in word/document.xml in the sectPr (section properties) section.

4. Analyzing the Hiding Location

The flag is hidden in the w:bottom attribute of the w:pgMar (page margins) element:

xml
<w:sectPr>
  <w:pgMar w:left="1134" 
           w:right="1134" 
           w:header="0" 
           w:top="1134" 
           w:footer="0" 
           w:bottom="CODEBY{REDACTED}"
           w:gutter="0"/>
</w:sectPr>

Normally w:bottom contains a numeric margin value in twips (1/20 of a point). Here, instead of a number — the flag. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

Quick Method

bash
# Extract and search
unzip document.docx -d extracted/
grep -r "CODEBY" extracted/

Detailed Analysis

bash
# Extract and format XML
unzip -p document.docx word/document.xml | xmllint --format - | grep -A5 -B5 "pgMar"

Python Script for Automation

python
#!/usr/bin/env python3
"""Extract hidden data from DOCX"""
import zipfile
import re
from xml.etree import ElementTree as ET

def extract_hidden_from_docx(docx_path):
    """Search for non-standard values in DOCX XML attributes"""
    
    with zipfile.ZipFile(docx_path, 'r') as zf:
        for filename in zf.namelist():
            if filename.endswith('.xml'):
                content = zf.read(filename).decode('utf-8')
                
                # Direct flag search
                flags = re.findall(r'CODEBY\{[^}]+\}', content)
                if flags:
                    print(f"[+] Found in {filename}:")
                    for flag in flags:
                        print(f"    {flag}")
                
                # Search for non-numeric values in numeric attributes
                # pgMar attributes should be numbers
                margins = re.findall(r'w:(left|right|top|bottom|header|footer|gutter)="([^"]+)"', content)
                for attr, value in margins:
                    if not value.isdigit():
                        print(f"[!] Suspicious {attr} value: {value}")
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

if __name__ == "__main__":
    import sys
    docx_file = sys.argv[1] if len(sys.argv) > 1 else "document.docx"
    extract_hidden_from_docx(docx_file)

Data Hiding Locations in DOCX

Commonly Used:

  1. document.xml — main content, comments, hidden text
  2. core.xml — metadata (author, title, comments)
  3. app.xml — application properties
  4. settings.xml — document settings
  5. styles.xml — style definitions

Attributes for Hiding:

  • w:pgMar — page margins (left, right, top, bottom)
  • w:pgSz — page size
  • w:docGrid — document grid
  • Custom XML properties
  • XML comments (<!-- -->) ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Related Formats

FormatExtensionArchive Type
Word.docxZIP (OOXML)
Excel.xlsxZIP (OOXML)
PowerPoint.pptxZIP (OOXML)
LibreOffice Writer.odtZIP (ODF)
LibreOffice Calc.odsZIP (ODF)

Analysis Tools

  1. unzip — basic extraction
  2. 7z — alternative archiver
  3. xmllint — XML formatting and validation
  4. oletools — OLE object analysis in documents
  5. python-docx — programmatic access to DOCX
  6. odfpy — working with ODF formats ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Alternative Approaches

  1. Hex editor — search for flag string in binary form
  2. strings — extract all strings from file
  3. binwalk — analyze embedded files
  4. foremost — file carving from archive

Related Techniques

  • Font steganography in documents
  • Hidden text (white on white)
  • Embedded objects (OLE)
  • Macro-based steganography
  • Custom XML parts
  • Document properties manipulation ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍