Off by one overflow
Last updated
Last updated
Вивчайте та практикуйте хакінг AWS: Навчання AWS Red Team Expert (ARTE) від HackTricks Вивчайте та практикуйте хакінг GCP: Навчання GCP Red Team Expert (GRTE) від HackTricks
Маючи доступ лише до переповнення на 1 байт, зловмиснику дозволяється змінювати поле size
наступного чанка. Це дозволяє впливати на те, які чанки фактично звільняються, що потенційно може призвести до створення чанку, який містить інший легітимний чанк. Експлуатація схожа на подвійне звільнення або перекривання чанків.
Існують 2 типи вразливостей на один байт:
Довільний байт: Цей тип дозволяє перезаписати цей байт будь-яким значенням
Нульовий байт (off-by-null): Цей тип дозволяє перезаписати цей байт лише значенням 0x00
Загальним прикладом цієї вразливості може бути код, де поведінка strlen
та strcpy
неузгоджена, що дозволяє встановити байт 0x00 в початку наступного чанка.
Це можна експлуатувати за допомогою House of Einherjar.
Якщо використовується Tcache, це може бути використано для ситуації подвійного звільнення.
Серед інших перевірок, тепер, коли блок вільний, попередній розмір порівнюється з розміром, налаштованим у метаданих блоку, що робить цей атаку досить складним з версії 2.28.
Ця атака більше не працює через використання Tcaches.
Більше того, якщо ви спробуєте зловживати цим, використовуючи більші блоки (так що tcaches не задіяні), ви отримаєте помилку: malloc(): invalid next size (unsorted)
Зробити так, щоб блок був вміщений всередині іншого блоку, так що доступ до запису в цей другий блок дозволяє перезаписати вміщений.
Переповнення на один байт, щоб змінити інформацію метаданих про розмір
Виділіть три блоки A
, B
та C
(скажімо, розміри 0x20), а також ще один, щоб уникнути консолідації з верхнім блоком.
Звільніть C
(вставлено у список вільних блоків Tcache 0x20).
Використовуйте блок A
для переповнення на B
. Зловживання off-by-one для зміни поля size
B
з 0x21 на 0x41.
Тепер у нас є B
, що містить вільний блок C
Звільніть B
та виділіть блок 0x40 (він буде розміщений тут знову)
Ми можемо змінити вказівник fd
з C
, який все ще вільний (забруднення Tcache)
Зарезервовано 3 блоки пам'яті (a, b, c) один після одного. Потім середній з них звільнюється. Перший містить вразливість на переповнення на один байт, і зловмисник зловживає нею з 0x00 (якщо попередній байт був 0x10, це зробить середній блок вказувати, що він на 0x10 менший, ніж він є насправді).
Потім, в середині вільного блоку (b) виділяються ще 2 менших блоки, однак, оскільки b + b->size
ніколи не оновлює блок c, оскільки вказана адреса менша, ніж повинна бути.
Потім b1 та c звільнені. Оскільки c - c->prev_size
все ще вказує на b (тепер b1), обидва об'єднуються в один блок. Однак b2 все ще знаходиться всередині між b1 та c.
Нарешті, виконується новий malloc, що повертає цю область пам'яті, яка фактично буде містити b2, дозволяючи власнику нового malloc контролювати вміст b2.
Ця картинка ідеально пояснює атаку:
Off-by-one через strlen
, який враховує поле size
наступного блоку.
Використовується Tcache, тому загальні атаки off-by-one працюють для отримання довільного запису зі забрудненням Tcache.
Можливо зловживати off-by-one, щоб витікати адресу з купи, оскільки байт 0x00 в кінці рядка перезаписується наступним полем.
Довільний запис отримується зловживанням off-by-one запису, щоб зробити вказівник вказувати на інше місце, де буде побудовано фейкову структуру з фейковими вказівниками. Потім можна слідувати вказівнику цієї структури, щоб отримати довільний запис.
Адреса libc витікається, оскільки якщо купа розширюється за допомогою mmap, пам'ять, виділена mmap, має фіксований зсув від libc.
Нарешті, зловживання довільним записом використовується для запису в адресу __free_hook за допомогою одного гаджета.
Є вразливість NULL off-by-one в функції getline
, яка читає рядки введення користувача. Ця функція використовується для читання "ключа" вмісту, а не вмісту.
Поширюйте хакерські трюки, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.