House of Force

Підтримайте HackTricks

Базова інформація

Код

  • Цю техніку виправлено (тут) і вона викликає помилку: malloc(): corrupted top size

  • Ви можете спробувати код звідси, щоб протестувати його, якщо хочете.

Мета

  • Метою цього нападу є можливість виділити фрагмент пам'яті за конкретною адресою.

Вимоги

  • Переповнення, яке дозволяє перезаписати розмір заголовка верхнього фрагмента (наприклад, -1).

  • Можливість контролювати розмір виділення купи.

Напад

Якщо зловмисник хоче виділити фрагмент пам'яті за адресою P, щоб перезаписати значення тут. Він починає з перезапису розміру верхнього фрагмента значенням -1 (можливо, з переповненням). Це гарантує, що malloc не буде використовувати mmap для будь-якого виділення, оскільки верхній фрагмент завжди матиме достатньо місця.

Потім розраховується відстань між адресою верхнього фрагмента та цільовим простором для виділення. Це тому, що malloc з таким розміром буде виконано для переміщення верхнього фрагмента на цю позицію. Ось як можна легко розрахувати різницю/розмір:

// 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)
*/

Отже, виділення розміру ціль - old_top - 4*sizeof(long) (4 long через метадані верхнього фрагмента та нового фрагмента при виділенні) перемістить верхній фрагмент на адресу, яку ми хочемо перезаписати. Потім знову виконайте malloc, щоб отримати фрагмент за цільовою адресою.

Посилання та Інші Приклади

  • Мета цього сценарію - ret2win, де потрібно змінити адресу функції, яка буде викликана адресою функції ret2win

  • У бінарному файлі є переповнення, яке можна використовувати для зміни розміру верхнього фрагмента, який змінено на -1 або p64(0xffffffffffffffff)

  • Потім обчислюється адреса місця, де існує вказівник для перезапису, і різниця від поточного положення верхнього фрагмента до туди виділяється за допомогою malloc

  • Нарешті, виділяється новий фрагмент, який буде містити цю бажану ціль всередині, яка перезаписується функцією ret2win

  • У 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

  • Альтернативний метод запропонований у цьому іншому описі, полягає в перезаписі free на puts, а потім додаванні адреси atoi@got, в вказівник, який потім буде звільнений, щоб витікав і з цим витоком знову перезаписати atoi@got на system і викликати його з /bin/sh.

  • Є UAF, що дозволяє повторно використовувати фрагмент, який був звільнений без очищення вказівника. Оскільки є деякі методи читання, можливо витікати адресу libc, записуючи вказівник на функцію free в GOT тут, а потім викликаючи функцію читання.

  • Потім було використано House of force (з використанням UAF) для перезапису розміру лівого простору на -1, виділення достатньо великого фрагмента для досягнення free hook, а потім виділення іншого фрагмента, який буде містити free hook. Потім записати в гачок адресу system, записати в фрагмент "/bin/sh" і, нарешті, звільнити фрагмент з цим вмістом рядка.

Last updated