Open Source im professionellen Einsatz

ImageMagick: Entfernter Angreifer kann Befehle ausführen

Eine kürzlich entdeckte Schwachstelle in der ImageMagick-Bibliothek erlaubt es einem entferntern Angreifer Befehle mit den Rechten des Anwenders auszuführen. Die Attacke ist denkbar einfach auszunutzen und kann über einen speziellen Dateinamen ausgeführt werden. Dieser muss lediglich ein Pipe-Zeichen enthalten. Die nach dem Pipe-Zeichen aufgeführten Befehle werden dann ausgeführt. Eine einfache Attacke könnte wie folgt aussehen:

rm -f hello.txt
convert '|echo Hello > hello.txt;' null:
ls hello.txt

Der erste Befehl löscht zunächst die Datei hello.txt, falls diese vorhanden ist. Anschliessend wird das convert-Tool auf einen geschickt konstruierten Dateinamen angewendet. Convert ist Teil des ImageMagick-Pakets und damit ebenfalls anfällig für die Schwachstelle. Der hinter dem Pipe-Zeichen übergebene Befehl hat dann zur Folge, dass der Text Hello in die Datei hello.txt geschrieben wird. Ein anschliessendes ls hello.txt zeigt dann die so erzeugt Datei an. In der Datei befindet sich auch der gewünschte Inhalt.

Ursache für diese sehr offensichtliche Schwachstelle ist, dass ImageMagick einen direkten »popen()«-Aufruf ausführt, ohne vorher den Dateinamen zu filtern. Der entsprechende Aufruf befindet sich in den Core-Routinen in der »MagickCore/blob.c«-Datei:

image->blob->file_info.file=(FILE *) popen_utf8(filename+1, fileMode);

Dieser Aufruf ist sehr fehleranfällig, weil »popen_utf8()« direkt auf den vom Anwender angegebenen Dateinamen angewendet wird. Ohne Filterung dieses Dateinamens ist es für einen Angreifer leicht möglich beliebige sicherheitskritsche Zeichen hier einzuschleusen.Werden so  Dateinamen mit Pipe-Zeichen nicht abgefangen, führen sie zu dem geschilderten Problem.

Das Problem wurde nun korrigiert indem der »filename«-String vor der Übergabe an »popen_utf8()« zunächst mit einer neu hinzugefügten Funktion gefiltert wird:

sanitize_command=SanitizeString(filename+1);
image->blob->file_info.file=(FILE *) popen_utf8(sanitize_command, fileMode);

Die »SanitizeString()«-Funktion nimmt als Argument den Dateinamen und filtert alle sicherheitskritischen Zeichen heraus. Diese Funktion wurde komplett neu in der »MagickCore/string.c«-Datei implementiert und nun auch noch an einigen anderen Stellen im ImageMagick-Code verwendet, um den Code ein wenig aufzuräumen. Die Funktionsweise von SanitizeString() ist sehr einfach: sie lässt nur solche Zeichen in dem übergebenen String zu, die in einer fest definierten Whitelist-Zeichentabelle enthalten sind. Diese Tabelle ist im Code definiert und enthält folgende Zeichen:

static char whitelist[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$-_.+!*'(),{}|\\^~[]`\"><#%;/?:@&="; 

Sollte der an die Funktion übergebene String ein Zeichen enthalten, welches nicht in dieser whitelist enthalten ist, so wird dieses kritische Zeichen einfach durch ein '_' ersetzt, um potentielle Probleme zu vermeiden. Neben der ImageMagick-Bibliothek ist auch der GraphicsMagick-Ableger anfällig für dieses Problem. Genau wie bei ImageMagick ist auch hier ein ungefilterter »popen()«-Aufruf für die Schwachstelle verantwortlich.  Er befindet sich in GraphicsMagick in der »OpenBlob()«-Funktion. Statt einer Filterfunktion hat man sich hier dafür entschieden ganz auf den »popen()«-Aufruf zu verzichten und verwendet stattdessen »fopen()«.   

comments powered by Disqus

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.