Off by one overflow

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support 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 overflow для зміни інформації про метадані розміру.

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

  • Виділити три шматки A, B і C (скажімо, розміри 0x20), і ще один, щоб запобігти консолідації з top-chunk.

  • Вивільнити C (вставлений у 0x20 Tcache free-list).

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

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

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

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

Атака off-by-null

  • 3 шматки пам'яті (a, b, c) резервуються один за одним. Потім середній шматок звільняється. Перший шматок містить уразливість off by one overflow, і зловмисник зловживає нею з 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, яка читає рядки введення користувача. Ця функція використовується для читання "ключа" вмісту, а не самого вмісту.

  • У звіті створюється 5 початкових шматків:

  • chunk1 (0x200)

  • chunk2 (0x50)

  • chunk5 (0x68)

  • chunk3 (0x1f8)

  • chunk4 (0xf0)

  • chunk defense (0x400), щоб уникнути консолідації з top chunk.

  • Потім шматки 1, 5 і 3 звільняються, тому:

[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]

* Потім, зловживаючи chunk3 (0x1f8), зловживають null off-by-one, записуючи prev\_size в `0x4e0`.
* Зверніть увагу, що розміри початково виділених шматків 1, 2, 5 і 3 плюс заголовки 4 з цих шматків дорівнюють `0x4e0`:  `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
* Потім шматок 4 звільняється, генеруючи шматок, що споживає всі шматки до початку:
* ```python
[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ]

[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]

* Потім виділяється `0x200` байтів, заповнюючи оригінальний шматок 1.
* І ще один 0x200 байтів виділяється, і chunk2 знищується, і тому немає ніякого витоку, і це не працює? Можливо, це не слід робити.
* Потім виділяється ще один шматок з 0x58 "a"s (перезаписуючи chunk2 і досягаючи chunk5) і змінює `fd` швидкого бін-шматка chunk5, вказуючи на `__malloc_hook`.
* Потім виділяється шматок 0x68, тому фейковий швидкий бін-шматок у `__malloc_hook` є наступним швидким бін-шматком.
* Нарешті, виділяється новий швидкий бін-шматок 0x68, і `__malloc_hook` перезаписується адресою `one_gadget`.

<div data-gb-custom-block data-tag="hint" data-style='success'>

Вивчайте та практикуйте AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Вивчайте та практикуйте GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Підтримати HackTricks</summary>

* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв GitHub.

</details>

</div>

Last updated