Ret2csu
https://www.scs.stanford.edu/brop/bittau-brop.pdfGrundlegende Informationen
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
.
Die magischen Gadgets in __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 wird.
Vielleicht kennst du keine Adresse, um dort zu schreiben, und du brauchst eine
ret
-Anweisung. Beachte, dass das zweite Gadget ebenfalls mit einemret
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
undrbx
müssen den gleichen Wert haben, um den Sprung zu vermeidenEs gibt einige ausgelassene Pops, die du berücksichtigen musst
RDI und RSI
Eine weitere Möglichkeit, rdi
und rsi
vom ret2csu-Gadget zu steuern, besteht darin, auf spezifische Offsets zuzugreifen:
Überprüfe diese Seite für weitere Informationen:
BROP - Blind Return Oriented ProgrammingBeispiel
Verwendung des Aufrufs
Stell dir vor, du möchtest einen Syscall machen oder eine Funktion wie write()
aufrufen, benötigst jedoch spezifische Werte in den Registern rdx
und rsi
als Parameter. Normalerweise würdest du nach Gadgets suchen, die diese Register direkt setzen, aber du kannst keine finden.
Hier kommt ret2csu ins Spiel:
Registriere die Register einrichten: Verwende das erste magische Gadget, um Werte vom Stack in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) und r15 zu poppen.
Verwende das zweite Gadget: Mit diesen Registern kannst du das zweite Gadget verwenden. Dies ermöglicht es dir, deine gewählten Werte in
rdx
undrsi
(von r14 und r13) zu verschieben und die Parameter für einen Funktionsaufruf vorzubereiten. Darüber hinaus kannst du durch die Kontrolle vonr15
undrbx
das Programm dazu bringen, eine Funktion an der Adresse aufzurufen, die du berechnest und in[r15 + rbx*8]
platzierst.
Du hast ein Beispiel, das diese Technik verwendet und es hier erklärt, und dies ist der endgültige Exploit, den es verwendet hat:
Beachten Sie, dass der vorherige Exploit nicht dazu gedacht ist, ein RCE
durchzuführen, sondern lediglich eine Funktion namens win
aufzurufen (die Adresse von win
aus stdin zu holen, indem gets in der ROP-Kette aufgerufen wird und sie in r15 gespeichert wird) mit einem dritten Argument mit dem Wert 0xdeadbeefcafed00d
.
Umgehen des Aufrufs und Erreichen von ret
Der folgende Exploit wurde von dieser Seite extrahiert, wo ret2csu verwendet wird, aber anstelle des Aufrufs die Vergleiche umgeht und das ret
nach dem Aufruf erreicht:
Warum nicht einfach libc direkt verwenden?
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 write()
-Funktion drei Parameter, und das Finden von Gadgets, um all diese direkt zu setzen, könnte nicht möglich sein.
Last updated