(c) teso. all rights reversed.
exploiting format string vulnerabilities - Multiple Print

Multiple Print

Wenn man die Möglichkeit hat, mehrere Male die format-Funktion in einem Prozess zu exploiten (zum Beispiel bei wuftpd 2.6.0), so kann man nicht nur die retaddr überschreiben, sondern auch den gesammten Shellcode zum Beispiel auf dem Heap ablegen. Damit läßt sich eine non-exec-Stack Protection leicht umgehen. Zusammen mit einem GOT-overwrite (siehe unten) lassen sich folgende Schutzmechanismen umgehen (kein Anspruch auf vollständigkeit):

  • StackGuard
  • StackShield
  • Solar Designers openwall kernel patch
  • libsafe

Seit Mitte Oktober 2000 gibt es auch eine Möglichkeit auf dem x86 schreib- und lesbare Memorypages zu implementieren, die nicht ausführbar sind [3]. Dies bringt zusätzliche Probleme mit sich. Es ist somit praktisch unmöglich eigenen Programmcode auszuführen. Aber es ist in den meisten Fällen schon nützlicher Programmcode im exploiteten Prozess vorhanden. So kann mit herkömmlichen LibC-Techniken [1] auch dieser Schutz umgangen werden. Am einfachsten ist es, direkt in system() zu returnen, mit dem Format String als Parameter. Dazu überschreibt man die retaddr der Funktion, die die *printf Funktion aufruft. Direkt dahinter legt man den Parameter für System ab, einen Pointer in den eigenen Buffer.

Theoretisch wäre es auch möglich direkt die retaddr der *printf Funktion zu überschreiben, doch damit zerstört man den ersten Parameter der printf Funktion, was zu einem Absturz führt.

Durch ein wenig Optimierung kann man die Offsets, die bekannt sein müssen auf nur eins reduzieren: Die Adresse der system() Funktion.
Denn wenn man zum Beispiel die bash aufrufen will benutzt man eine Zeile der Form (am besten am Ende des Format Strings, damit sie NUL terminiert ist):

"/../../../../../../../../../bin/bash -c \"id;exit\""

Bei allen "Treffern" vor "/bin/bash" gelingt dieser Aufruf, denn "../", "./" und "/" sind gültig. Das sind quasi NOP's ;-)

<< - < - > - >>