Off by one overflow

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

Основна інформація

Маючи доступ лише до переповнення на 1 байт, зловмиснику дозволяється змінювати поле size наступного чанка. Це дозволяє впливати на те, які чанки фактично звільняються, що потенційно може призвести до створення чанку, який містить інший легітимний чанк. Експлуатація схожа на подвійне звільнення або перекривання чанків.

Існують 2 типи вразливостей на один байт:

  • Довільний байт: Цей тип дозволяє перезаписати цей байт будь-яким значенням

  • Нульовий байт (off-by-null): Цей тип дозволяє перезаписати цей байт лише значенням 0x00

  • Загальним прикладом цієї вразливості може бути код, де поведінка strlen та strcpy неузгоджена, що дозволяє встановити байт 0x00 в початку наступного чанка.

  • Це можна експлуатувати за допомогою House of Einherjar.

  • Якщо використовується Tcache, це може бути використано для ситуації подвійного звільнення.

Off-by-null

```c // From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/ int main(void) { char buffer[40]=""; void *chunk1; chunk1 = malloc(24); puts("Get Input"); gets(buffer); if(strlen(buffer)==24) { strcpy(chunk1,buffer); } return 0; } ```

Серед інших перевірок, тепер, коли блок вільний, попередній розмір порівнюється з розміром, налаштованим у метаданих блоку, що робить цей атаку досить складним з версії 2.28.

Приклад коду:

Мета

  • Зробити так, щоб блок був вміщений всередині іншого блоку, так що доступ до запису в цей другий блок дозволяє перезаписати вміщений.

Вимоги

  • Переповнення на один байт, щоб змінити інформацію метаданих про розмір

Загальна атака off-by-one

  • Виділіть три блоки A, B та C (скажімо, розміри 0x20), а також ще один, щоб уникнути консолідації з верхнім блоком.

  • Звільніть C (вставлено у список вільних блоків Tcache 0x20).

  • Використовуйте блок A для переповнення на B. Зловживання off-by-one для зміни поля size B з 0x21 на 0x41.

  • Тепер у нас є B, що містить вільний блок C

  • Звільніть B та виділіть блок 0x40 (він буде розміщений тут знову)

  • Ми можемо змінити вказівник fd з C, який все ще вільний (забруднення Tcache)

Атака off-by-null

  • Зарезервовано 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.

Last updated