← Back to Writeups
CUSTOMMediumSteganography

Your Eyes Lie To You

XESXOR9/2/20262 min read
#steganography#custom#medium#unicode-homoglyph-steganograph#html-entity-decoding-and-analy#character-code-comparison

Your Eyes Lie To You

Platform: hackerlab.pro | Category: Steganography | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-22 | Status: Solved Techniques: Unicode homoglyph steganography, HTML entity decoding and analysis, Character code comparison

Summary

File: task.zip contains task.html

Your Eyes Lie To You — hackerlab.pro

Description

"Задание точно не сломано?" (Is the task really not broken?)

File: task.zip contains task.html

Analysis

Step 1: Examining the HTML file

The HTML file contains text fully encoded in HTML entities format &#NNN;:

html
your eyes ...

Step 2: Decoding

When decoded, we get regular text in English and Russian:

  • "your eyes deceive you"
  • Hint: "if you were a robot or computer, you would immediately understand" ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Visually the text looks completely normal!

Step 3: Analyzing character codes

Key observation: some characters have codes outside the ASCII range!

Regular letter 'y' = code 121
Special 'y' = code 120274 (U+1D5B2, Mathematical Sans-Serif Small Y)

Step 4: Unicode Mathematical Sans-Serif Small

The Unicode block Mathematical Sans-Serif Small (U+1D5BA - U+1D5D3):

  • Codes: 120250 - 120275
  • Look identical to regular lowercase letters a-z
  • But have completely different codes!

This is called homoglyph steganography — hiding data by replacing regular characters with visually identical Unicode characters. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Script to extract the hidden message

python
#!/usr/bin/env python3
import re

# Read the HTML file
with open('task.html', 'r') as f:
    content = f.read()

# Extract all HTML entities
entities = re.findall(r'&#(\d+);', content)

# Mathematical Sans-Serif Small: U+1D5BA (120250) = 'a' ... U+1D5D3 (120275) = 'z'
# Mapping: code 120250 -> 'a', 120251 -> 'b', ..., 120275 -> 'z'

hidden_message = []
for code in entities:
    code = int(code)
    # Check if the code is in the Mathematical Sans-Serif Small range
    if 120250 <= code <= 120275:
        # Convert to regular letter
        letter = chr(ord('a') + (code - 120250))
        hidden_message.append(letter)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

print("Hidden message:", ''.join(hidden_message))

Result

Hidden message: REDACTED

Unicode Homoglyphs Reference

BlockRangeLooks like
Mathematical Sans-Serif SmallU+1D5BA-U+1D5D3 (120250-120275)a-z
Mathematical Sans-Serif CapitalU+1D5A0-U+1D5B9 (120224-120249)A-Z
Mathematical Bold SmallU+1D41A-U+1D433 (119834-119859)a-z
Fullwidth Latin SmallU+FF41-U+FF5A (65345-65370)a-z

Related Techniques

  • Zero-width character steganography (U+200B, U+200C, U+200D, U+FEFF)
  • Confusables/Homoglyphs for phishing
  • Unicode normalization attacks ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍