(c) teso. all rights reversed.
exploiting format string vulnerabilities - brute force (response)

brute force (response)

Diese Technik war rudimentär zuerst in Exploits für wuftpd 2.6.0 zu sehen, wurde jedoch später von smiler und mir erweitert und in unserem wuftpd Exploit (7350wu) verwendet.

Dabei macht man sich zu Nutze, daß man die Ausgabe des Format Strings sehen kann. Wie schon gesagt braucht man mindestens drei Angaben, um normale Format String Vulnerabilities zu exploiten: Die distance, die return address location und die return address.

Um die distance zu brute forcen, benutzt man einen Format String der Art: "AAAABBBB|<stackpop>|%08x|". Der Stackpop wird nun für jeden Versuch neu konstruiert:
        while (distance > 0) {
                strcat (fmtstring, "%u");
                distance -= 4;
        }
So sieht bei einer distance von zum Beispiel 32 der Format String so aus:

"AAAABBBB|%u%u%u%u%u%u%u%u|%08x|".

Man popped also 32 Bytes (8 * "%u") vom Stack und gibt dann hexadezimal den nächsten Parameter aus. Idealerweise sieht die Ausgabe dann so aus:

AAAABBBB|912402418294128001248701248702480228827413487030|41414141|

Da "41414141" die hexadezimale Repräsentation für "AAAA" ist, hat man genau den Bufferanfang nach 32 Bytes auf dem Stack liegen. Sollte man durch Erhöhen der distance um vier nicht auf dieses Muster treffen, so kann dies zwei Gründe haben. Entweder der Format String liegt nicht auf dem Stack (siehe unten bei "Format String im Heap"), oder man erhält dafür ein Muster der Art: "42424141". Dann muss das alignment anders gewählt werden, in diesem Fall muß es dann zwei betragen.

Hat man erst einmal alignment und distance, so kann man sich an das finden der Buffer Adresse machen. Dazu benutzt man einen ähnlichen Format String:
<addr><stackpop>|___________________________________________________%%|%s|
Der stackpop arbeitet sich wieder im Stack hoch, so daß der nächste Parameter die in vier Bytes codierte Adresse 'addr' ist. Der Speicherinhalt bei 'addr' wird nun mit Hilfe von "%s" angezeigt. Idealerweise sieht die Ausgabe so aus:
<Müll>|___________________________________________________%|________%%|%s||
Man kann hier sehen, daß der "%%" Parameter umgewandelt wurde. Hinter dem ersten '|'-Zeichen ist nun der Speicherinhalt bei der Adresse 'addr' zu sehen, da wir "einen String bei 'addr'" mit Hilfe von "%s" ausgeben. Zeigt 'addr' in den Format String, so bietet sich das obige Bild. Da wir 'addr' kennen - wir haben es ja selbst gewählt - können wir nun die genaue Adresse des Format Strings ausmachen. Es kann sich dabei aber auch um eine Kopie des Format Strings handeln, was für das Exploiten jedoch unwichtig ist.

Zeigt 'addr' jedoch in den Zielbuffer, in den *snprintf'd wird, so zeigt sich:
<Müll>|___________________________________________________%|________%||
Man beachte, das der "%%" Parameter bereits umgewandelt wurde. Wieder können wir Rückschlüsse auf die Adresse des Zielbuffers machen, was und bei der "im Heap"-Situation hilfreich sein kann.

<< - < - > - >>