63 lines
7.8 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.

# House of Force
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
### Code
- Ця техніка була виправлена ([**тут**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) і викликає цю помилку: `malloc(): corrupted top size`
- Ви можете спробувати [**код звідси**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html), щоб протестувати його, якщо хочете.
### Goal
- Метою цієї атаки є можливість виділити шматок пам'яті за певною адресою.
### Requirements
- Переповнення, яке дозволяє перезаписати розмір заголовка верхнього шматка (наприклад, -1).
- Можливість контролювати розмір виділення пам'яті
### Attack
Якщо зловмисник хоче виділити шматок пам'яті за адресою P, щоб перезаписати значення тут. Він починає з перезапису розміру верхнього шматка на `-1` (можливо, з переповненням). Це забезпечує, що malloc не буде використовувати mmap для будь-якого виділення, оскільки верхній шматок завжди матиме достатньо місця.
Потім обчисліть відстань між адресою верхнього шматка та цільовим простором для виділення. Це тому, що malloc з таким розміром буде виконано для переміщення верхнього шматка на цю позицію. Ось як різницю/розмір можна легко обчислити:
```c
// From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5
/*
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
* req = target - old_top - 4*sizeof(long)
*/
```
Отже, виділення розміру `target - old_top - 4*sizeof(long)` (4 long'и через метадані верхнього шматка та нового шматка при виділенні) перемістить верхній шматок до адреси, яку ми хочемо перезаписати.\
Потім виконайте ще один malloc, щоб отримати шматок за адресою цілі.
### Посилання та інші приклади
- [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file)
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/)
- [https://heap-exploitation.dhavalkapil.com/attacks/house_of_force](https://heap-exploitation.dhavalkapil.com/attacks/house_of_force)
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c)
- [https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html)
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11)
- Мета цього сценарію - ret2win, де нам потрібно змінити адресу функції, яка буде викликана адресою функції ret2win
- Бінарний файл має переповнення, яке можна використати для зміни розміру верхнього шматка, який змінюється на -1 або p64(0xffffffffffffffff)
- Потім обчислюється адреса місця, де існує вказівник для перезапису, і різниця від поточної позиції верхнього шматка до цього місця виділяється за допомогою `malloc`
- Нарешті, виділяється новий шматок, який міститиме цю бажану ціль, всередині якої перезаписується функція ret2win
- [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
- У `Input your name:` є початкова вразливість, яка дозволяє витікати адресу з купи
- Потім у функціональності `Org:` та `Host:` можливо заповнити 64B вказівника `s`, коли запитують **назву організації**, яка в стеку слідує за адресою v2, яка потім слідує за вказаною **назвою хоста**. Оскільки потім strcpy буде копіювати вміст s в шматок розміром 64B, можливо **перезаписати розмір верхнього шматка** даними, вставленими в **назву хоста**.
- Тепер, коли можливе довільне записування, GOT `atoi` було перезаписано на адресу printf. Потім стало можливим витікати адресу `IO_2_1_stderr` _з_ `%24$p`. І з цим витоком libc стало можливим знову перезаписати GOT `atoi` адресою `system` і викликати його, передавши як параметр `/bin/sh`
- Альтернативний метод [пропонований у цьому іншому описі](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud) полягає в перезаписуванні `free` на `puts`, а потім додаванні адреси `atoi@got` у вказівник, який пізніше буде звільнений, щоб він був витік і з цим витоком знову перезаписати `atoi@got` на `system` і викликати його з `/bin/sh`.
- [https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html)
- Існує UAF, що дозволяє повторно використовувати шматок, який був звільнений без очищення вказівника. Оскільки є деякі методи читання, можливо витікати адресу libc, записуючи вказівник на функцію free в GOT тут, а потім викликаючи функцію читання.
- Потім House of force було використано (зловживаючи UAF), щоб перезаписати розмір лівого простору на -1, виділити шматок достатнього розміру, щоб дістатися до free hook, а потім виділити ще один шматок, який міститиме free hook. Потім запишіть у hook адресу `system`, запишіть у шматок `"/bin/sh"` і нарешті звільніть шматок з вмістом цього рядка.
{{#include ../../banners/hacktricks-training.md}}