# 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}}