Summary
A .kra-adjacent artifact named Bundle_99 is handed off for analysis. It turns out to be a Krita resource bundle (.bundle) — a plain ZIP archive containing a brush preset (Brush 99.kpp). The .kpp file is itself a PNG with an embedded XML Preset block in its metadata. Buried inside dozens of harmless paintop parameters is a kis_text_brush definition whose text attribute contains the flag — Krita lets you generate a brush that stamps out literal text, so the flag was simply typed into that field and saved as a custom brush.
Flag: bronco{REDACTED}
Walkthrough
1. Identify the file type
The starting artifact, Bundle_99, doesn't carry a useful extension. file identifies it as a ZIP:
file Bundle_99
Bundle_99: Zip data (MIME type "application/x-krita-resourcebundle"?)
The MIME type hint (application/x-krita-resourcebundle) confirms this is a Krita resource bundle — Krita's format for packaging brush presets, patterns, and other assets for sharing.
2. Inspect and extract the archive
zipinfo Bundle_99
Archive: Bundle_99
Zip file size: 83110 bytes, number of entries: 5
-r--r--r-- 3.0 unx 34 b- stor 26-Feb-13 20:44 mimetype
-r--r--r-- 3.0 unx 19143 b- defN 26-Feb-13 20:44 paintoppresets/Brush 99.kpp
-r--r--r-- 3.0 unx 62913 b- defN 26-Feb-13 20:44 preview.png
-r--r--r-- 3.0 unx 436 t- defN 26-Feb-13 20:44 META-INF/manifest.xml
-r--r--r-- 3.0 unx 907 t- defN 26-Feb-13 20:44 meta.xml
5 files, 83433 bytes uncompressed, 82558 bytes compressed: 1.0%
unzip Bundle_99
Archive: Bundle_99
extracting: mimetype
inflating: paintoppresets/Brush 99.kpp
inflating: preview.png
inflating: META-INF/manifest.xml
inflating: meta.xml
This is the same layout OpenDocument-family formats use — a mimetype file, a META-INF/manifest.xml, and asset payloads. Confirmed by the raw mimetype contents:
cat mimetype
application/x-krita-resourcebundle
3. Check the bundle metadata
meta.xml and META-INF/manifest.xml describe the bundle but hold no flag — just author/license placeholders and a file manifest with an MD5 for the single preset:
cat meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<meta:meta>
<meta:generator>Krita (5.2.10 (git ea9eb7a))</meta:generator>
<meta:bundle-version>1</meta:bundle-version>
<dc:author>Bundle 99</dc:author>
<dc:title>Bundle 99</dc:title>
<dc:description>99 bundles of brushes on the wall, 99 bundles of brushes.
Take one down and pass it around, 98 bundles of brushes on the wall.</dc:description>
...
</meta:meta>
cat META-INF/manifest.xml
<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">
<manifest:file-entry manifest:media-type="application/x-krita-resourcebundle" manifest:full-path="/"/>
<manifest:file-entry manifest:media-type="paintoppresets" manifest:full-path="paintoppresets/Brush 99.kpp" manifest:md5sum="3c3433276c419d607d0a5b60d65fc21d"/>
</manifest:manifest>
A quick recursive grep for the flag prefix across the extracted tree comes up empty — it isn't sitting in any plaintext file:
grep -rn "bronco{" .
(no output — the flag isn't sitting in plaintext anywhere in the tree)
4. Identify the actual type of the .kpp preset
.kpp looks like a proprietary Krita extension, but file-type detection shows it's really a PNG:
file paintoppresets/Brush\ 99.kpp
paintoppresets/Brush 99.kpp: PNG image data, 200 x 200, 8-bit/color RGBA, non-interlaced
Krita brush presets store a 200×200 thumbnail as the "real" PNG image, then stash the entire preset configuration (every paintop parameter — size, spacing, opacity curves, sensor curves, etc.) as XML inside a PNG text/metadata chunk. That's the natural place to dig with exiftool.
5. Pull the embedded metadata with exiftool
exiftool paintoppresets/Brush\ 99.kpp
...
Preset : <Preset embedded_resources="0" paintopid="paintbrush" name="Brush 99">
<param name="ColorSource/Type" type="string"><![CDATA[plain]]></param>
...
<param name="brush_definition" type="string"><![CDATA[<Brush spacing="0.1" density="1" type="auto_brush" ...> <MaskGenerator .../> </Brush>]]></param>
...
<param name="brush_definition" type="string"><![CDATA[<Brush font="Segoe UI,9,-1,5,50,0,0,0,0,0" spacing="0.2" pipe="false" type="kis_text_brush" BrushVersion="2" text="bronco{REDACTED}"/>]]></param>
...
</Preset>
Version : 5.0
Image Size : 200x200
Megapixels : 0.040
The Preset XML block is a long dump of nearly every paintop setting Krita tracks (pressure sensors, opacity/size/rotation curves, masking brush config, etc.) — almost all noise. Two brush_definition params stand out, though:
- One is
type="auto_brush"— a normal procedurally-generated circular brush tip. - The other is
type="kis_text_brush"— Krita's text brush, which renders a literal string as the brush stamp shape instead of a generated tip. Itstextattribute is the flag:text="bronco{REDACTED}".
Someone built this preset specifically to smuggle the flag: rather than hiding it in unrelated metadata fields, they used a first-class Krita feature (typing text to create a custom brush shape) and just never intended to actually paint with it.
Attack Chain
Bundle_99 (misnamed ZIP, MIME hints "krita-resourcebundle")
│
▼
unzip → paintoppresets/Brush 99.kpp, meta.xml, manifest.xml, mimetype, preview.png
│
▼
file Brush 99.kpp → actually a PNG (Krita preset thumbnails carry embedded config)
│
▼
exiftool Brush 99.kpp → dumps <Preset> XML metadata chunk
│
▼
Two <param name="brush_definition"> entries:
- auto_brush (decoy, procedural tip)
- kis_text_brush text="bronco{FLAG}" ← flag hidden as brush glyph text
Key Points
| Step | Technique | Notes |
|---|---|---|
| File identification |
file on an unlabeled artifact |
ZIP masquerading as a generic filename revealed as a Krita bundle via MIME string |
| Archive structure | OpenDocument-style bundle layout |
mimetype + META-INF/manifest.xml + payload, same pattern as ODF/EPUB |
| Nested file-type mismatch |
.kpp extension vs. actual PNG magic bytes |
Krita presets are PNGs with an embedded XML config chunk |
| Metadata extraction | exiftool |
Pulled the full <Preset> XML, including all paintop parameters |
| Data hiding technique | Krita kis_text_brush
|
Flag stored as the literal text attribute of a text-based brush definition — a legitimate feature repurposed for steganography |
Top comments (0)