Лисичка (Fox)
Лисичка (Fox)
Platform: hackerlab.pro | Category: Steganography | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2025-12-23 | Status: Solved Techniques: Bit plane analysis beyond LSB (bit 0), Color channel separation and analysis, Higher bit plane extraction (bit 2)
Summary
File: task.png - PNG image of a fox (1280x873 pixels, RGBA)
Лисичка (Fox) - hackerlab.pro
Description
Ну только посмотри на эту лисичку. Она точно что-то стащила, спрятала и сидит радуется. (Look at this fox. She definitely stole something, hid it and is sitting happy)
File: task.png - PNG image of a fox (1280x873 pixels, RGBA)
Analysis
1. Standard Tools
First, we try standard LSB steganography tools:
bash read-only • copy allowedzsteg task.png # Nothing found steghide extract -sf task.png # Does not support PNG stegano-lsb reveal -i task.png # Nothing found
All standard tools find no hidden data.
2. Understanding the Problem
Standard LSB tools only check bit 0 (least significant bit) of each channel. However, data can be hidden in higher bit planes (bit 1, bit 2, etc.).
3. Bit Plane Analysis
An image consists of pixels, each pixel has 8 bits per channel (0-255). These 8 bits can be represented as 8 separate "planes":
Bit 7 (MSB): 128 - most significant, determines the main color
Bit 6: 64
Bit 5: 32
Bit 4: 16
Bit 3: 8
Bit 2: 4 <- FLAG IS HIDDEN HERE
Bit 1: 2
Bit 0 (LSB): 1 <- standard tools only check this
4. Flag Discovery
Systematic analysis of all bit planes across all channels (R, G, B, A) revealed:
Bit 2 of the green channel (Green bit 2) contains the flag text, visible as white letters on a black background.
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Fox - Bit Plane Steganography solver Flag hidden in bit 2 of Green channel (not standard LSB bit 0) """ from PIL import Image import numpy as np def extract_bit_plane(image_path, channel=1, bit=2): """ Extract specific bit plane from image channel. Args: image_path: Path to image file channel: 0=Red, 1=Green, 2=Blue, 3=Alpha bit: Bit position (0=LSB, 7=MSB) Returns: PIL Image with extracted bit plane """ img = Image.open(image_path) arr = np.array(img) print(f"Image size: {img.size}") print(f"Array shape: {arr.shape}") print(f"Extracting bit {bit} from channel {channel}") # Extract specific bit from channel # (value >> bit) & 1 gives us the bit value (0 or 1) # Multiply by 255 to make it visible (black/white) bit_plane = ((arr[:, :, channel] >> bit) & 1) * 255 # Convert to image result = Image.fromarray(bit_plane.astype(np.uint8)) return result def analyze_all_bit_planes(image_path, output_dir="."): """ Extract all bit planes from all channels for analysis. """ img = Image.open(image_path) arr = np.array(img) channels = ['Red', 'Green', 'Blue'] if arr.shape[2] == 4: channels.append('Alpha') for ch_idx, ch_name in enumerate(channels): for bit in range(8): bit_plane = ((arr[:, :, ch_idx] >> bit) & 1) * 255 result = Image.fromarray(bit_plane.astype(np.uint8)) filename = f"{output_dir}/{ch_name}_bit{bit}.png" result.save(filename) print(f"Saved: {filename}") def solve_fox(image_path): """ Extract flag from Green channel bit 2. """ # Extract bit 2 from green channel result = extract_bit_plane(image_path, channel=1, bit=2) # Save result output_path = "flag.png" result.save(output_path) print(f"\nSaved extracted bit plane to: {output_path}") print("Open the image to see the flag as white text on black background") return result if __name__ == "__main__": # Quick solution - extract known location solve_fox("task.png") # For analysis - uncomment to extract all bit planes # analyze_all_bit_planes("task.png", "bit_planes")
Script Output
Image size: (1280, 873)
Array shape: (873, 1280, 4)
Extracting bit 2 from channel 1
Saved extracted bit plane to: flag.png
Open the image to see the flag as white text on black background
Result
Opening flag.png, we see white text on a black background:
CODEBY{REDACTED}
Why Standard Tools Don't Work
| Tool | What it checks | Why it didn't find |
|---|---|---|
| zsteg | LSB (bit 0) of all channels | Data is in bit 2 |
| steghide | Does not support PNG | File format |
| stegano-lsb | Only LSB (bit 0) | Data is in bit 2 |
| binwalk | Embedded files | No embedded files |
| |
Alternative Approaches
1. Visual Analysis in StegSolve
StegSolve (Java) allows switching between bit planes visually:
- Open the image
- Use arrows to switch between bit planes
- Green plane 2 will show the flag
2. Full Analysis of All Planes
python read-only • copy allowed# Save all 24 bit planes (8 bits × 3 channels) for channel in range(3): for bit in range(8): plane = ((arr[:,:,channel] >> bit) & 1) * 255 Image.fromarray(plane.astype(np.uint8)).save(f"ch{channel}_bit{bit}.png")
3. Command Line with ImageMagick
bash read-only • copy allowed# Extract green channel convert task.png -channel G -separate green.png # Apply threshold to extract bit 2 # (requires additional processing)
Theory: Bit Plane Steganography
Pixel Structure
Pixel value: 157 = 10011101 in binary
Bit 7: 1 (128) ─┐
Bit 6: 0 (0) │ Visually noticeable bits
Bit 5: 0 (0) │ (changes strongly affect color)
Bit 4: 1 (16) ─┘
Bit 3: 1 (8) ─┐
Bit 2: 1 (4) │ Less noticeable bits
Bit 1: 0 (0) │ (changes weakly affect color)
Bit 0: 1 (1) ─┘ <- LSB, classic steganography
Why Bit 2?
- Bit 0-1: Too obvious location, all tools check it
- Bit 2-3: Compromise between stealth and invisibility
- Bit 4-7: Changes are too visually noticeable
Conclusions
This challenge demonstrates the importance of checking all bit planes, not just LSB. Standard tools are optimized for the most common case (LSB), but attackers can use any bit plane to hide data.
Rule: If LSB tools find nothing, but the challenge is clearly about steganography - check all 8 bit planes of each channel manually.