Description
Despite the hint to "enhance," there's no need to zoom the image; just read the text stored in the SVG file.
Run strings or open the SVG in a text editor.
Grep for lines containing > / < and strip the XML tags to reveal the embedded characters.
strings drawing.flag.svg | grep ">" | cut -d '>' -f2 | cut -d '<' -f1 | tr -d '\n 'Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Treat the SVG as text
ObservationThe file is an SVG rather than a raster image like PNG or JPEG. Its content is XML markup, readable directly as text with no image processing at all.SVG files are XML, so you can view them as text. The flag's characters are split, space-separated, across a handful of<tspan>elements inside a single<text>element, drawn at a font-size of 0.0035px so nothing shows up visually.Learn more
SVG (Scalable Vector Graphics) is an XML-based image format that describes graphics through markup rather than pixels. Unlike raster formats (PNG, JPEG), SVG files are plain text that a browser or renderer interprets - you can open one in any text editor and read the underlying structure directly.
Because SVG is XML, it embeds arbitrary text inside
<text>elements. That XML stays in the file even when the renderer hides it. Authors can shrink the font (font-size="0.1pt"), position the text outside the canvas (x="-9999"), setvisibility="hidden", or use color matching the background. None of those affect the underlying XML;stringsreads them verbatim.The challenge title references the TV trope of endlessly enhancing low-resolution images to reveal hidden detail. The joke is that the real "enhancement" is recognizing that SVG is text, not a bitmap - no image processing needed.
Step 2Remove the markup
ObservationThe flag characters are scattered across many individual XML text nodes rather than sitting on one line. cut and tr can strip the surrounding tags and join the pieces into a single readable string.Strip the tags, drop whitespace, and concatenate. Build it up step by step so you can sanity-check each stage.bashstrings drawing.flag.svg | grep '>'bashstrings drawing.flag.svg | grep '>' | cut -d '>' -f2bashstrings drawing.flag.svg | grep '>' | cut -d '>' -f2 | cut -d '<' -f1bashstrings drawing.flag.svg | grep '>' | cut -d '>' -f2 | cut -d '<' -f1 | tr -d '\n 'bashxmlstarlet sel -t -v "//text()" drawing.flag.svg | tr -d '\n 'Expected output
image/svg+xmlpicoCTF{3nh4nc3d_24374675}What didn't work first
Tried: Open the SVG in a browser and use the browser's built-in zoom to magnify the tiny text until it is readable.
The text nodes carry a font size so small they render as invisible or single-pixel dots even at full zoom. The browser draws the visual output rather than the raw XML, so zooming only enlarges blank space. Reading the file as text, with strings or an editor, skips the renderer and shows the characters directly.
Tried: Run
grep 'picoCTF' drawing.flag.svgto find the flag in one shot instead of building the cut pipeline.The characters are spread across several XML text elements on separate lines, so no single line holds the whole flag. grep matches whole lines and returns nothing useful. The cut and tr pipeline extracts the per-character text nodes and concatenates them into one continuous string.
Learn more
Walk the pipeline left to right.
strings ... | grep ">"filters to lines that contain at least one tag terminator - i.e. lines with text content sitting next to markup.cut -d '>' -f2keeps everything to the right of the first>, dropping the opening tag.cut -d '<' -f1keeps everything to the left of the next<, dropping the closing tag. What survives is the inner text.tr -d '\n 'collapses the per-character lines into one continuous string - that's your flag.The pipeline is fragile (multiple tags per line, attributes containing
>, mixed content all break it) but fast enough for well-formed simple SVG. For anything bigger, use a real XML parser:xmlstarlet sel -t -v "//text()" drawing.flag.svguses XPath to extract all text nodes regardless of layout. Python'sxml.etree.ElementTreeworks too:import xml.etree.ElementTree as ET tree = ET.parse('drawing.flag.svg') print(''.join(t.strip() for t in tree.getroot().itertext()))
Interactive tools
- StegallDrop any file and Stegall runs every applicable steg technique in parallel: LSB sweeps, bit planes, spectrograms, polyglot carving, metadata, whitespace decode, and a 6-layer base/ROT/XOR/zlib cascade. Recursively unpacks results and surfaces flag matches.
- Image Metadata ViewerRead EXIF, XMP, JPEG comments, and PNG tEXt / iTXt / zTXt chunks from images entirely in the browser. Highlights flag-like values.
- 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.
Flag
Reveal flag
picoCTF{3nh4nc3d_24374675}
Sometimes "enhancing" means simply inspecting the source.