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, die Sie normalerweise verwenden, um das Verhalten des Programms zu manipulieren, nicht finden können.
Wenn ein Programm bestimmte Bibliotheken verwendet (wie libc), verfügt es über einige integrierte Funktionen zur Verwaltung der Kommunikation zwischen verschiedenen Teilen des Programms. Unter diesen Funktionen befinden sich einige versteckte Schätze, die als unsere fehlenden Gadgets fungieren können, insbesondere eine namens __libc_csu_init
.
Die magischen Gadgets in __libc_csu_init
In __libc_csu_init
gibt es zwei Sequenzen von Anweisungen (Gadgets), die hervorgehoben werden sollten:
Die erste Sequenz ermöglicht es uns, Werte in mehreren Registern (rbx, rbp, r12, r13, r14, r15) einzurichten. Diese dienen als Speicherplätze, 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 Stapel in sie laden.
Die zweite Sequenz verwendet die von uns eingerichteten Werte, um ein paar Dinge zu tun:
Bestimmte Werte in andere Register verschieben, um sie für uns als Parameter in Funktionen vorzubereiten.
Einen Aufruf an eine Stelle durchführen, die durch Addition der Werte in r15 und rbx bestimmt wird, und dann rbx mit 8 multipliziert.
Vielleicht kennen Sie keine Adresse, die Sie dort eingeben können, und Sie benötigen eine
ret
-Anweisung. Beachten Sie, dass der zweite Gadget auch mit einemret
enden wird, aber Sie müssen einige Bedingungen erfüllen, um ihn zu erreichen:
Die Bedingungen werden sein:
[r12 + rbx*8]
muss auf eine Adresse zeigen, die eine aufrufbare Funktion speichert (wenn keine Idee und kein PIE vorhanden sind, können Sie einfach die Funktion_init
verwenden):Wenn _init sich bei
0x400560
befindet, verwenden Sie GEF, um nach einem Zeiger im Speicher darauf zu suchen und machen Sie[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 berücksichtigt werden müssen
RDI und RSI
Eine weitere Möglichkeit, rdi
und rsi
aus dem ret2csu-Gadget zu steuern, besteht darin, auf spezifische Offset zuzugreifen:
Überprüfen Sie diese Seite für weitere Informationen:
pageBROP - Blind Return Oriented ProgrammingBeispiel
Verwendung des Aufrufs
Stellen Sie sich vor, Sie möchten einen Systemaufruf machen oder eine Funktion wie write()
aufrufen, aber spezifische Werte in den Registern rdx
und rsi
als Parameter benötigen. Normalerweise würden Sie nach Gadgets suchen, die diese Register direkt setzen, aber Sie finden keine.
Hier kommt ret2csu ins Spiel:
Registrierungen einrichten: Verwenden Sie den ersten magischen Gadget, um Werte vom Stapel in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) und r15 zu laden.
Verwenden des zweiten Gadgets: Mit diesen gesetzten Registern verwenden Sie den zweiten Gadget. Dies ermöglicht es Ihnen, Ihre ausgewählten Werte in
rdx
undrsi
zu verschieben (aus r14 und r13), um Parameter für einen Funktionsaufruf vorzubereiten. Darüber hinaus können Sie durch die Steuerung vonr15
undrbx
das Programm dazu bringen, eine Funktion aufzurufen, die sich an der von Ihnen berechneten Adresse befindet und in[r15 + rbx*8]
platziert wird.
Es gibt ein Beispiel für die Verwendung dieser Technik und deren Erklärung hier, und dies ist der endgültige Exploit, der verwendet wurde:
Beachten Sie, dass das vorherige Exploit nicht dazu gedacht ist, eine RCE
durchzuführen, sondern lediglich eine Funktion namens win
aufzurufen (die Adresse von win
aus stdin aufrufen, gets im ROP-Chain und in r15 speichern) mit einem dritten Argument mit dem Wert 0xdeadbeefcafed00d
.
Umgehen des Aufrufs und Erreichen von ret
Der folgende Exploit wurde von dieser Seite extrahiert, auf der ret2csu verwendet wird, aber anstelle des Aufrufs die Vergleiche umgeht und den ret
nach dem Aufruf erreicht:
Warum nicht einfach libc direkt verwenden?
Normalerweise sind diese Fälle auch anfällig für ret2plt + ret2lib, aber manchmal müssen mehr Parameter kontrolliert werden, als mit den Gadgets möglich ist, die direkt in libc gefunden werden. Zum Beispiel erfordert die write()
-Funktion drei Parameter, und es ist möglicherweise nicht möglich, Gadgets zu finden, um diese direkt zu setzen.
Last updated