← Back to Writeups
CUSTOMMediumSteganography

Literary Anomaly (Литературная аномалия)

XESXOR9/2/20263 min read
#steganography#custom#medium#character-level-steganography#docx-xml-extraction-and-analys#homoglyph-identification-(cyri#text-anomaly-detection-via-com#linux

Literary Anomaly (Литературная аномалия)

Platform: hackerlab | Category: Steganography | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2025-12-22 | Status: Solved Techniques: Character-level steganography, DOCX XML extraction and analysis, Homoglyph identification (Cyrillic vs Latin), Text anomaly detection via comparison with original

Summary

Task: Word document with classic literature text (Pride and Prejudice) found on old library computer. Solution: Compare with original text to find character-level anomalies (homoglyphs, leet speak, extra letters) that spell out the hidden flag.

Literary Anomaly — hackerlab.pro

Description

В старом компьютере городской библиотеки был найден этот текстовый файл. Библиотекарь утверждает, что никогда его не видел, но почему-то очень нервничает при упоминании о нём...

File: literaryAnomaly.zip contains a Word document "Литературная аномалия.docx"

Analysis

1. Extraction and Investigation

bash
unzip literaryAnomaly.zip
# Result: Литературная аномалия.docx

# DOCX is a ZIP archive with XML files
unzip "Литературная аномалия.docx" -d docx_contents/

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

2. Text Identification

The document contains text from Chapter 1 of "Pride and Prejudice" by Jane Austen. This is a classic work, and the original can be easily found for comparison.

3. Finding Anomalies

Comparing the document text with the original, we discover intentional modifications — added or changed characters:

Position in textOriginalIn documentAnomaly
"some one"some onesome oneсAdded Cyrillic с (looks like Latin "c")
"consent"consentc0nsentZero instead of letter "o" → 0
"ignorant"ignorantingnorantAdded extra n
"vexing"vexingvexingGAdded uppercase G
"high respect"respectRespectUppercase R instead of lowercase
"four thousand"four47Number 47 instead of word
"year come"comecomesAdded s
"my dear"dearbearb instead of "d"
"discontented"discontenteddiscortentedAdded r
"business of"of0fZero instead of letter "o" → 0
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

4. Assembling the Flag

Collecting anomalous characters in order of appearance in the text:

c + 0 + n + G + R + 4 + 7 + s + b + r + 0
= c0nGR47sbr0

This reads as "conGRATs bro" (congratulations bro)!

Solution

Script for Automatic Anomaly Detection

python
#!/usr/bin/env python3
"""
Finding text anomalies in DOCX document
by comparing with original text
"""

import zipfile
import xml.etree.ElementTree as ET
from difflib import SequenceMatcher

def extract_docx_text(docx_path):
    """Extracts text from DOCX file"""
    with zipfile.ZipFile(docx_path, 'r') as z:
        xml_content = z.read('word/document.xml')
    
    root = ET.fromstring(xml_content)
    ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
    
    text_parts = []
    for t in root.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t'):
        if t.text:
            text_parts.append(t.text)
    
    return ''.join(text_parts)
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

def find_anomalies(modified_text, original_text):
    """Finds differences between texts"""
    matcher = SequenceMatcher(None, original_text, modified_text)
    anomalies = []
    
    for tag, i1, i2, j1, j2 in matcher.get_opcodes():
        if tag == 'replace':
            anomalies.append(('replace', original_text[i1:i2], modified_text[j1:j2]))
        elif tag == 'insert':
            anomalies.append(('insert', '', modified_text[j1:j2]))
        elif tag == 'delete':
            anomalies.append(('delete', original_text[i1:i2], ''))
    
    return anomalies
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Usage example
docx_text = extract_docx_text("Литературная аномалия.docx")

# Original Pride and Prejudice Chapter 1 text (fragment)
original = """It is a truth universally acknowledged..."""  # full text

anomalies = find_anomalies(docx_text, original)
hidden_message = ''.join([a[2] for a in anomalies if a[0] == 'insert'])
print(f"Hidden message: {hidden_message}")

Manual Method

  1. Download the original Pride and Prejudice Chapter 1 from Project Gutenberg
  2. Compare character by character with the document text
  3. Write down all differences in order of appearance ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Text Steganography Techniques

  1. Homoglyphs — replacing Latin letters with similar Cyrillic ones (c→с, a→а, o→о)
  2. Leet speak — replacing letters with numbers (o→0, a→4, e→3)
  3. Adding characters — extra letters in words
  4. Case changes — uppercase letters where lowercase should be
  5. Word substitution — numbers instead of words (four→47)

Analysis Tools

  • diff — text comparison
  • Python difflib — programmatic comparison
  • Hex editor — viewing Unicode character codes
  • Online diff tools — visual text comparison ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍