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 1
Treat the SVG as textObservationI noticed the challenge file was an SVG rather than a raster image like PNG or JPEG, which suggested that its content is stored as XML markup and can be read directly as text without any image processing.SVG files are XML, so you can view them as text. The flag's letters appear as separate<text>nodes.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 2
Remove the markupObservationI noticed the flag characters were spread across many individual XML text nodes rather than appearing on a single line, which suggested that standard text tools like cut and tr would be needed to strip the surrounding tags and concatenate the pieces into one 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
picoCTF{...}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 have a font-size so small they render as invisible or single-pixel dots even at maximum browser zoom. The browser renders the visual output, not the raw XML, so zooming just scales up blank space. Reading the file as text with strings or a text editor bypasses the renderer entirely and reveals the characters directly.
Tried: Run
grep 'picoCTF' drawing.flag.svgto find the flag in one shot instead of building the cut pipeline.Each letter of the flag is stored in its own separate XML text element across many lines, so no single line contains the full flag string. grep matches whole lines, so it returns nothing useful. The cut and tr pipeline is needed to extract and concatenate the per-character inner text nodes 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
- 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{...}
Sometimes "enhancing" means simply inspecting the source.