Heap Overflow
Reading time: 5 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Basic Information
Переповнення купи - це як переповнення стеку, але в купі. В основному це означає, що деякий простір було зарезервовано в купі для зберігання деяких даних, і збережені дані були більшими за зарезервований простір.
У випадку переповнень стеку ми знаємо, що деякі регістри, такі як вказівник інструкцій або стековий фрейм, будуть відновлені зі стеку, і це може бути можливим для зловживання. У випадку переповнень купи немає жодної чутливої інформації, що зберігається за замовчуванням в купі, яка може бути переповнена. Однак це можуть бути чутливі дані або вказівники, тому критичність цієї вразливості залежить від того, які дані можуть бути перезаписані і як зловмисник може цим зловживатися.
tip
Щоб знайти зсуви переповнення, ви можете використовувати ті ж шаблони, що й у переповненнях стеку.
Stack Overflows vs Heap Overflows
У переповненнях стеку розташування та дані, які будуть присутні в стеку в момент, коли вразливість може бути активована, є досить надійними. Це пов'язано з тим, що стек є лінійним, завжди зростаючим у зіткненні пам'яті, у конкретних місцях виконання програми стекова пам'ять зазвичай зберігає подібні дані і має певну структуру з деякими вказівниками в кінці частини стеку, що використовується кожною функцією.
Однак у випадку переповнення купи використовувана пам'ять не є лінійною, а використовувані шматки зазвичай знаходяться в окремих позиціях пам'яті (не один біля одного) через контейнери та зони, які розділяють алокації за розміром, і через те, що попередньо звільнена пам'ять використовується перед алокацією нових шматків. Це складно знати об'єкт, який буде зіткненням з вразливим до переповнення купи. Тому, коли виявляється переповнення купи, потрібно знайти надійний спосіб зробити так, щоб бажаний об'єкт був наступним у пам'яті після того, що може бути переповнене.
Одна з технік, що використовуються для цього, - це Heap Grooming, яка використовується, наприклад, в цьому пості. У пості пояснюється, як у ядрі iOS, коли зона вичерпується пам'яттю для зберігання шматків пам'яті, вона розширюється на сторінку ядра, і ця сторінка ділиться на шматки очікуваних розмірів, які будуть використовуватися в порядку (до версії iOS 9.2, потім ці шматки використовуються випадковим чином, щоб ускладнити експлуатацію цих атак).
Отже, у попередньому пості, де відбувається переповнення купи, щоб змусити переповнений об'єкт зіткнутися з об'єктом жертви, кілька kallocs
примушуються кількома потоками, щоб спробувати забезпечити заповненість усіх вільних шматків і створити нову сторінку.
Щоб примусити це заповнення об'єктами певного розміру, алокація поза лінією, пов'язана з iOS mach port, є ідеальним кандидатом. Шляхом формування розміру повідомлення можна точно вказати розмір алокації kalloc
, і коли відповідний mach port знищується, відповідна алокація буде негайно звільнена назад до kfree
.
Тоді деякі з цих заповнювачів можуть бути звільнені. Список вільних kalloc.4096
звільняє елементи в порядку останній прийшов - перший пішов, що в основному означає, що якщо деякі заповнювачі звільнені, і експлойт намагається алокувати кілька об'єктів жертви, намагаючись алокувати об'єкт, вразливий до переповнення, ймовірно, що цей об'єкт буде слідувати за об'єктом жертви.
Example libc
На цій сторінці можна знайти базову емуляцію переповнення купи, яка показує, як перезаписуючи біт prev in use наступного шматка та позицію prev size, можна консолідувати використаний шматок (змушуючи його думати, що він не використовується) і потім знову алокувати його, маючи можливість перезаписати дані, які використовуються в іншому вказівнику.
Ще один приклад з protostar heap 0 показує дуже базовий приклад CTF, де переповнення купи може бути використано для виклику функції переможця, щоб отримати прапор.
У прикладі protostar heap 1 можна побачити, як зловживаючи переповненням буфера, можна перезаписати в сусідньому шматку адресу, куди будуть записані довільні дані від користувача.
Example ARM64
На сторінці https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ ви можете знайти приклад переповнення купи, де команда, яка буде виконана, зберігається в наступному шматку від переповненого шматка. Таким чином, можна змінити виконувану команду, перезаписавши її простим експлойтом, таким як:
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Інші приклади
- Auth-or-out. Hack The Box
- Ми використовуємо вразливість цілочисельного переповнення, щоб отримати переповнення купи.
- Ми корумпуємо вказівники на функцію всередині
struct
переповненого блоку, щоб встановити функцію, таку якsystem
, і отримати виконання коду.
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.