Leaking libc address with ROP
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Finde Overflow Offset
Finde POP_RDI
Gadget, PUTS_PLT
und MAIN
Gadgets
Verwende die vorherigen Gadgets, um die Speicheradresse von puts oder einer anderen libc-Funktion zu leaken und die libc-Version zu finden (herunterladen)
Mit der Bibliothek berechne den ROP und exploitiere ihn
Dieses Tutorial wird den im Tutorial vorgeschlagenen Code/Binary ausnutzen: https://tasteofsecurity.com/security/ret2libc-unknown-libc/ Weitere nützliche Tutorials: https://made0x78.com/bseries-ret2libc/, https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
Dateiname: vuln.c
Lade den Exploit herunter und platziere ihn im selben Verzeichnis wie die verwundbare Binärdatei und gib die benötigten Daten an das Skript weiter:
Die Vorlage benötigt einen Offset, bevor mit dem Exploit fortgefahren werden kann. Wenn ein Offset bereitgestellt wird, wird der notwendige Code ausgeführt, um ihn zu finden (standardmäßig OFFSET = ""
):
Führen Sie python template.py
aus, ein GDB-Konsole wird geöffnet, in der das Programm abgestürzt ist. Führen Sie in dieser GDB-Konsole x/wx $rsp
aus, um die Bytes zu erhalten, die den RIP überschreiben sollten. Holen Sie sich schließlich den Offset mit einer Python-Konsole:
Nachdem der Offset gefunden wurde (in diesem Fall 40), ändern Sie die OFFSET-Variable im Template mit diesem Wert.
OFFSET = "A" * 40
Eine andere Möglichkeit wäre: pattern create 1000
-- ausführen bis ret -- pattern seach $rsp
von GEF.
Jetzt müssen wir ROP-Gadgets im Binärdatei finden. Diese ROP-Gadgets werden nützlich sein, um puts
aufzurufen, um die verwendete libc zu finden, und später um den endgültigen Exploit zu starten.
Der PUTS_PLT
wird benötigt, um die Funktion puts aufzurufen.
Der MAIN_PLT
wird benötigt, um die Hauptfunktion nach einer Interaktion erneut aufzurufen, um die Überlauf erneut zu exploiten (unendliche Runden der Ausnutzung). Es wird am Ende jedes ROP verwendet, um das Programm erneut aufzurufen.
Der POP_RDI wird benötigt, um einen Parameter an die aufgerufene Funktion zu übergeben.
In diesem Schritt müssen Sie nichts ausführen, da alles während der Ausführung von pwntools gefunden wird.
Jetzt ist es an der Zeit herauszufinden, welche Version der libc-Bibliothek verwendet wird. Dazu werden wir die Adresse im Speicher der Funktion puts
leaken und dann werden wir suchen, in welcher Bibliotheksversion sich die puts-Version an dieser Adresse befindet.
Um dies zu tun, ist die wichtigste Zeile des ausgeführten Codes:
Dies wird einige Bytes senden, bis das Überschreiben des RIP möglich ist: OFFSET
.
Dann wird die Adresse des Gadgets POP_RDI
gesetzt, sodass die nächste Adresse (FUNC_GOT
) im RDI-Register gespeichert wird. Das liegt daran, dass wir puts aufrufen möchten, indem wir ihm die Adresse von PUTS_GOT
übergeben, da die Adresse im Speicher der puts-Funktion in der Adresse gespeichert ist, auf die PUTS_GOT
zeigt.
Danach wird PUTS_PLT
aufgerufen (mit PUTS_GOT
im RDI), sodass puts den Inhalt in PUTS_GOT
(die Adresse der puts-Funktion im Speicher) liest und ihn ausgibt.
Schließlich wird die Hauptfunktion erneut aufgerufen, damit wir den Überlauf erneut ausnutzen können.
Auf diese Weise haben wir die puts-Funktion getäuscht, um die Adresse im Speicher der Funktion puts (die sich in der libc-Bibliothek befindet) auszugeben. Jetzt, da wir diese Adresse haben, können wir suchen, welche libc-Version verwendet wird.
Da wir einige lokale Binärdateien ausnutzen, ist es nicht nötig, herauszufinden, welche Version von libc verwendet wird (einfach die Bibliothek in /lib/x86_64-linux-gnu/libc.so.6
finden).
Aber im Fall eines Remote-Exploits erkläre ich hier, wie Sie es finden können:
Sie können suchen, welche Bibliothek auf der Webseite verwendet wird: https://libc.blukat.me/ Es wird Ihnen auch ermöglichen, die entdeckte Version von libc herunterzuladen.
Sie können auch Folgendes tun:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
Das wird einige Zeit in Anspruch nehmen, seien Sie geduldig. Damit dies funktioniert, benötigen wir:
Libc-Symbolname: puts
Leaked libc-Adresse: 0x7ff629878690
Wir können herausfinden, welche libc höchstwahrscheinlich verwendet wird.
Wir erhalten 2 Übereinstimmungen (Sie sollten die zweite ausprobieren, wenn die erste nicht funktioniert). Laden Sie die erste herunter:
Kopiere die libc von libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
in unser Arbeitsverzeichnis.
An diesem Punkt sollten wir die verwendete libc-Bibliothek kennen. Da wir ein lokales Binary ausnutzen, werde ich einfach verwenden: /lib/x86_64-linux-gnu/libc.so.6
Ändern Sie also am Anfang von template.py
die libc-Variable in: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Setzen Sie den Bibliothekspfad, wenn Sie ihn kennen
Durch die Angabe des Pfads zur libc-Bibliothek wird der Rest des Exploits automatisch berechnet.
Innerhalb der get_addr
-Funktion wird die Basisadresse von libc berechnet:
Beachten Sie, dass die endgültige libc-Basisadresse mit 00 enden muss. Wenn das nicht der Fall ist, haben Sie möglicherweise eine falsche Bibliothek geleakt.
Dann werden die Adresse der Funktion system
und die Adresse des Strings "/bin/sh" aus der Basisadresse von libc berechnet und der libc-Bibliothek gegeben.
Schließlich wird der /bin/sh Ausführungs-Exploit vorbereitet und gesendet:
Lass uns dieses letzte ROP erklären.
Das letzte ROP (rop1
) endete damit, dass die Hauptfunktion erneut aufgerufen wurde, dann können wir die Overflow erneut ausnutzen (deshalb ist der OFFSET
hier wieder). Dann wollen wir POP_RDI
aufrufen, das auf die Adresse von "/bin/sh" (BINSH
) zeigt, und die system Funktion (SYSTEM
) aufrufen, da die Adresse von "/bin/sh" als Parameter übergeben wird.
Schließlich wird die Adresse der Exit-Funktion aufgerufen, damit der Prozess schön beendet wird und keine Warnung generiert wird.
Auf diese Weise wird der Exploit eine _/bin/sh_** Shell ausführen.**
Du könntest auch ONE_GADGET verwenden, um eine Shell zu erhalten, anstatt system und "/bin/sh" zu verwenden. ONE_GADGET wird in der libc-Bibliothek eine Möglichkeit finden, eine Shell mit nur einer ROP-Adresse zu erhalten.
Normalerweise gibt es jedoch einige Einschränkungen, die häufigsten und am einfachsten zu vermeidenden sind wie [rsp+0x30] == NULL
. Da du die Werte im RSP kontrollierst, musst du nur einige weitere NULL-Werte senden, damit die Einschränkung umgangen wird.
Sie können hier eine Vorlage finden, um diese Schwachstelle auszunutzen:
Wenn das "main"-Symbol nicht existiert. Dann können Sie herausfinden, wo sich der Hauptcode befindet:
und die Adresse manuell festlegen:
Wenn die Binary Puts nicht verwendet, sollten Sie überprüfen, ob sie verwendet wird
sh: 1: %s%s%s%s%s%s%s%s: nicht gefunden
Wenn Sie diesen Fehler nach der Erstellung des gesamten Exploits finden: sh: 1: %s%s%s%s%s%s%s%s: nicht gefunden
Versuchen Sie, 64 Bytes von der Adresse von "/bin/sh" abzuziehen:
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)