76 lines
11 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 Orange
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
### Code
- Знайдіть приклад у [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c)
- Техніка експлуатації була виправлена в цьому [патчі](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0), тому це більше не працює (працює в версіях раніше 2.26)
- Той же приклад **з більшою кількістю коментарів** у [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
### Goal
- Зловживати функцією `malloc_printerr`
### Requirements
- Перезаписати розмір верхнього блоку
- Витоки libc та heap
### Background
Деяка необхідна інформація з коментарів з [**цього прикладу**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**
Справа в тому, що в старіших версіях libc, коли викликалася функція `malloc_printerr`, вона **перебирала список структур `_IO_FILE`, що зберігаються в `_IO_list_all`**, і фактично **виконувала** вказівник інструкції в цій структурі.\
Ця атака підробить **фальшиву структуру `_IO_FILE`**, яку ми запишемо в **`_IO_list_all`**, і змусить `malloc_printerr` запуститися.\
Тоді вона **виконає будь-яку адресу**, яку ми зберегли в таблиці стрибків структур **`_IO_FILE`**, і ми отримаємо виконання коду.
### Attack
Атака починається з того, що вдається отримати **верхній блок** всередині **несортованого контейнера**. Це досягається шляхом виклику `malloc` з розміром, більшим за поточний розмір верхнього блоку, але меншим за **`mmp_.mmap_threshold`** (за замовчуванням 128K), що в іншому випадку викликало б виділення `mmap`. Коли розмір верхнього блоку змінюється, важливо переконатися, що **верхній блок + його розмір** вирівняні по сторінках і що біт **prev_inuse** верхнього блоку завжди встановлений.
Щоб отримати верхній блок всередині несортованого контейнера, виділіть блок, щоб створити верхній блок, змініть розмір верхнього блоку (з переповненням у виділеному блоці), щоб **верхній блок + розмір** був вирівняний по сторінках з встановленим бітом **prev_inuse**. Потім виділіть блок, більший за новий розмір верхнього блоку. Зверніть увагу, що `free` ніколи не викликається, щоб отримати верхній блок у несортований контейнер.
Старий верхній блок тепер у несортованому контейнері. Припускаючи, що ми можемо читати дані всередині нього (можливо, через вразливість, яка також викликала переповнення), можливо витягти адреси libc з нього та отримати адресу **\_IO_list_all**.
Атака на несортований контейнер виконується шляхом зловживання переповненням, щоб записати `topChunk->bk->fwd = _IO_list_all - 0x10`. Коли виділяється новий блок, старий верхній блок буде розділений, і вказівник на несортований контейнер буде записаний у **`_IO_list_all`**.
Наступний крок полягає в зменшенні розміру старого верхнього блоку, щоб він помістився в малий контейнер, зокрема, встановивши його розмір на **0x61**. Це має дві мети:
1. **Вставка в Малий Контейнер 4**: Коли `malloc` сканує несортований контейнер і бачить цей блок, він спробує вставити його в малий контейнер 4 через його малий розмір. Це призводить до того, що блок опиняється на початку списку малого контейнера 4, що є місцем для вказівника FD блоку **`_IO_list_all`**, оскільки ми записали близьку адресу в **`_IO_list_all`** через атаку на несортований контейнер.
2. **Виклик Перевірки Malloc**: Ця маніпуляція з розміром блоку призведе до того, що `malloc` виконає внутрішні перевірки. Коли він перевіряє розмір фальшивого блоку вперед, який буде нульовим, це викликає помилку і викликає `malloc_printerr`.
Маніпуляція з малим контейнером дозволить вам контролювати вказівник вперед блоку. Перекриття з **\_IO_list_all** використовується для підробки фальшивої структури **\_IO_FILE**. Структура ретельно розроблена, щоб включати ключові поля, такі як `_IO_write_base` і `_IO_write_ptr`, встановлені на значення, які проходять внутрішні перевірки в libc. Крім того, в фальшивій структурі створюється таблиця стрибків, де вказівник інструкції встановлюється на адресу, де може бути виконаний довільний код (наприклад, функція `system`).
Щоб підсумувати залишок техніки:
- **Зменшити Старий Верхній Блок**: Відрегулюйте розмір старого верхнього блоку на **0x61**, щоб помістити його в малий контейнер.
- **Налаштувати Фальшиву Структуру `_IO_FILE`**: Перекрийте старий верхній блок з фальшивою структурою **\_IO_FILE** та налаштуйте поля відповідно, щоб захопити потік виконання.
Наступний крок полягає в підробці фальшивої структури **\_IO_FILE**, яка перекриває старий верхній блок, що наразі знаходиться в несортованому контейнері. Перші байти цієї структури ретельно розроблені, щоб включати вказівник на команду (наприклад, "/bin/sh"), яка буде виконана.
Ключові поля у фальшивій структурі **\_IO_FILE**, такі як `_IO_write_base` і `_IO_write_ptr`, встановлені на значення, які проходять внутрішні перевірки в libc. Крім того, в фальшивій структурі створюється таблиця стрибків, де вказівник інструкції встановлюється на адресу, де може бути виконаний довільний код. Зазвичай це буде адреса функції `system` або іншої функції, яка може виконувати команди оболонки.
Атака завершується, коли виклик `malloc` викликає виконання коду через маніпульовану структуру **\_IO_FILE**. Це ефективно дозволяє виконання довільного коду, зазвичай призводячи до появи оболонки або виконання іншого шкідливого корисного навантаження.
**Підсумок Атаки:**
1. **Налаштуйте верхній блок**: Виділіть блок і змініть розмір верхнього блоку.
2. **Примусьте верхній блок у несортований контейнер**: Виділіть більший блок.
3. **Витягніть адреси libc**: Використовуйте вразливість, щоб читати з несортованого контейнера.
4. **Виконайте атаку на несортований контейнер**: Запишіть у **\_IO_list_all** за допомогою переповнення.
5. **Зменшіть старий верхній блок**: Відрегулюйте його розмір, щоб помістити в малий контейнер.
6. **Налаштуйте фальшиву структуру \_IO_FILE**: Підробіть фальшиву структуру файлу, щоб захопити потік виконання.
7. **Викличте виконання коду**: Виділіть блок, щоб виконати атаку та запустити довільний код.
Цей підхід експлуатує механізми управління купою, витоки інформації libc та переповнення купи, щоб досягти виконання коду без прямого виклику `free`. Ретельно підробляючи фальшиву структуру **\_IO_FILE** та розміщуючи її в правильному місці, атака може захопити потік виконання під час стандартних операцій виділення пам'яті. Це дозволяє виконання довільного коду, що потенційно призводить до появи оболонки або інших шкідливих дій.
## References
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
- [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
{{#include ../../banners/hacktricks-training.md}}