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