Три в одном (Three in One)
Три в одном (Three in One)
Platform: duckerz | Category: Steganography | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-02-09 | Status: Solved Techniques: color_channel_extraction, rgb_ascii_encoding
Summary
Task: PNG image with text where each letter has a unique color. Solution: Interpret RGB values as ASCII characters (3 bytes per color = 3 chars per letter).
Три в одном (Three in One) — duckerz CTF
Description
"Это же про кофе так говорят? Я больше чай люблю, особенно с цветами"
File: deliciousdrink.png (PNG image data, 1420 x 360, 8-bit/color RGBA)
The image contains text "coffee maybe?" with a coffee cup and beans on the right.
Analysis
Standard recon — nothing
- file / exiftool — regular PNG, no anomalies in metadata
- strings — no flag
- binwalk — no embedded files, no data after IEND
- zsteg / stegsolve — standard LSB techniques yield nothing
Breaking down the hints
The task contains three key hints:
-
"Три в одном" (Three in one) — task name. In RGB context: 3 bytes (ASCII characters) encoded in 1 color (R, G, B).
-
"особенно с цветами" (especially with flowers/colors) — the word "цветами" in Russian has a double meaning:
- "цветы" (flowers) — a red herring
- "цвета" (colors) — pointing to color channels
-
"Это же про кофе так говорят?" (That's what they say about coffee, right?) — "three in one" = 3-in-1 coffee (coffee + cream + sugar). But the data is hidden in text colors, not in coffee.
Discovery
Upon close inspection, each letter of the text "coffee maybe?" is rendered in its own unique color. The colors look visually similar (dark shades), but hex values differ:
| Letter | Color (hex) | ASCII |
|---|---|---|
| c | #445543 | DUC |
| o | #4b4552 | KER |
| f | #5a7b6e | Z{n |
| f | #6f215f | o!_ |
| e | #695f77 | i_w |
| e | #616e74 | ant |
| m | #5f6d79 | _my |
| a | #5f6661 | _fa |
| y | #766f75 | vou |
| b | #726974 | rit |
| e | #655f74 | e_t |
| ? | #65617d | ea} |
| |
The space between "coffee" and "maybe?" is skipped (contains no data).
Vulnerability
RGB Color Channel Steganography — encoding ASCII in text colors.
Each RGB color is 3 bytes. If we interpret (R, G, B) as three ASCII characters, we get a hidden message. 12 letters × 3 characters = 36 characters of the flag.
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Solution for "Three in One" — duckerz CTF RGB steganography: each letter of text is colored with a color where R, G, B = 3 ASCII characters of the flag. """ from PIL import Image import numpy as np from collections import defaultdict, Counter img = Image.open('deliciousdrink.png') data = np.array(img) # Step 1: Find all dark (text) pixels in the lower part text_pixels = [] for y in range(100, 360): for x in range(data.shape[1]): r, g, b, a = data[y, x] if r < 170 and g < 170 and b < 170: text_pixels.append((x, y, r, g, b)) # Step 2: Group pixels by X-coordinates (each letter = group) x_counts = defaultdict(int) for x, y, r, g, b in text_pixels: x_counts[x] += 1 xs = sorted(x_counts.keys()) groups = [] current_group = [xs[0]] for i in range(1, len(xs)): if xs[i] - xs[i-1] > 5: # gap > 5px = new letter groups.append((current_group[0], current_group[-1])) current_group = [xs[i]] else: current_group.append(xs[i]) if current_group: groups.append((current_group[0], current_group[-1])) # Step 3: For each group find the dominant color hex_string = "" for start, end in groups: colors = Counter() for x, y, r, g, b in text_pixels: if start <= x <= end: colors[(r, g, b)] += 1 top_color = colors.most_common(1)[0][0] r, g, b = top_color hex_string += f"{r:02x}{g:02x}{b:02x}" # Step 4: Decode hex as ASCII flag = bytes.fromhex(hex_string).decode('ascii') print(f"[+] Flag: {flag}")
Output:
[+] Flag: DUCKERZ{REDACTED}
Related Techniques
- LSB steganography — data in least significant bits, here data is in full color bytes
- Palette-based stego — similar principle, but through PNG palette
- Font color stego in HTML/documents — same technique, but in web context (invisible text via font color = background color)