This challenge presents us with a PNG image file called rainbow_box.png. The challenge involves extracting hidden information from the image using bitplane analysis.
The key insight is that this is a bitplane steganography challenge where information is typically hidden in the least significant bits of the RGB channels. In bitplane steganography:
In this case, checking the bitplanes using any visual tool will clearly show identifiable characters. For example, the LSB for red shows the character M, the first character of the flag.

The easiest approach is to use StegOnline, a powerful web-based steganography analysis tool:
rainbow_box.png file to StegOnlineStegOnline provides an intuitive interface for bitplane extraction and makes it easy to identify patterns that form readable text. Just browse each bitplane grabbing each character 1 by 1 to solve this way.
Alternatively, you can write a custom script to extract the bitplanes. Here's a Python script that extracts all bitplanes except the MSB and displays them in a single row:
#!/usr/bin/env python3"""Extract all bitplanes (except MSBs) from a stego image and display them in black and white."""from PIL import Imageimport osdef extract_bitplanes_simple(image_path, exclude_msb=True): """Extract all bitplanes from an image and save them as individual files.""" img = Image.open(image_path) img_array = img.convert('RGB') pixels = img_array.load() width, height = img_array.size output_dir = "extracted_bitplanes" os.makedirs(output_dir, exist_ok=True) channel_names = ['R', 'G', 'B'] bitplanes_extracted = 0 for channel_idx, channel_name in enumerate(channel_names): for bit_idx in range(8): if exclude_msb and bit_idx == 7: continue bitplane_img = Image.new('L', (width, height)) bitplane_pixels = bitplane_img.load() for y in range(height): for x in range(width): pixel = pixels[x, y] channel_value = pixel[channel_idx] bit_value = (channel_value >> bit_idx) & 1 bitplane_pixels[x, y] = bit_value * 255 filename = f"{output_dir}/bitplane_{channel_name}{bit_idx}.png" bitplane_img.save(filename) bitplanes_extracted += 1 print(f"Saved: {filename}") print(f"\nExtracted {bitplanes_extracted} bitplanes to '{output_dir}/' directory") create_summary_image(output_dir, bitplanes_extracted, width, height)def create_summary_image(output_dir, num_bitplanes, width, height): """Create a summary image showing all bitplanes in a single row.""" summary_width = width * num_bitplanes summary_height = height summary_img = Image.new('L', (summary_width, summary_height), 255) for i in range(num_bitplanes): x = i * width y = 0 channel_names = ['R', 'G', 'B'] bit_idx = i % 7 channel_idx = i // 7 if channel_idx < len(channel_names): channel_name = channel_names[channel_idx] filename = f"{output_dir}/bitplane_{channel_name}{bit_idx}.png" try: bitplane_img = Image.open(filename) summary_img.paste(bitplane_img, (x, y)) except Exception as e: print(f"Warning: Could not load {filename}: {e}") summary_path = f"{output_dir}/all_bitplanes_summary.png" summary_img.save(summary_path) print(f"Created summary image: {summary_path}")if __name__ == "__main__": extract_bitplanes_simple("rainbow_box.png", exclude_msb=True)
