Freitag, 25. Mai 2012 |
| |
Auch in dieser Folge ist das Thema die SOAP-Injection bzw. das Einschleusen eigenen Codes in SOAP. Zuerst wird das Beispiel aus About Security #190 um einen weiteren Angriff erweitert.
Die betroffene Backend-Anwendung verwendet jetzt das letzte gefundene
<Gedeckt>-Element . Wie in About Security
#190
beschrieben, ist es beim vorgestellten Aufbau der SOAP-Nachricht nicht
möglich, hinter das vorhandene <Gedeckt>-Element
Code einzuschleusen. Es kann also weder ein gefälschtes
<Gedeckt>-Element eingefügt noch das vorhandene
erfolgreich auskommentiert werden.
Günstiger wäre es, wenn die Elemente in der SOAP-Nachricht eine
andere Reihenfolge hätten, z.B. <vonKonto>,
<Betrag>, <Gedeckt>,
<vonKonto>:
<?xml version="1.0" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
<pre:Add xmlns:pre="http://ziel.example/liste
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<Konto>
<vonKonto>1234567</vonKonto>
<Betrag>123,45</Betrag>
<Gedeckt>False</Gedeckt>
<aufKonto>9876543</aufKonto>
</Konto>
</pre:Add>
</soap:Body>
</soap:Envelope>
In diesem Fall könnte das gefälschte
<Gedeckt>-Element über den Parameter
Betrag eingeschleust werden und der Kommentar über den
Parameter aufKonto geschlossen werden:
http://www.bank.example/ueberweisen.cgi?vonKonto=1234567&
Betrag=123,45</Betrag><Gedeckt>True</Gedeckt><aufKonto><!
-- &aufKonto= -->9876543
Das ergibt die syntaktisch korrekte SOAP-Nachricht
<?xml version="1.0" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
<pre:Add xmlns:pre="http://ziel.example/liste
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<Konto>
<vonKonto>1234567</vonKonto>
<Betrag>123,45</Betrag>
<Gedeckt>True</Gedeckt>
<aufKonto>
<!-- </Betrag><Gedeckt>False</Gedeckt><aufKonto> -->
9876543</aufKonto>
</Konto>
</pre:Add>
</soap:Body>
</soap:Envelope>
mit einem geschlossenen Kommentar, durch den das ursprüngliche
<Gedeckt>-Element vor der Backend-Anwendung verborgen
wird.
SOAP-Injection-Schwachstellen sind schwer zu finden, da falsch eingeschleuste XML-Metazeichen das Format der SOAP-Nachricht zerstören und damit oft nur zu einer allgemeinen Fehlermeldung führen. Hinzu kommt, das SOAP meist im Backend-Bereich verwendet wird, so dass dort erzeugte Fehlermeldungen oft zusätzlich vom Web-Frontend geändert oder ersetzt werden. Generell können SOAP-Injection-Schwachstellen mit den folgenden Tests erkannt werden:
Zuerst wird der Reihe nach in jeden verfügbaren Parameter ein nicht
existierendes schließendes XML-Tag wie z.B.
</gibtsnicht> eingegeben. Führt das zu keinem
Fehler, wird der betreffende Parameter entweder nicht in einer
SOAP-Nachricht eingefügt oder vor dem Einfügen gefiltert.
Tritt ein Fehler auf, wird als nächster Test ein gültiges Paar
aus öffnenden und schließenden XML-Tag wie z.B.
<gibtsnicht></gibtsnicht> eingegeben. Tritt nun
kein Fehler mehr auf, enthält die Anwendung sehr wahrscheinlich eine
SOAP-Injection-Schwachstelle.
Manchmal werden in eine SOAP-Nachricht eingefügte Parameter nach der Verarbeitung wieder an den Benutzer ausgegeben. Dann kann getestet werden, ob eingegebene XML-Daten unverändert oder in irgend einer Form normalisiert zurückgegeben werden. Dazu können z.B. folgende Testwerte verwendet werden:
test<gibtsnicht/>
test<gibtsnicht></gibtsnicht>
Werden entweder beide Eingaben unverändert oder nur test
zurückgeliefert, wurden sie sehr wahrscheinlich in eine XML-basierte
Nachricht eingefügt.
Werden über einen HTTP-Request mehrere Parameter übertragen, die
Teil einer SOAP-Nachricht werden könnten, können darüber
Kommentarzeichen als Test eingeschleust werden: Über einen der
Parameter werden die öffnenden Zeichen <!--
eingegeben, über einen anderen die schließenden Zeichen
-->. Wird dadurch ein Teil der SOAP-Nachricht
auskommentiert, ändert sich entweder das Verhalten der
Anwendungslogik, oder es gibt vielleicht eine andere Fehlermeldung. Ideal
wäre es, wenn statt einer allgemeinen Fehlermeldung eine Meldung wie
z.B. "Parameter 'irgendwas' fehlt" weitere Informationen
über den Aufbau der SOAP-Nachricht liefert.
Da nicht bekannt ist, in welcher Reihenfolge die Parameter in die SOAP-Nachricht übernommen werden, müssen ggf. alle möglichen Kombinationen ausprobiert werden, bis es zu einem brauchbaren Ergebnis kommt.
Es ist schon schwierig genug, SOAP-Injection überhaupt zu erkennen. Eine gefundene Schwachstelle dann auch auszunutzen, ist i.A. noch deutlich schwieriger. Um die SOAP-Nachricht erfolgreich zu manipulieren, muss ihr Aufbau bekannt sein. Das ist bei Closed-Source-Software wenn überhaupt meist nur durch umfangreiche Tests mit anschließender Auswertung der Fehlermeldungen zu erreichen. Daher freut sich ein Angreifer natürlich besonders über eine ausführliche Fehlermeldung, die gleich die gesamte fehlerhafte SOAP-Nachricht enthält.
Wie immer gilt: Um das Einschleusen von Code zu verhindern, müssen alle Daten vor ihrer Übernahme in eine SOAP-Nachricht geprüft, bereinigt und/oder ggf. verworfen werden. Das betrifft alle vom Benutzer manipulierbare Daten, egal ob es sich um direkte Eingaben oder um zuvor gespeicherte und/oder bearbeitete Daten handelt.
XML-Metazeichen müssen in die entsprechenden HTML-Entities umgewandelt
werden, so dass der XML-Interpreter sie als Daten des betreffenden Elements
und nicht als Teil der Nachrichtenstruktur interpretiert. Das betrifft
insbesondere < (<), > (>) und
/ (/).
Wie am Beispiel zu sehen war, kann auch der Aufbau der SOAP-Nachricht sowie deren Interpretation einen Angriff erleichtern oder erschweren. Auch wenn bösartige Eingaben niemals bis in die SOAP-Nachricht gelangen sollten, schadet es nichts, sich bei deren Konstruktion Gedanken darüber zu machen, ob und wie Benutzereingaben von selbst erzeugten Daten getrennt werden können.
In der nächsten Folge geht es um einen weiteren Command-Injection-Angriff, und zwar um das Einschleusen zusätzlicher Daten in SMTP.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!