Ret2csu
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
ret2csu ist eine Hacking-Technik, die verwendet wird, wenn Sie versuchen, die Kontrolle über ein Programm zu übernehmen, aber die gadgets nicht finden können, die Sie normalerweise verwenden, um das Verhalten des Programms zu manipulieren.
Wenn ein Programm bestimmte Bibliotheken (wie libc) verwendet, hat es einige integrierte Funktionen, um zu verwalten, wie verschiedene Teile des Programms miteinander kommunizieren. Unter diesen Funktionen gibt es einige versteckte Schätze, die als unsere fehlenden Gadgets fungieren können, insbesondere eines namens __libc_csu_init
.
In __libc_csu_init
gibt es zwei Befehlsfolgen (gadgets), die hervorgehoben werden sollten:
Die erste Befehlsfolge ermöglicht es uns, Werte in mehreren Registern (rbx, rbp, r12, r13, r14, r15) einzurichten. Diese sind wie Slots, in denen wir Zahlen oder Adressen speichern können, die wir später verwenden möchten.
Dieses Gadget ermöglicht es uns, diese Register zu steuern, indem wir Werte vom Stack in sie hineinpoppen.
Die zweite Sequenz verwendet die Werte, die wir eingerichtet haben, um ein paar Dinge zu tun:
Bestimmte Werte in andere Register verschieben, um sie bereit zu machen, dass wir sie als Parameter in Funktionen verwenden können.
Einen Aufruf zu einem Ort durchführen, der bestimmt wird, indem die Werte in r15 und rbx zusammenaddiert und dann rbx mit 8 multipliziert werden.
Vielleicht kennst du keine Adresse, um dort zu schreiben, und du brauchst eine ret
-Anweisung. Beachte, dass das zweite Gadget ebenfalls mit einem ret
endet, aber du musst einige Bedingungen erfüllen, um es zu erreichen:
Die Bedingungen sind:
[r12 + rbx*8]
muss auf eine Adresse zeigen, die eine aufrufbare Funktion speichert (wenn keine Idee und kein pie, kannst du einfach die _init
-Funktion verwenden):
Wenn _init bei 0x400560
ist, verwende GEF, um einen Zeiger im Speicher darauf zu suchen und mache [r12 + rbx*8]
zur Adresse mit dem Zeiger auf _init:
rbp
und rbx
müssen den gleichen Wert haben, um den Sprung zu vermeiden
Es gibt einige ausgelassene Pops, die Sie berücksichtigen müssen
Eine weitere Möglichkeit, rdi
und rsi
vom ret2csu-Gadget zu steuern, besteht darin, auf spezifische Offsets zuzugreifen:
Überprüfen Sie diese Seite für weitere Informationen:
BROP - Blind Return Oriented ProgrammingStellen Sie sich vor, Sie möchten einen Syscall durchführen oder eine Funktion wie write()
aufrufen, benötigen jedoch spezifische Werte in den Registern rdx
und rsi
als Parameter. Normalerweise würden Sie nach Gadgets suchen, die diese Register direkt setzen, aber Sie können keine finden.
Hier kommt ret2csu ins Spiel:
Register einrichten: Verwenden Sie das erste magische Gadget, um Werte vom Stack in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) und r15 zu poppen.
Zweites Gadget verwenden: Mit diesen gesetzten Registern verwenden Sie das zweite Gadget. Dies ermöglicht es Ihnen, Ihre gewählten Werte in rdx
und rsi
(von r14 und r13) zu verschieben und die Parameter für einen Funktionsaufruf vorzubereiten. Darüber hinaus können Sie durch die Kontrolle von r15
und rbx
das Programm dazu bringen, eine Funktion an der Adresse aufzurufen, die Sie berechnen und in [r15 + rbx*8]
platzieren.
Sie haben ein Beispiel, das diese Technik verwendet und es hier erklärt, und dies ist der endgültige Exploit, den es verwendet:
Beachten Sie, dass der vorherige Exploit nicht dazu gedacht ist, ein RCE
durchzuführen, sondern lediglich eine Funktion namens win
aufzurufen (indem die Adresse von win
aus stdin, die in der ROP-Kette durch gets aufgerufen wird, entnommen und in r15 gespeichert wird) mit einem dritten Argument mit dem Wert 0xdeadbeefcafed00d
.
Der folgende Exploit wurde von dieser Seite extrahiert, wo ret2csu verwendet wird, aber anstelle des Aufrufs wird die Überprüfung umgangen und ret
nach dem Aufruf erreicht:
In der Regel sind diese Fälle auch anfällig für ret2plt + ret2lib, aber manchmal müssen Sie mehr Parameter steuern, als mit den Gadgets, die Sie direkt in libc finden, leicht kontrolliert werden können. Zum Beispiel erfordert die Funktion write()
drei Parameter, und das Finden von Gadgets, um all diese direkt zu setzen, könnte nicht möglich sein.