WhitePages: Unicode Whitespace Steganography & Binary Demodulation

“I stop and consider the numbers... I look at the white page and I find nothing.”
picoCTF{...}Forensic Analysis: Unicode Whitespace Steganography
When opened in standard text editors, whitepages.txt renders as a blank document. Hex inspection reveals that the 2,770-byte file consists entirely of two alternating whitespace characters: standard ASCII spaces (0x20) and Unicode EM Spaces (UTF-8 bytes E2 80 83 / \u2003). Because only two discrete characters exist, they form a binary alphabet (0 and 1) that translates directly into ASCII character bytes.
1. Inspecting the 2,770 Bytes
Running Format-Hex reveals the entire 2.7 KB file consists of only two repeating UTF-8 byte sequences:
00000000 E2 80 83 E2 80 83 E2 80 83 E2 80 83 20 E2 80 83 ............ ...
00000010 20 E2 80 83 E2 80 83 20 20 20 E2 80 83 E2 80 83 .... ....Bytes: E2 80 83 → Mapped to Binary 0
Bytes: 20 → Mapped to Binary 1
2. Automated Extraction Script (`solve.py`)
# Read the raw UTF-8 whitespace characters
with open('whitepages.txt', 'rb') as f:
raw = f.read()
# Decode UTF-8 string
text = raw.decode('utf-8')
# Map EM SPACE (\u2003) -> 0 and ASCII SPACE (' ') -> 1
binary_str = text.replace('\u2003', '0').replace(' ', '1')
# Convert 8-bit binary chunks into ASCII bytes
flag_bytes = bytes([
int(binary_str[i:i+8], 2)
for i in range(0, len(binary_str) - len(binary_str) % 8, 8)
])
print("[+] Decoded Flag:")
print(flag_bytes.decode('utf-8', errors='ignore'))python -c "t=open('whitepages.txt','rb').read().decode('utf-8').replace('\u2003','0').replace(' ','1'); print(bytes([int(t[i:i+8],2) for i in range(0,len(t)-len(t)%8,8)]).decode('utf-8',errors='ignore'))"3. Decoded Flag
Extracted Secret Flag:
4. The Complete Investigation Path & Mental Roadmap
Observed that whitepages.txt appeared visually empty in text editors despite having a file size of 2,770 bytes.
Inspected raw bytes and identified exactly two distinct symbols: 0xE2 0x80 0x83 (EM Space) and 0x20 (Standard Space).
Mapped the two whitespace characters to binary 0 and 1, grouped into 8-bit ASCII bytes, and extracted the flag: picoCTF{not_all_spaces_are_created_equal_...}.