Stack Pivoting - EBP2Ret - EBP chaining
Grundlegende Informationen
Diese Technik nutzt die Möglichkeit, den Base Pointer (EBP) zu manipulieren, um die Ausführung mehrerer Funktionen durch sorgfältige Verwendung des EBP-Registers und der leave; ret
-Instruktionssequenz zu verketten.
Zur Erinnerung bedeutet leave
im Grunde genommen:
Und da sich der EBP im Stack vor dem EIP befindet, ist es möglich, ihn zu kontrollieren, indem man den Stack kontrolliert.
EBP2Ret
Diese Technik ist besonders nützlich, wenn Sie den EBP-Register ändern können, aber keinen direkten Weg haben, das EIP-Register zu ändern. Sie nutzt das Verhalten von Funktionen aus, wenn sie die Ausführung beenden.
Wenn es Ihnen während der Ausführung von fvuln
gelingt, einen gefälschten EBP im Stack einzuspeisen, der auf einen Speicherbereich zeigt, in dem die Adresse Ihres Shellcodes liegt (plus 4 Bytes für die pop
-Operation), können Sie indirekt das EIP kontrollieren. Wenn fvuln
zurückkehrt, wird der ESP auf diese manipulierte Position gesetzt, und die nachfolgende pop
-Operation verringert den ESP um 4, wodurch er effektiv auf eine Adresse zeigt, die vom Angreifer dort gespeichert wurde.
Beachten Sie, wie Sie 2 Adressen kennen müssen: Diejenige, wohin der ESP gehen wird, und diejenige, an die Sie die Adresse schreiben müssen, auf die der ESP zeigt.
Exploit-Konstruktion
Zuerst müssen Sie eine Adresse kennen, an der Sie beliebige Daten/Adressen schreiben können. Der ESP wird hierhin zeigen und das erste ret
ausführen.
Dann müssen Sie die Adresse kennen, die von ret
verwendet wird, um beliebigen Code auszuführen. Sie könnten verwenden:
Eine gültige ONE_GADGET-Adresse.
Die Adresse von
system()
gefolgt von 4 Junk-Bytes und der Adresse von"/bin/sh"
(x86-Bits).Die Adresse eines
jump esp;
-Gadgets (ret2esp) gefolgt vom Shellcode zur Ausführung.Einige ROP-Kette
Denken Sie daran, dass vor einer dieser Adressen im kontrollierten Speicherbereich 4
Bytes stehen müssen, aufgrund des pop
-Teils der leave
-Anweisung. Es wäre möglich, diese 4B zu missbrauchen, um einen zweiten gefälschten EBP zu setzen und die Ausführung weiter zu kontrollieren.
Off-By-One Exploit
Es gibt eine spezifische Variante dieser Technik, die als "Off-By-One Exploit" bekannt ist. Sie wird verwendet, wenn Sie nur das am wenigsten signifikante Byte des EBP ändern können. In einem solchen Fall muss der Speicherort, der die Adresse zum Springen mit dem ret
speichert, die ersten drei Bytes mit dem EBP teilen, was eine ähnliche Manipulation unter stärker eingeschränkten Bedingungen ermöglicht.
Normalerweise wird das Byte 0x00 modifiziert, um so weit wie möglich zu springen.
Außerdem ist es üblich, einen RET-Schlitten im Stack zu verwenden und die echte ROP-Kette am Ende zu platzieren, um die Wahrscheinlichkeit zu erhöhen, dass der neue ESP innerhalb des RET-Schlittens zeigt und die endgültige ROP-Kette ausgeführt wird.
EBP-Chaining
Daher ist es möglich, indem Sie eine kontrollierte Adresse im EBP
-Eintrag des Stacks platzieren und eine Adresse zu leave; ret
in EIP
, den ESP
zur kontrollierten EBP
-Adresse im Stack zu verschieben.
Nun wird der ESP
kontrolliert und zeigt auf eine gewünschte Adresse, und die nächste auszuführende Anweisung ist ein RET
. Um dies auszunutzen, können Sie an der kontrollierten ESP-Stelle Folgendes platzieren:
&(nächster gefälschter EBP)
-> Lädt den neuen EBP aufgrund vonpop ebp
aus derleave
-Anweisungsystem()
-> Aufgerufen vonret
&(leave;ret)
-> Wird nach dem Ende von system aufgerufen, es verschiebt ESP zum gefälschten EBP und startet erneut&("/bin/sh")
-> Parameter fürsystem
Auf diese Weise ist es im Grunde möglich, mehrere gefälschte EBPs zu verketten, um den Programmfluss zu kontrollieren.
Dies ist wie ein ret2lib, aber komplexer ohne offensichtlichen Nutzen, könnte jedoch in einigen Randfällen interessant sein.
Darüber hinaus finden Sie hier eine Beispielherausforderung, die diese Technik mit einem Stack-Leak verwendet, um eine Gewinnfunktion aufzurufen. Dies ist das endgültige Nutzlast von der Seite:
EBP könnte nicht verwendet werden
Wie in diesem Beitrag erklärt, wenn ein Binärprogramm mit einigen Optimierungen kompiliert wird, wird EBP niemals ESP kontrollieren, daher wird jeder Exploit, der durch die Kontrolle von EBP funktioniert, im Grunde scheitern, da er keine echte Wirkung hat. Dies liegt daran, dass sich das Prolog- und Epilogverhalten ändert, wenn das Binärprogramm optimiert ist.
Nicht optimiert:
Optimiert:
Andere Möglichkeiten, um RSP zu kontrollieren
pop rsp
Gadget
pop rsp
GadgetAuf dieser Seite finden Sie ein Beispiel für die Verwendung dieser Technik. Für diese Herausforderung war es erforderlich, eine Funktion mit 2 spezifischen Argumenten aufzurufen, und es gab ein pop rsp
Gadget sowie ein Leak aus dem Stack:
xchg <reg>, rsp Gadget
jmp esp
Überprüfen Sie die ret2esp-Technik hier:
pageRet2esp / Ret2regReferenzen & Weitere Beispiele
64 Bit, Off-by-One-Exploitation mit einer ROP-Kette, die mit einem Ret-Schlitten beginnt
64 Bit, kein relro, canary, nx und pie. Das Programm gewährt ein Leak für den Stack oder pie und ein WWW eines Qwords. Zuerst den Stack-Leak erhalten und das WWW verwenden, um zurückzugehen und den pie-Leak zu erhalten. Verwenden Sie dann das WWW, um eine ewige Schleife zu erstellen, indem Sie
.fini_array
-Einträge missbrauchen +__libc_csu_fini
aufrufen (mehr Infos hier). Durch den Missbrauch dieses "ewigen" Schreibens wird eine ROP-Kette im .bss geschrieben und schließlich aufgerufen, indem mit RBP gepivottet wird.
ARM64
Im ARM64 speichern und wiederherstellen die Prologe und Epiloge der Funktionen nicht das SP-Register im Stack. Darüber hinaus kehrt die RET
-Anweisung nicht zur Adresse zurück, die vom SP gezeigt wird, sondern zur Adresse innerhalb von x30
.
Daher können Sie standardmäßig durch den Missbrauch des Epilogs das SP-Register nicht kontrollieren, indem Sie einige Daten im Stack überschreiben. Und selbst wenn es Ihnen gelingt, das SP zu kontrollieren, bräuchten Sie immer noch eine Möglichkeit, den x30
-Register zu kontrollieren.
Prolog
Epilog
Der Weg, etwas Ähnliches wie Stack-Pivoting in ARM64 durchzuführen, wäre die Fähigkeit, das SP
zu kontrollieren (indem Sie ein Register kontrollieren, dessen Wert an SP
übergeben wird oder weil aus irgendeinem Grund SP
seine Adresse vom Stack nimmt und wir einen Überlauf haben) und dann den Epilog zu missbrauchen, um das **x30
-Register von einem kontrollierten SP
zu laden und an ihn zu **RET
**en.
Auf der folgenden Seite können Sie auch das Äquivalent von Ret2esp in ARM64 sehen:
pageRet2esp / Ret2regLast updated