Description
A bright red PNG hides an obvious poem plus a suspicious Base64 blob in the LSB plane. Run an LSB scanner, grab the repeating string, and decode it to recover the flag.
Setup
Confirm the file is a real PNG with file and pngcheck. pngcheck -v should report OK for every chunk; if it ever says extra bytes after IEND, the payload is appended data and you'd switch to binwalk instead of zsteg.
Install zsteg (Ruby + gem install zsteg) so you can scan the RGBA bit planes quickly. zsteg is the right tool here because the carrier is a PNG with LSB Stepic encoding; steghide handles JPEG, binwalk handles appended files, and stegsolve is a slower GUI bit-plane viewer.
Run zsteg on the PNG and look for an entry like b1,rgba,lsb,xy ... text: "<base64>". The longest decodable text line is the payload.
file red.pngpngcheck -v red.pngbinwalk red.png # quick sanity check for appended filessudo apt install ruby ruby-devsudo gem install zstegzsteg red.pngSolution
Walk me through it- Step 1Extract the Base64 payloadzsteg prints the flag repeated several times in the LSB plane (the encoder pads the carrier, which is what produces the duplication). Just take the first complete
picoCTF{...}substring from theb1,rgba,lsb,xyline; the duplicates can be ignored.Learn more
LSB (Least Significant Bit) steganography hides data in the lowest-order bit of each color channel in an image. A pixel's RGB values each contribute one bit of hidden data, so a 1-megapixel image can hide approximately 375 kilobytes of payload while remaining visually indistinguishable from the original - the color difference caused by flipping a single bit is below human perception threshold.
zsteg is a Ruby tool that systematically tests all combinations of bit planes (bits 1 through 8 of each channel), channel combinations (R, G, B, A and their combinations), and byte orderings (LSB-first vs. MSB-first, row-by-row vs. column-by-column). The
b1,rgba,lsb,xynotation reads as: bit plane 1 (the least-significant bit) of the RGBA channels, in least-significant-bit order, scanning x then y (left-to-right then top-to-bottom). That is exactly what the Stepic library used to encode this PNG, so zsteg's default scan finds the payload on the first try without any flags.Other steganography detection tools serve different carriers: steghide handles password-protected JPEG/BMP embedding, stegsolve is a GUI bit-plane viewer that is slower than zsteg's automated scan, and binwalk detects appended files or embedded archives. The choice of tool depends on the file format and embedding technique suspected.
- Step 2Decode to textUse CyberChef's From Base64 recipe or Linux's
base64 -dtool to decode the string into ASCII. The plaintext is already formatted as a picoCTF flag.bashbase64 -d <<< 'cGljb0NURntyM2RfMXNfdGgzX3VsdDFtNHQzX2N1cjNfZjByXzU0ZG4zNTVffQ=='bash# Or pull from zsteg directly:bashzsteg -E b1,rgba,lsb,xy red.png | base64 -d 2>/dev/null | headLearn more
Finding the same Base64-encoded flag repeated multiple times in the LSB data reveals that the challenge author embedded enough copies to ensure retrieval even if some LSB bits are corrupted by image processing (like JPEG re-encoding). PNG is lossless, so corruption is not an issue here, but the repetition also makes the payload easy to spot - any LSB scanner that finds a long run of the same pattern flags it immediately.
The
base64 -dcommand (orbase64 --decode) reads Base64 input and writes raw bytes. Theechoapproach works for single-line strings, but for multi-line or padded input, piping from a file is more reliable:base64 -d < encoded.txt. CyberChef's "Magic" operation can auto-detect encoding schemes and chain decoders, which is useful when the exact encoding isn't immediately obvious.From a defensive perspective, LSB steganography is used in the real world for both legitimate purposes (digital watermarking of media to prove ownership or detect leaks) and malicious purposes (hiding malware configuration, command-and-control instructions, or exfiltrated data in innocuous-looking images). Network DLP solutions struggle to detect LSB steganography because the images appear valid and the hidden data has no file signature to match.
Flag
picoCTF{r3d_1s_th3_ult1m4t3_cur3_f0r_54dn...}
Any LSB tool works; zsteg just makes it a one-command extraction.