Leaking libc address with ROP
Kurze Zusammenfassung
Ermitteln des Überlauf-Offsets
Finden des
POP_RDI
-Gadgets,PUTS_PLT
undMAIN
-GadgetsVerwenden Sie die zuvor gefundenen Gadgets, um die Speicheradresse von
puts
oder einer anderen libc-Funktion zu leaken und die libc-Version zu ermitteln (herunterladen)Mit der Bibliothek das ROP berechnen und ausnutzen
Weitere Tutorials und Binärdateien zum Üben
Dieses Tutorial wird den im folgenden Tutorial vorgeschlagenen Code/Binärdatei 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 - Auslaufende LIBC-Vorlage
Laden Sie das Exploit herunter und platzieren Sie es im selben Verzeichnis wie die anfällige Binärdatei und geben Sie die benötigten Daten an das Skript:
pageLeaking libc - template1- Ermittlung des Offset
Die Vorlage benötigt einen Offset, bevor sie mit dem Exploit fortfahren kann. Wenn keiner bereitgestellt wird, führt sie den erforderlichen Code aus, um ihn zu finden (standardmäßig OFFSET = ""
):
Führen Sie python template.py
aus, es wird eine GDB-Konsole geöffnet, in der das Programm abstürzt. Führen Sie innerhalb dieser GDB-Konsole x/wx $rsp
aus, um die Bytes zu erhalten, die den RIP überschreiben werden. Ermitteln Sie abschließend den Offset mithilfe einer Python-Konsole:
Nachdem Sie den Offset gefunden haben (in diesem Fall 40), ändern Sie die OFFSET-Variable innerhalb der Vorlage mit diesem Wert.
OFFSET = "A" * 40
Eine andere Möglichkeit wäre die Verwendung von: pattern create 1000
-- ausführen bis ret -- pattern seach $rsp
von GEF.
2- Finden von Gadgets
Jetzt müssen wir ROP-Gadgets innerhalb des 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 auszuführen.
Der PUTS_PLT
wird benötigt, um die Funktion puts aufzurufen.
Der MAIN_PLT
wird benötigt, um die Hauptfunktion erneut aufzurufen, nachdem eine Interaktion stattgefunden hat, um den Überlauf erneut zu ausnutzen (unendliche Runden der Ausnutzung). Es wird am Ende jedes ROP verwendet, um das Programm erneut aufzurufen.
Das 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 von pwntools während der Ausführung gefunden wird.
3- Auffinden 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 sendet einige Bytes, bis das Überschreiben des RIP möglich ist: OFFSET
.
Dann wird die Adresse des Gadgets POP_RDI
festgelegt, damit die nächste Adresse (FUNC_GOT
) im RDI-Register gespeichert wird. Dies geschieht, weil wir puts aufrufen möchten, wobei wir ihm die Adresse des PUTS_GOT
übergeben, da die Adresse der puts-Funktion im Speicher 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 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 der Funktion puts im Speicher auszugeben (die sich in der libc-Bibliothek befindet). Jetzt, da wir diese Adresse haben, können wir herausfinden, welche libc-Version verwendet wird.
Da wir einige lokale Binärdateien ausnutzen, ist es nicht erforderlich, herauszufinden, welche Version von libc verwendet wird (einfach die Bibliothek in /lib/x86_64-linux-gnu/libc.so.6
finden).
In einem Fall von Remote-Exploits werde ich hier erklären, wie Sie es finden können:
3.1- Suchen nach libc-Version (1)
Sie können auf der Webseite suchen, welche Bibliothek verwendet wird: https://libc.blukat.me/ Es ermöglicht Ihnen auch, die entdeckte Version von libc herunterzuladen.
3.2- Suchen nach libc-Version (2)
Sie können auch Folgendes tun:
$ git clone https://github.com/niklasb/libc-database.git
$ cd libc-database
$ ./get
Dies wird einige Zeit dauern, bitte haben Sie Geduld. Damit dies funktioniert, benötigen wir:
Libc-Symbolname:
puts
Durchgesickerte libc-Adresse:
0x7ff629878690
Wir können herausfinden, welche libc höchstwahrscheinlich verwendet wird.
Wir haben 2 Treffer (probieren Sie den zweiten aus, wenn der erste nicht funktioniert). Laden Sie den ersten herunter:
Kopieren Sie die libc von libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so
in unser Arbeitsverzeichnis.
3.3- Andere Funktionen zum Auslesen
4- Finden basierend auf der libc-Adresse & ausnutzen
An diesem Punkt sollten wir die verwendete libc-Bibliothek kennen. Da wir eine lokale Binärdatei ausnutzen, werde ich einfach verwenden: /lib/x86_64-linux-gnu/libc.so.6
Also, am Anfang von template.py
ändern Sie die libc Variable zu: libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it
Indem Sie den Pfad zur libc-Bibliothek angeben, wird der Rest des Exploits automatisch berechnet.
Im get_addr
-Funktion wird die Basisadresse von libc berechnet:
Beachten Sie, dass die endgültige Basisadresse von libc mit 00 enden muss. Wenn das nicht der Fall ist, haben Sie möglicherweise eine falsche Bibliothek durchgesickert.
Dann werden die Adresse der Funktion system
und die Adresse des Strings "/bin/sh" aus der Basisadresse von libc berechnet und unter Verwendung der libc-Bibliothek angegeben.
Schließlich wird das Ausführungs-Exploit für /bin/sh vorbereitet und gesendet:
Lassen Sie uns dieses letzte ROP erklären.
Das letzte ROP (rop1
) endete erneut mit dem Aufruf der Hauptfunktion, dann können wir erneut ausnutzen den Überlauf (deshalb ist hier wieder der OFFSET
). Dann möchten wir POP_RDI
aufrufen, der auf die Adresse von "/bin/sh" (BINSH
) zeigt, und die system-Funktion aufrufen (SYSTEM
), da die Adresse von "/bin/sh" als Parameter übergeben wird.
Schließlich wird die Adresse der exit-Funktion aufgerufen, damit der Prozess ordnungsgemäß beendet wird und keine Warnung generiert wird.
Auf diese Weise wird das Exploit eine _/bin/sh_** Shell ausführen.**
4(2)- Verwendung von ONE_GADGET
Sie könnten auch ONE_GADGET verwenden, um anstelle von system und **"/bin/sh" eine Shell zu erhalten. ONE_GADGET wird innerhalb der libc-Bibliothek einen Weg finden, um eine Shell zu erhalten, indem nur eine ROP-Adresse verwendet wird.
Normalerweise gibt es jedoch einige Einschränkungen, die häufigsten und einfach zu vermeidenden sind wie [rsp+0x30] == NULL
. Da Sie die Werte im RSP kontrollieren, müssen Sie nur einige weitere NULL-Werte senden, damit die Einschränkung vermieden wird.
EXPLOIT DATEI
Sie können hier eine Vorlage finden, um diese Schwachstelle auszunutzen:
pageLeaking libc - templateHäufige Probleme
MAIN_PLT = elf.symbols['main'] nicht gefunden
Wenn das Symbol "main" nicht existiert. Dann können Sie herausfinden, wo sich der Hauptcode befindet:
und die Adresse manuell setzen:
Puts nicht gefunden
Wenn das Binär nicht Puts verwendet, sollten Sie überprüfen, ob es verwendet
sh: 1: %s%s%s%s%s%s%s%s: not found
sh: 1: %s%s%s%s%s%s%s%s: not found
Wenn Sie diesen Fehler nach Erstellung des gesamten Exploits finden: sh: 1: %s%s%s%s%s%s%s%s: not found
Versuchen Sie, 64 Bytes von der Adresse von "/bin/sh" abzuziehen:
Last updated