From 09307690f79a6f2c1ec278cbf78607e6a26ad677 Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 18 Aug 2025 16:16:41 +0000 Subject: [PATCH] Translated ['src/binary-exploitation/stack-overflow/stack-pivoting-ebp2r --- .../stack-pivoting-ebp2ret-ebp-chaining.md | 171 ++++++++++++------ 1 file changed, 118 insertions(+), 53 deletions(-) diff --git a/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md b/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md index 089c255df..63f5944f6 100644 --- a/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md +++ b/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md @@ -2,61 +2,65 @@ {{#include ../../banners/hacktricks-training.md}} -## Grundlegende Informationen +## Grundinformationen -Diese Technik nutzt die Fähigkeit, den **Basiszeiger (EBP)** zu manipulieren, um die Ausführung mehrerer Funktionen durch sorgfältige Verwendung des EBP-Registers und der **`leave; ret`** Instruktionssequenz zu verketten. +Diese Technik nutzt die Fähigkeit, den **Basiszeiger (EBP/RBP)** zu manipulieren, um die Ausführung mehrerer Funktionen durch sorgfältige Verwendung des Rahmenzeigers und der **`leave; ret`** Instruktionssequenz zu verketten. -Zur Erinnerung, **`leave`** bedeutet im Grunde: +Zur Erinnerung: Auf x86/x86-64 ist **`leave`** gleichbedeutend mit: ``` -mov ebp, esp -pop ebp +mov rsp, rbp ; mov esp, ebp on x86 +pop rbp ; pop ebp on x86 ret ``` -Und da sich das **EBP im Stack** vor dem EIP befindet, ist es möglich, es zu kontrollieren, indem man den Stack kontrolliert. +Und da das gespeicherte **EBP/RBP im Stack** vor dem gespeicherten EIP/RIP liegt, ist es möglich, es zu kontrollieren, indem man den Stack kontrolliert. + +> Hinweise +> - Bei 64-Bit ersetzen Sie EBP→RBP und ESP→RSP. Die Semantik bleibt gleich. +> - Einige Compiler lassen den Frame-Pointer weg (siehe „EBP könnte nicht verwendet werden“). In diesem Fall könnte `leave` nicht erscheinen und diese Technik funktioniert nicht. ### EBP2Ret -Diese Technik ist besonders nützlich, wenn Sie **das EBP-Register ändern, aber keinen direkten Weg haben, das EIP-Register zu ändern**. Sie nutzt das Verhalten von Funktionen, wenn sie die Ausführung beenden. +Diese Technik ist besonders nützlich, wenn Sie **das gespeicherte EBP/RBP ändern, aber keinen direkten Weg haben, EIP/RIP zu ändern**. Sie nutzt das Verhalten des Funktionsepilogs. -Wenn Sie während der Ausführung von `fvuln` ein **falsches EBP** in den Stack injizieren, das auf einen Bereich im Speicher zeigt, in dem sich die Adresse Ihres Shellcodes befindet (plus 4 Bytes für die `pop`-Operation), können Sie indirekt das EIP kontrollieren. Wenn `fvuln` zurückkehrt, wird der ESP auf diesen gestalteten Ort gesetzt, und die nachfolgende `pop`-Operation verringert den ESP um 4, **was effektiv bedeutet, dass er auf eine Adresse zeigt, die dort vom Angreifer gespeichert wurde.**\ -Beachten Sie, dass Sie **2 Adressen kennen müssen**: Die, zu der der ESP gehen wird, und die, zu der Sie die Adresse schreiben müssen, auf die der ESP zeigt. +Wenn Sie während der Ausführung von `fvuln` es schaffen, ein **falsches EBP** in den Stack zu injizieren, das auf einen Bereich im Speicher zeigt, wo sich die Adresse Ihres Shellcodes/ROP-Ketten befindet (plus 8 Bytes auf amd64 / 4 Bytes auf x86, um für das `pop` zu rechnen), können Sie RIP indirekt kontrollieren. Wenn die Funktion zurückkehrt, setzt `leave` RSP auf die gestaltete Adresse und das nachfolgende `pop rbp` verringert RSP, **was effektiv auf eine Adresse zeigt, die dort vom Angreifer gespeichert wurde**. Dann wird `ret` diese Adresse verwenden. + +Beachten Sie, dass Sie **2 Adressen wissen müssen**: die Adresse, zu der ESP/RSP gehen wird, und den Wert, der an dieser Adresse gespeichert ist, den `ret` konsumieren wird. #### Exploit-Konstruktion -Zuerst müssen Sie eine **Adresse kennen, an die Sie beliebige Daten / Adressen schreiben können**. Der ESP wird hierhin zeigen und **die erste `ret`** ausführen. +Zuerst müssen Sie eine **Adresse kennen, an die Sie beliebige Daten/Adressen schreiben können**. RSP wird hierhin zeigen und **den ersten `ret` konsumieren**. -Dann müssen Sie die Adresse kennen, die von `ret` verwendet wird, um **beliebigen Code auszuführen**. Sie könnten verwenden: +Dann müssen Sie die Adresse wählen, die von `ret` verwendet wird, um **die Ausführung zu übertragen**. Sie könnten verwenden: - Eine gültige [**ONE_GADGET**](https://github.com/david942j/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**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) gefolgt vom **Shellcode**, der ausgeführt werden soll. -- Eine [**ROP**](../rop-return-oriented-programing/index.html) Kette +- Die Adresse von **`system()`**, gefolgt von der entsprechenden Rückkehr und Argumenten (auf x86: `ret` Ziel = `&system`, dann 4 Junk-Bytes, dann `&"/bin/sh"`). +- Die Adresse eines **`jmp esp;`** Gadgets ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)), gefolgt von Inline-Shellcode. +- Eine [**ROP**](../rop-return-oriented-programing/index.html) Kette, die im beschreibbaren Speicher gestaged ist. -Denken Sie daran, dass vor einer dieser Adressen im kontrollierten Teil des Speichers **`4` Bytes** vorhanden sein müssen, wegen des **`pop`**-Teils der `leave`-Anweisung. Es wäre möglich, diese 4B auszunutzen, um ein **zweites falsches EBP** zu setzen und die Ausführung weiterhin zu kontrollieren. +Denken Sie daran, dass vor einer dieser Adressen im kontrollierten Bereich **Platz für das `pop ebp/rbp`** von `leave` sein muss (8B auf amd64, 4B auf x86). Sie können diese Bytes missbrauchen, um ein **zweites falsches EBP** zu setzen und die Kontrolle nach dem ersten Rückruf zu behalten. #### 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 speichert, zu der mit dem **`ret`** gesprungen werden soll, die ersten drei Bytes mit dem EBP teilen, was eine ähnliche Manipulation unter restriktiveren Bedingungen ermöglicht.\ -In der Regel wird das Byte 0x00 geändert, um so weit wie möglich zu springen. +Es gibt eine Variante, die verwendet wird, wenn Sie **nur das am wenigsten signifikante Byte des gespeicherten EBP/RBP ändern können**. In einem solchen Fall muss der Speicherort, der die Adresse speichert, zu der mit **`ret`** gesprungen werden soll, die ersten drei/fünf Bytes mit dem ursprünglichen EBP/RBP teilen, damit ein 1-Byte-Überschreiben es umleiten kann. Üblicherweise wird das niedrige Byte (Offset 0x00) erhöht, um so weit wie möglich innerhalb einer nahegelegenen Seite/ausgerichteten Region zu springen. -Es ist auch üblich, einen RET-Sled 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-SLED zeigt und die endgültige ROP-Kette ausgeführt wird. +Es ist auch üblich, einen RET-Sled im Stack zu verwenden und die echte ROP-Kette am Ende zu platzieren, um die Wahrscheinlichkeit zu erhöhen, dass das neue RSP innerhalb des Sleds zeigt und die endgültige ROP-Kette ausgeführt wird. -### **EBP Chaining** +### EBP-Verkettung -Daher ist es möglich, eine kontrollierte Adresse in den `EBP`-Eintrag des Stacks zu setzen und eine Adresse zu `leave; ret` in `EIP`, um **den `ESP` zur kontrollierten `EBP`-Adresse aus dem Stack zu bewegen**. +Indem Sie eine kontrollierte Adresse im gespeicherten `EBP`-Slot des Stacks platzieren und ein `leave; ret` Gadget in `EIP/RIP`, ist es möglich, **`ESP/RSP` zu einer vom Angreifer kontrollierten Adresse zu bewegen**. -Jetzt wird der **`ESP`** kontrolliert und zeigt auf eine gewünschte Adresse, und die nächste auszuführende Anweisung ist ein `RET`. Um dies auszunutzen, ist es möglich, an der kontrollierten ESP-Stelle Folgendes zu platzieren: +Jetzt ist `RSP` kontrolliert und die nächste Anweisung ist `ret`. Platzieren Sie im kontrollierten Speicher etwas wie: -- **`&(nächstes falsches EBP)`** -> Lädt das neue EBP wegen `pop ebp` aus der `leave`-Anweisung -- **`system()`** -> Aufgerufen von `ret` -- **`&(leave;ret)`** -> Aufgerufen, nachdem system endet, wird es den ESP zum falschen EBP bewegen und erneut starten -- **`&("/bin/sh")`**-> Parameter für `system` +- `&(nächstes falsches EBP)` -> Geladen durch `pop ebp/rbp` von `leave`. +- `&system()` -> Aufgerufen durch `ret`. +- `&(leave;ret)` -> Nachdem `system` endet, bewegt RSP zum nächsten falschen EBP und fährt fort. +- `&("/bin/sh")` -> Argument für `system`. -Grundsätzlich ist es auf diese Weise möglich, mehrere falsche EBPs zu verketten, um den Fluss des Programms zu kontrollieren. +Auf diese Weise ist es möglich, mehrere falsche EBPs zu verketten, um den Fluss des Programms zu kontrollieren. -Dies ist wie ein [ret2lib](../rop-return-oriented-programing/ret2lib/index.html), aber komplexer ohne offensichtlichen Vorteil, könnte aber in einigen Randfällen interessant sein. +Das ist wie ein [ret2lib](../rop-return-oriented-programing/ret2lib/index.html), aber komplexer und nur in Grenzfällen nützlich. -Darüber hinaus haben Sie hier ein [**Beispiel für eine Herausforderung**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave), die diese Technik mit einem **Stack-Leak** verwendet, um eine gewinnende Funktion aufzurufen. Dies ist die endgültige Payload von der Seite: +Darüber hinaus haben Sie hier ein [**Beispiel für eine Herausforderung**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave), das diese Technik mit einem **Stack-Leak** verwendet, um eine gewinnende Funktion aufzurufen. Dies ist die endgültige Payload von der Seite: ```python from pwn import * @@ -72,7 +76,7 @@ POP_RDI = 0x40122b POP_RSI_R15 = 0x401229 payload = flat( -0x0, # rbp (could be the address of anoter fake RBP) +0x0, # rbp (could be the address of another fake RBP) POP_RDI, 0xdeadbeef, POP_RSI_R15, @@ -81,23 +85,24 @@ POP_RSI_R15, elf.sym['winner'] ) -payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP) +payload = payload.ljust(96, b'A') # pad to 96 (reach saved RBP) payload += flat( -buffer, # Load leak address in RBP -LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it +buffer, # Load leaked address in RBP +LEAVE_RET # Use leave to move RSP to the user ROP chain and ret to execute it ) pause() p.sendline(payload) print(p.recvline()) ``` +> amd64 Alignment-Tipp: System V ABI erfordert eine 16-Byte-Stack-Ausrichtung an Aufrufstellen. Wenn Ihre Kette Funktionen wie `system` aufruft, fügen Sie ein Ausrichtungs-Gadget hinzu (z. B. `ret` oder `sub rsp, 8 ; ret`), bevor Sie den Aufruf tätigen, um die Ausrichtung aufrechtzuerhalten und `movaps`-Abstürze zu vermeiden. + ## EBP könnte nicht verwendet werden -Wie [**in diesem Beitrag erklärt**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), wenn ein Binary mit einigen Optimierungen kompiliert wird, hat **EBP niemals Kontrolle über ESP**, daher wird jeder Exploit, der durch Kontrolle von EBP funktioniert, im Grunde scheitern, weil er keinen echten Effekt hat.\ -Das liegt daran, dass sich die **Prolog- und Epilog-Änderungen** ändern, wenn das Binary optimiert ist. +Wie [**in diesem Beitrag erklärt**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), wenn ein Binärprogramm mit einigen Optimierungen oder mit Frame-Pointer-Auslassung kompiliert wird, **kontrolliert EBP/RBP niemals ESP/RSP**. Daher wird jeder Exploit, der durch die Kontrolle von EBP/RBP funktioniert, fehlschlagen, da das Prolog/Epilog nicht vom Frame-Pointer wiederherstellt. -- **Nicht optimiert:** +- Nicht optimiert / Frame-Pointer verwendet: ```bash push %ebp # save ebp mov %esp,%ebp # set new ebp @@ -108,22 +113,24 @@ sub $0x100,%esp # increase stack size leave # restore ebp (leave == mov %ebp, %esp; pop %ebp) ret # return ``` -- **Optimiert:** +- Optimiert / Frame-Zeiger weggelassen: ```bash -push %ebx # save ebx +push %ebx # save callee-saved register sub $0x100,%esp # increase stack size . . . add $0x10c,%esp # reduce stack size -pop %ebx # restore ebx +pop %ebx # restore ret # return ``` +Auf amd64 sieht man oft `pop rbp ; ret` anstelle von `leave ; ret`, aber wenn der Frame-Zeiger vollständig weggelassen wird, gibt es kein `rbp`-basiertes Epilog, durch das man pivotieren kann. + ## Andere Möglichkeiten, RSP zu steuern -### **`pop rsp`** Gadget +### `pop rsp` Gadget -[**Auf dieser Seite**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) finden Sie ein Beispiel, das diese Technik verwendet. Für diese Herausforderung war es notwendig, eine Funktion mit 2 spezifischen Argumenten aufzurufen, und es gab ein **`pop rsp` Gadget** und es gibt einen **leak vom Stack**: +[**Auf dieser Seite**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) finden Sie ein Beispiel, das diese Technik verwendet. Für diese Herausforderung war es notwendig, eine Funktion mit 2 spezifischen Argumenten aufzurufen, und es gab ein **`pop rsp` Gadget** und es gibt einen **Leak vom Stack**: ```python # Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp # This version has added comments @@ -167,7 +174,7 @@ pause() p.sendline(payload) print(p.recvline()) ``` -### xchg \, rsp Gadget +### xchg , rsp Gadget ``` pop <=== return pointer @@ -181,27 +188,74 @@ xchg , rsp ../rop-return-oriented-programing/ret2esp-ret2reg.md {{#endref}} -## Referenzen & Weitere Beispiele +### Pivot-Gadgets schnell finden -- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/) -- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting) -- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html) -- 64 Bit, Off-by-One-Exploitation mit einer ROP-Kette, die mit einem Ret-Sled beginnt -- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html) -- 64 Bit, kein RELRO, Canary, NX und PIE. Das Programm gewährt einen Leak für Stack oder PIE und ein WWW eines Qword. Zuerst den Stack-Leak erhalten und das WWW verwenden, um zurückzugehen und den PIE-Leak zu erhalten. Dann das WWW verwenden, um eine ewige Schleife zu erstellen, die `.fini_array`-Einträge missbraucht + `__libc_csu_fini` aufruft ([mehr Informationen hier](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Durch den Missbrauch dieses "ewigen" Schreibens wird eine ROP-Kette im .bss geschrieben und endet damit, dass sie mit RBP pivotiert wird. +Verwenden Sie Ihren bevorzugten Gadget-Finder, um nach klassischen Pivot-Primitiven zu suchen: + +- `leave ; ret` in Funktionen oder in Bibliotheken +- `pop rsp` / `xchg rax, rsp ; ret` +- `add rsp, ; ret` (oder `add esp, ; ret` auf x86) + +Beispiele: +```bash +# Ropper +ropper --file ./vuln --search "leave; ret" +ropper --file ./vuln --search "pop rsp" +ropper --file ./vuln --search "xchg rax, rsp ; ret" + +# ROPgadget +ROPgadget --binary ./vuln --only "leave|xchg|pop rsp|add rsp" +``` +### Klassisches Pivot-Staging-Muster + +Eine robuste Pivot-Strategie, die in vielen CTFs/Exploits verwendet wird: + +1) Verwenden Sie einen kleinen anfänglichen Overflow, um `read`/`recv` in einen großen beschreibbaren Bereich (z. B. `.bss`, Heap oder gemappeter RW-Speicher) zu rufen und dort eine vollständige ROP-Kette zu platzieren. +2) Kehren Sie in ein Pivot-Gadget zurück (`leave ; ret`, `pop rsp`, `xchg rax, rsp ; ret`), um RSP in diesen Bereich zu verschieben. +3) Fahren Sie mit der gestaffelten Kette fort (z. B. libc leaken, `mprotect` aufrufen, dann Shellcode lesen und dann zu ihm springen). + +## Moderne Abschwächungen, die Stack-Pivoting brechen (CET/Shadow Stack) + +Moderne x86-CPUs und Betriebssysteme setzen zunehmend **CET Shadow Stack (SHSTK)** ein. Mit aktiviertem SHSTK vergleicht `ret` die Rücksprungadresse auf dem normalen Stack mit einem hardwaregeschützten Shadow-Stack; jede Abweichung löst einen Control-Protection-Fehler aus und beendet den Prozess. Daher werden Techniken wie EBP2Ret/leave;ret-basierte Pivots abstürzen, sobald das erste `ret` von einem gepivotteten Stack ausgeführt wird. + +- Für Hintergrundinformationen und tiefere Details siehe: + +{{#ref}} +../common-binary-protections-and-bypasses/cet-and-shadow-stack.md +{{#endref}} + +- Schnelle Überprüfungen unter Linux: +```bash +# 1) Is the binary/toolchain CET-marked? +readelf -n ./binary | grep -E 'x86.*(SHSTK|IBT)' + +# 2) Is the CPU/kernel capable? +grep -E 'user_shstk|ibt' /proc/cpuinfo + +# 3) Is SHSTK active for this process? +grep -E 'x86_Thread_features' /proc/$$/status # expect: shstk (and possibly wrss) + +# 4) In pwndbg (gdb), checksec shows SHSTK/IBT flags +(gdb) checksec +``` +- Hinweise für Labs/CTF: +- Einige moderne Distributionen aktivieren SHSTK für CET-aktivierte Binärdateien, wenn Hardware- und glibc-Unterstützung vorhanden ist. Für kontrollierte Tests in VMs kann SHSTK systemweit über den Kernel-Bootparameter `nousershstk` deaktiviert oder selektiv über glibc-Tunables während des Starts aktiviert werden (siehe Referenzen). Deaktivieren Sie keine Mitigationen auf Produktionszielen. +- JOP/COOP oder SROP-basierte Techniken könnten auf einigen Zielen weiterhin möglich sein, aber SHSTK bricht speziell `ret`-basierte Pivots. + +- Windows-Hinweis: Windows 10+ exponiert den Benutzermodus und Windows 11 fügt den Kernelmodus „Hardware-enforced Stack Protection“ hinzu, der auf Shadow Stacks basiert. CET-kompatible Prozesse verhindern Stack-Pivoting/ROP bei `ret`; Entwickler optieren über CETCOMPAT und verwandte Richtlinien ein (siehe Referenz). ## ARM64 -In ARM64 speichern und rufen die **Prologe und Epiloge** der Funktionen **das SP-Register nicht im Stack** ab. Darüber hinaus gibt die **`RET`**-Anweisung nicht an die Adresse zurück, die von SP gezeigt wird, sondern **an die Adresse in `x30`**. +In ARM64 speichern die **Prologe und Epiloge** der Funktionen **nicht das SP-Register** im Stack und rufen es nicht ab. Darüber hinaus gibt die **`RET`**-Anweisung nicht die Adresse zurück, die von SP angezeigt wird, sondern **die Adresse in `x30`**. -Daher können Sie standardmäßig, nur durch den Missbrauch des Epilogs, **das SP-Register nicht kontrollieren**, indem Sie einige Daten im Stack überschreiben. Und selbst wenn Sie es schaffen, das SP zu kontrollieren, müssten Sie immer noch einen Weg finden, um **das `x30`**-Register zu kontrollieren. +Daher können Sie standardmäßig durch das Ausnutzen des Epilogs **das SP-Register nicht kontrollieren**, indem Sie einige Daten im Stack überschreiben. Und selbst wenn Sie es schaffen, das SP zu kontrollieren, benötigen Sie immer noch eine Möglichkeit, das **`x30`**-Register zu **kontrollieren**. - Prolog ```armasm sub sp, sp, 16 stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30 -mov x29, sp // FP zeigt auf den Frame-Record +mov x29, sp // FP zeigt auf den Frame-Datensatz ``` - Epilog @@ -213,12 +267,23 @@ ret ``` > [!CAUTION] -> Der Weg, um etwas Ähnliches wie Stack-Pivoting in ARM64 durchzuführen, wäre, in der Lage zu sein, **das `SP`** zu kontrollieren (indem man ein Register kontrolliert, dessen Wert an `SP` übergeben wird, oder weil aus irgendeinem Grund `SP` seine Adresse vom Stack bezieht und wir einen Overflow haben) und dann **den Epilog zu missbrauchen**, um das **`x30`**-Register von einem **kontrollierten `SP`** zu laden und **dann `RET`** darauf auszuführen. +> Der Weg, etwas Ähnliches wie Stack-Pivoting in ARM64 durchzuführen, wäre, in der Lage zu sein, **das `SP`** zu **kontrollieren** (indem man ein Register kontrolliert, dessen Wert an `SP` übergeben wird, oder weil aus irgendeinem Grund `SP` seine Adresse aus dem Stack bezieht und wir einen Überlauf haben) und dann **den Epilog auszunutzen**, um das **`x30`**-Register von einem **kontrollierten `SP`** zu laden und **`RET`** darauf auszuführen. -Auch auf der folgenden Seite können Sie das Äquivalent von **Ret2esp in ARM64** sehen: +Auch auf der folgenden Seite sehen Sie das Äquivalent von **Ret2esp in ARM64**: {{#ref}} ../rop-return-oriented-programing/ret2esp-ret2reg.md {{#endref}} +## Referenzen + +- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/) +- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting) +- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html) +- 64 Bits, Off-by-One-Ausnutzung mit einer ROP-Kette, die mit einem Ret-Sled beginnt +- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html) +- 64 Bit, kein relro, canary, nx und pie. Das Programm gewährt einen Leak für 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. Dann das WWW verwenden, um eine ewige Schleife zu erstellen, die `.fini_array`-Einträge ausnutzt + `__libc_csu_fini` aufruft ([mehr Informationen hier](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Durch das Ausnutzen dieses "ewigen" Schreibens wird eine ROP-Kette im .bss geschrieben und endet damit, dass sie mit RBP pivotiert wird. +- Linux-Kernel-Dokumentation: Control-flow Enforcement Technology (CET) Shadow Stack — Details zu SHSTK, `nousershstk`, `/proc/$PID/status`-Flags und Aktivierung über `arch_prctl`. https://www.kernel.org/doc/html/next/x86/shstk.html +- Microsoft Learn: Kernel Mode Hardware-enforced Stack Protection (CET Shadow Stacks auf Windows). https://learn.microsoft.com/en-us/windows-server/security/kernel-mode-hardware-stack-protection + {{#include ../../banners/hacktricks-training.md}}