(c) teso. all rights reversed.
exploiting format string vulnerabilities - GOT Overwrite

GOT Overwrite

Durch die lange bekannte Geschichte der Buffer Overflows glauben viele Leute, dass es das Beste sei, immer die Return Address (retaddr) auf dem Stack zu überschreiben, um Kontrolle über den Prozess zu erlangen. Obwohl dies offensichtlich gut funktioniert, ist es eher eine aus dem Zwang heraus gewählte Möglichkeit. Bei herkömmlichen Bufferoverflows auf dem Stack besteht halt nur die Möglichkeit, die auf dem Stack gespeicherten Daten zu überschreiben. Haben wir jedoch wie hier die Freiheit, beliebige Daten im beschreibbaren Speicher des Prozesses zu überschreiben, so gibt es eine oft bessere Alternative: die Adresse einer library-Funktion in der Global Offset Table (GOT). Sie enthält für alle zu dem Programm dazugelinkten Funktionen einen Eintrag, der die Adresse der Funktion erhält.

Sind die GNU binutils installiert, kann mit
objdump --dynamic-reloc binary

eine Liste der GOT Einträge der Binary angezeigt werden. Die Sprungadresse liegt direkt bei der angegebenen Adresse. Objdump zeigt somit direkt die von uns benötigte Return Address Location (retloc) an.

Vorteile: Wir brauchen kein "ret", sondern auch Code der Art:
        syslog (LOG_NOTICE, user);
        exit (EXIT_FAILURE);
führt zur Ausführung unseres Shellcodes, wenn der GOT Eintrag von exit() überschrieben wurde [4].

Ein weiterer Vorteil ist, dass man somit Schutzmechanismen umgehen kann, die mit einem carnary die Return Address auf dem Stack sichern [5]. Zusätzlich ist die GOT Adresse per Binary fest, das heisst, sie verändert sich nicht wie eine Stackadresse, wenn das Program zum Beispiel mit einem anderen Environment gestartet wird.
Ausserdem ist es einfach praktischer als im GDB die retaddr auf dem Stack zu suchen (Hacker sind schliesslich tippfaul ;-)

<< - < - > - >>