Description
Ron just found his own copy of advanced potion making, but it's been corrupted. Help him recover it!
Setup
Download advanced-potion-making from the challenge page.
Install a hex editor (e.g. hexedit, ghex, or use xxd) and StegSolve.
xxd advanced-potion-making | headSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Identify the file typeObservationI noticed the challenge file had no extension and the 'file' command reported 'data' rather than a recognized format, which suggested the magic bytes at the start of the file were corrupted and a hex dump was needed to inspect the raw bytes and identify what format the body actually contained.Run xxd on the file and compare the first 8 bytes to the PNG magic signature 89 50 4E 47 0D 0A 1A 0A. The file contains IHDR and IEND chunks confirming it is a PNG, but the magic bytes at offset 0 are wrong.bashxxd advanced-potion-making | headbashfile advanced-potion-makingExpected output
advanced-potion-making: data
What didn't work first
Tried: Trust the 'file' command output alone and conclude the download is corrupted beyond repair.
The 'file' command only reads the first few bytes (the magic signature) to classify a file. When those bytes are wrong it reports 'data', but the rest of the file can be completely intact. Running xxd and scanning further into the output reveals IHDR and IEND chunk names, which are definitive proof the body is a valid PNG - only the 8-byte header needs to be patched.
Tried: Run strings on the file hoping to find the flag directly without repairing it first.
strings extracts printable ASCII sequences from raw bytes, but a corrupted PNG header means image viewers and stego tools refuse to process the file at all. Any flag embedded via LSB steganography is encoded in pixel bit planes, not as a printable ASCII string in the raw binary stream, so strings produces no useful output and skips the necessary header repair step.
Learn more
Magic bytes (also called file signatures) are fixed byte sequences at the beginning of a file that identify its format. The PNG signature is
89 50 4E 47 0D 0A 1A 0A: the89is a non-ASCII byte that prevents the file from being misidentified as text;50 4E 47is ASCII "PNG"; the carriage return and line feed sequence detects line-ending corruption; and1Ais a DOS EOF marker. Together they form a robust format fingerprint.The
filecommand reads magic bytes rather than file extensions to identify types - this is whyfilecorrectly identifies a JPEG renamed to.txt. When magic bytes are corrupted,filereportsdata(unrecognized binary). Comparingxxdoutput to published format specifications lets you pinpoint which bytes are wrong.PNG chunks provide a secondary confirmation: IHDR (image header) and IEND (image end) are mandatory chunks with fixed names. Finding them in the
xxdoutput confirms the file body is a valid PNG even when the header is corrupted, narrowing the repair to just the first 8 bytes.Step 2
Fix the PNG magic bytesObservationI noticed that xxd confirmed the file body contained IHDR and IEND PNG chunk names while only the first 8 bytes were wrong, which suggested a targeted in-place patch of the PNG magic signature using dd with conv=notrunc would be enough to make the file parseable again without touching any image data.Overwrite the first 8 bytes with the correct PNG signature using dd. The conv=notrunc flag ensures the rest of the file is not truncated.bashprintf '\x89\x50\x4e\x47\x0d\x0a\x1a\x0a' | dd of=advanced-potion-making bs=1 count=8 conv=notruncbashfile advanced-potion-makingWhat didn't work first
Tried: Use 'dd' without conv=notrunc to write the magic bytes.
Without conv=notrunc, dd truncates the output file to match the size of the input - so writing 8 bytes would delete everything after byte 8, destroying all the PNG image data. The file command would then report a valid PNG header on a nearly empty file and no image would display. Adding conv=notrunc tells dd to write only the specified bytes in place and leave the rest of the file untouched.
Tried: Open the file in a hex editor and manually type the PNG signature bytes as ASCII characters 89504E47.
Typing the characters '8', '9', '5', '0' in a text-mode hex editor writes their ASCII code points (0x38, 0x39, 0x35, 0x30), not the raw byte value 0x89 followed by 0x50. The PNG signature requires specific raw byte values, not the ASCII representation of their hex digits. Using printf with \xNN escapes or a dedicated hex editor in overwrite mode ensures the correct raw bytes are written.
Learn more
ddis the Unix low-level copy utility.bs=1sets a block size of 1 byte so it writes exactly as many bytes as specified.count=8limits it to 8 bytes. Crucially,conv=notruncpreventsddfrom truncating the output file to the size of the input - without this flag, the 8-byte write would delete everything after byte 8.printfwith\\xNNescape sequences emits raw bytes. This is the standard shell idiom for writing arbitrary binary data without a dedicated hex editor. An alternative is Python:python3 -c "import sys; sys.stdout.buffer.write(bytes([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]))".This repair technique - patching just the damaged bytes in-place - is safer than recreating the file because it preserves every byte of the original. The same approach is used in file carving during forensic recovery: extract the known-good body and prepend or repair the header to make the file parseable again.
Step 3
Open the repaired imageObservationI noticed that after patching the magic bytes the file command confirmed a valid 500x500 RGB PNG, which suggested opening it in an image viewer to assess the visual content before choosing a steganography extraction technique.The file now opens as a solid red PNG image. The flag is hidden in the least-significant bits of the red channel - not visible to the naked eye.basheog advanced-potion-makingWhat didn't work first
Tried: Run steghide on the repaired PNG to extract the hidden data.
steghide uses its own embedding algorithm based on graph theory and requires a passphrase to both hide and extract data. This challenge uses simple LSB steganography with no passphrase, so steghide extract will either prompt for a password and fail or report that no data was found. The correct tool is one that reads raw bit planes directly, such as StegSolve or zsteg.
Tried: Run zsteg on the image and assume the first result is the flag without checking the channel.
zsteg scans multiple channels and bit depths in sequence and may surface false-positive matches in other planes before reaching the red LSB plane. If the output lists several candidates, picking the first without verifying the channel (b1,r,lsb,xy or similar) can lead to garbled output instead of the flag. The correct approach is to look for the result labeled with the red channel at bit depth 1.
Learn more
LSB (Least Significant Bit) steganography hides data by replacing the lowest-order bit of each pixel's color channel with one bit of the secret message. For an 8-bit red channel, changing bit 0 from 0 to 1 shifts the color by 1/255 - imperceptible to human vision but readable by software that extracts those bits and reassembles them into bytes.
A solid color image is an ideal steganography carrier for a CTF because the contrast between the data-carrying pixels and the rest is zero to the human eye - every pixel appears to be exactly the same shade of red. Any variation is in the LSB, which the eye cannot distinguish. A photographic image would be a more typical real-world carrier because the natural noise in photos provides cover for the introduced bit-flips.
The specific focus on the red channel (rather than all channels or a different channel) is a challenge design choice. Tools like StegSolve let you isolate individual color planes and bit depths to find where hidden data lives, rather than having to check all 24 possible bit planes manually.
Step 4
Extract the hidden flag with StegSolveObservationI noticed the repaired image appeared as a perfectly uniform solid red color with no visible variation, which is a classic LSB steganography carrier and suggested using StegSolve to inspect the red channel's bit plane 0 where the hidden data would be readable as structured text rather than noise.Open the repaired file in StegSolve. Navigate to the Red plane 0 view. The flag text becomes clearly readable in the LSBs of the red channel.Learn more
StegSolve is a Java application for image steganography analysis. Its "Bit Plane" view renders each bit of each color channel as a separate black-and-white image - white pixels where the bit is 1, black where it is 0. Plane 0 is the LSB plane. If the LSBs are not random noise but instead encode structured data (like ASCII text), the pattern will be immediately visible as text or a recognizable image.
The workflow - view each plane, look for patterns, extract data - mirrors what automated steganography detection tools do. Tools like zsteg (for PNG and BMP), steghide (password-protected hiding), and outguess each use different embedding algorithms. When a stego challenge does not specify the tool used, you try common ones in sequence.
Steganography differs from encryption: encryption hides the content of a message while its existence is known, whereas steganography hides the existence of the message entirely. In practice they complement each other - encrypt the message, then hide it steganographically, so an adversary who finds the carrier file still cannot read the content.
Interactive tools
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
- File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
Flag
Reveal flag
picoCTF{w1z4rdry}
PNG files have a fixed 8-byte magic signature - corrupting just these bytes makes the file unreadable to any image viewer despite all image data being completely intact.