Pixels Secret
Pixels Secret
Platform: hackerlab | Category: Steganography | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-22 | Status: Solved Techniques: Pixel color filtering for anomaly detection, X-coordinate to ASCII character mapping, Y-coordinate based character ordering
Summary
Task: Image with dark background containing hidden dust pixels. Solution: X-coordinates of anomalous pixels encode ASCII characters, Y-coordinates determine character order.
Pixels Secret - hackerlab.pro
Description
На цифровых фотографиях тоже иногда оседает "пыль" (On digital photos, "dust" sometimes settles too)
File: pixels_secret.zip contains pixels_secret.jpg
Analysis
1. Image Investigation
Unpack the archive and analyze the image:
- Size: 4300x1800 pixels
- Format: JPEG
- Metadata indicates creation in GIMP
The image has an almost completely black background with RGB ≈ (1, 2, 4).
2. Hint Interpretation
The hint about "dust" on digital photos suggests looking for individual pixels that differ from the main background - like dust particles on a dark surface.
3. Finding Anomalous Pixels
Analysis showed that in the first 11 rows of the image (Y from 0 to 10) there are "dust particles" - pixels with a characteristic pattern:
- R ≤ 10
- G ≤ 10
- 20 ≤ B ≤ 30
These pixels stand out against the dark background due to a higher blue channel value.
4. Decoding
Key observation: The X-coordinate of each "dust" pixel corresponds to an ASCII character code.
When sorting pixels by Y-coordinate (then by X), the X-values decode to flag characters:
| Y | X-coordinates | Characters |
|---|---|---|
| 0 | 67, 79 | C, O |
| 1 | 68, 69 | D, E |
| 2 | 66, 89, 123 | B, Y, { |
| 3 | 99, 104 | c, h |
| 4 | 51, 99, 107 | 3, c, k |
| 5 | 95, 116 | _, t |
| 6 | 104 | h |
| 7 | 101 | e |
| 8 | 95, 112 | _, p |
| 9 | 49, 120 | 1, x |
| 10 | 51, 108, 115, 125 | 3, l, s, } |
| |
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Pixels Secret - Coordinate-based steganography solver Flag is encoded in X-coordinates of "dust" pixels """ from PIL import Image import numpy as np def solve_pixels_secret(image_path): img = Image.open(image_path) arr = np.array(img) print(f"Image size: {img.size}") print(f"Array shape: {arr.shape}") # Find dust pixels with specific RGB pattern in first 20 rows dust_pixels = [] for y in range(20): # Dust is in first 11 rows, check 20 for safety for x in range(arr.shape[1]): r, g, b = int(arr[y, x, 0]), int(arr[y, x, 1]), int(arr[y, x, 2]) # Dust pixels have low R, low G, but elevated B (20-30) if r <= 10 and g <= 10 and b >= 20 and b <= 30: dust_pixels.append((x, y, (r, g, b))) print(f"\nFound {len(dust_pixels)} dust pixels") # Sort by Y coordinate (row), then by X coordinate dust_pixels.sort(key=lambda p: (p[1], p[0])) # Print pixel details print("\nDust pixels (sorted by Y, then X):") for x, y, rgb in dust_pixels: char = chr(x) if 32 <= x < 127 else '?' print(f" Y={y:2d}, X={x:3d} -> '{char}' (RGB: {rgb})") # Decode: X coordinate = ASCII code flag = ''.join([chr(x) for x, y, rgb in dust_pixels if 32 <= x < 127]) print(f"\n{'='*50}") print(f"FLAG: {flag}") print(f"{'='*50}") return flag if __name__ == "__main__": solve_pixels_secret("pixels_secret.jpg")
Script Output
Image size: (4300, 1800)
Array shape: (1800, 4300, 3)
Found 22 dust pixels
Dust pixels (sorted by Y, then X):
Y= 0, X= 67 -> 'C' (RGB: (1, 2, 25))
Y= 0, X= 79 -> 'O' (RGB: (1, 2, 25))
Y= 1, X= 68 -> 'D' (RGB: (1, 2, 25))
Y= 1, X= 69 -> 'E' (RGB: (1, 2, 25))
Y= 2, X= 66 -> 'B' (RGB: (1, 2, 25))
Y= 2, X= 89 -> 'Y' (RGB: (1, 2, 25))
Y= 2, X=123 -> '{' (RGB: (1, 2, 25))
Y= 3, X= 99 -> 'c' (RGB: (1, 2, 25))
Y= 3, X=104 -> 'h' (RGB: (1, 2, 25))
Y= 4, X= 51 -> '3' (RGB: (1, 2, 25))
Y= 4, X= 99 -> 'c' (RGB: (1, 2, 25))
Y= 4, X=107 -> 'k' (RGB: (1, 2, 25))
Y= 5, X= 95 -> '_' (RGB: (1, 2, 25))
Y= 5, X=116 -> 't' (RGB: (1, 2, 25))
Y= 6, X=104 -> 'h' (RGB: (1, 2, 25))
Y= 7, X=101 -> 'e' (RGB: (1, 2, 25))
Y= 8, X= 95 -> '_' (RGB: (1, 2, 25))
Y= 8, X=112 -> 'p' (RGB: (1, 2, 25))
Y= 9, X= 49 -> '1' (RGB: (1, 2, 25))
Y= 9, X=120 -> 'x' (RGB: (1, 2, 25))
Y=10, X= 51 -> '3' (RGB: (1, 2, 25))
Y=10, X=108 -> 'l' (RGB: (1, 2, 25))
Y=10, X=115 -> 's' (RGB: (1, 2, 25))
Y=10, X=125 -> '}' (RGB: (1, 2, 25))
==================================================
FLAG: CODEBY{REDACTED}
==================================================
Alternative Approaches
- Visual analysis: Increasing image contrast can make "dust particles" visible
- Histogram: Analyzing color distribution will show anomalous values
- Channel filtering: Separate analysis of R, G, B channels
Lessons
The challenge demonstrates an interesting coordinate-based steganography technique where information is encoded not in pixel color, but in pixel position. The X-coordinate determines the ASCII character code, and the Y-coordinate determines the order of characters in the message.