Leaking libc address with ROP
Schnelle Zusammenfassung
Finden Sie den Überlauf Offset
Finden Sie
POP_RDI
Gadget,PUTS_PLT
undMAIN
GadgetsVerwenden Sie 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 berechnen Sie den ROP und exploiten Sie ihn
Weitere Tutorials und Binaries zum Üben
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
Code
Dateiname: vuln.c
ROP - Leaking LIBC Vorlage
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:
Leaking libc - template1- Offset finden
Die Vorlage benötigt einen Offset, bevor sie mit dem Exploit fortfahren 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, eine 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.
2- Gadgets finden
Jetzt müssen wir ROP-Gadgets im Binärdatei finden. Diese ROP-Gadgets werden nützlich sein, um puts
aufzurufen, um die libc zu finden, die verwendet wird, 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 auszunutzen (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.
3- Finden der libc-Bibliothek
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 innerhalb von PUTS_GOT
(die Adresse der puts-Funktion im Speicher) liest und ausgibt.
Schließlich wird die Hauptfunktion erneut aufgerufen, damit wir das Ü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:
3.1- Suche nach der libc-Version (1)
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.
3.2- Suche nach der libc-Version (2)
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
Leckende libc-Adresse:
0x7ff629878690
Wir können herausfinden, welche libc höchstwahrscheinlich verwendet wird.
Wir erhalten 2 Übereinstimmungen (du solltest die zweite ausprobieren, wenn die erste nicht funktioniert). Lade die erste herunter:
Kopiere die libc von libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
in unser Arbeitsverzeichnis.
3.3- Andere Funktionen zum Leaken
4- Finden der libc-Adresse und Ausnutzen
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") #Setze den Bibliothekspfad, wenn bekannt
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 endet und keine Warnung generiert wird.
Auf diese Weise wird der Exploit eine _/bin/sh_** Shell ausführen.**
4(2)- Verwendung von ONE_GADGET
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.
EXPLOIT DATEI
Sie können hier eine Vorlage finden, um diese Schwachstelle auszunutzen:
Leaking libc - templateHäufige Probleme
MAIN_PLT = elf.symbols['main'] nicht gefunden
Wenn das "main"-Symbol nicht existiert. Dann können Sie herausfinden, wo sich der Hauptcode befindet:
und die Adresse manuell festlegen:
Puts nicht gefunden
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
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:
Last updated