Freitag, 19. Juni 2009


Topthema

Donnerstag, 5. Februar 2009 | Topthema

About Security #191: Schwachstellen-Suche: SOAP-Injection finden

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/047197)

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.

Beispiel, Version 2

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 finden

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.

SOAP-Injection ausnutzen
About Security: Die komplette Serie

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.

SOAP-Injection verhindern

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 < (&lt;), > (&gt;) und / (&#47;).

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!

Carsten Eilers

About Security - Übersicht zum aktuellen Thema:

Kommentare

Folgende Links könnten Sie auch interessieren