← Back to Writeups
CUSTOMEasySteganography

Дверь (Door)

XESXOR9/2/20262 min read
#steganography#custom#easy#green_channel_lsb#msb_first_bit_assembly#single_channel_lsb_extraction

Дверь (Door)

Platform: bug-makers | Category: Steganography | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-05-29 | Status: Solved Techniques: green_channel_lsb, msb_first_bit_assembly, single_channel_lsb_extraction

Summary

Task: a PNG door image hides a message; combined-RGB LSB extraction produces garbage. Solution: single-channel Green-only LSB extraction (MSB-first, row-major) with PIL/numpy recovers the flag and a chained password, with the narrative 'three-walled bastion' hinting at the RGB channel split.

Дверь (Door) — bug-makers

Description

Бродя по улочкам Глубины, вы наткнулись на странную дверь. Шестое чувство подсказывает, что ключ в двери, но в замочной скважине его не видно. Попробуйте найти ключ, и откройте доступ к следующему заданию.

English translation: "Wandering the streets of the Depths, you came across a strange door. A sixth sense tells you the key is in the door, but it's not visible in the keyhole. Try to find the key and open access to the next task."

Artifact: door-password.png — 617x950, 8-bit/color RGB, non-interlaced PNG (~1.1 MB). Goal: recover the hidden flag (and a password for the next chained challenge). ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

Initial recon eliminated the common stego vectors:

  • file door-password.png → PNG 617x950 8-bit RGB non-interlaced.
  • exiftool door-password.png → nothing unusual in metadata.
  • binwalk door-password.png → no appended or embedded files.
  • strings door-password.png | grep -iE "flag|ctf|key|pass" → suspicious short fragments XKeyb and keYp.

The strings fragments are the key tell: short, broken word-fragments like XKeyb/keYp appear when an LSB-encoded ASCII message happens to align to byte boundaries in the raw pixel data. This strongly indicates text hidden in the least significant bits. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

A naive combined-RGB LSB extraction produced garbage. The semantic clue resolves why: the description says the key is "in the door but not visible in the keyhole," and the recovered message itself refers to a "three-walled bastion". The "three walls" = the three RGB channels. The data lives in only ONE channel — the Green channel — which is why combined-RGB LSB failed while single-channel extraction succeeded.

Solution

zsteg / steghide / stegseek were unavailable, so the extraction was done manually with Python + PIL + numpy. Winning parameters: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  • Channel: Green only (bit 0 / LSB)
  • Pixel order: row-major (xy)
  • Bit assembly: MSB-first, 8 bits per byte
python
#!/usr/bin/env python3
from PIL import Image
import numpy as np

img = Image.open('door-password.png').convert('RGB')
a = np.array(img)
g = a[:, :, 1].flatten() & 1          # Green channel LSB
bits = ''.join(map(str, g))

out = bytearray()
for i in range(0, len(bits) - 7, 8):
    out.append(int(bits[i:i+8], 2))   # MSB-first

print(bytes(out[:300]))

Recovered plaintext message: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

You think you found a entrance, huh? But i just got you inside of my
three-walled bastion! Try to escape, if you can, hehehe...
First flag is: BugCTF{REDACTED}
Password for the next part: LEET1BOOBS00

(followed by trailing non-text bytes — the rest of the channel is normal image noise.)

Bonus loot for the chained challenge: password LEET1BOOBS00. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍