First Fit

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

Перший Підбір

Коли ви вивільняєте пам'ять у програмі, використовуючи glibc, для керування фрагментами пам'яті використовуються різні "біни". Ось спрощене пояснення двох загальних сценаріїв: неупорядковані біни та швидкі біни.

Неупорядковані Біни

Коли ви вивільняєте фрагмент пам'яті, який не є швидким фрагментом, він потрапляє до неупорядкованого біна. Цей бін діє як список, куди нові вивільнені фрагменти додаються до передньої частини («голови»). Коли ви запитуєте новий фрагмент пам'яті, алокатор дивиться на неупорядкований бін з кінця («хвоста»), щоб знайти фрагмент, який достатньо великий. Якщо фрагмент з неупорядкованого біна більший, ніж вам потрібно, він розбивається, з передньою частиною, яка повертається, а решта залишається в біні.

Приклад:

  • Ви виділяєте 300 байтів (a), потім 250 байтів (b), вивільняєте a і знову запитуєте 250 байтів (c).

  • Коли ви вивільняєте a, він потрапляє до неупорядкованого біна.

  • Якщо потім ви знову запитуєте 250 байтів, алокатор знаходить a на хвості і розбиває його, повертаючи частину, яка відповідає вашому запиту, і залишаючи решту в біні.

  • c буде посилатися на попередній a і заповнений a.

char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);

Fastbins

Fastbins використовуються для невеликих фрагментів пам'яті. На відміну від несортованих блоків, fastbins додають нові фрагменти в голову, створюючи поведінку "останнім прийшов - першим вийшов" (LIFO). Якщо ви запитуєте невеликий фрагмент пам'яті, алокатор витягне його з голови fastbin.

Приклад:

  • Ви виділяєте чотири фрагменти по 20 байт кожен (a, b, c, d).

  • Коли ви вивільняєте їх у будь-якому порядку, вивільнені фрагменти додаються до голови fastbin.

  • Якщо ви потім запитуєте фрагмент 20 байт, алокатор поверне найбільш недавно вивільнений фрагмент з голови fastbin.

char *a = malloc(20);
char *b = malloc(20);
char *c = malloc(20);
char *d = malloc(20);
free(a);
free(b);
free(c);
free(d);
a = malloc(20);   // d
b = malloc(20);   // c
c = malloc(20);   // b
d = malloc(20);   // a

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

  • ARM64. Використання після вивільнення: Створення об'єкту користувача, вивільнення його, створення об'єкту, який отримує вивільнений чанк і дозволяє записувати в нього, перезаписуючи позицію пароля користувача з попереднього. Повторне використання користувача для обхід перевірки пароля

  • Програма дозволяє створювати нотатки. Нотатка матиме інформацію про нотатку в malloc(8) (з посиланням на функцію, яку можна викликати) та посилання на інший malloc(<size>) з вмістом нотатки.

  • Атака полягатиме в створенні 2 нотаток (note0 та note1) з більшим вмістом malloc, ніж розмір інформації про нотатку, а потім вивільнення їх, щоб вони потрапили в швидкий бін (або tcache).

  • Потім створіть іншу нотатку (note2) з розміром вмісту 8. Вміст буде в нотатці 1, оскільки чанк буде повторно використаний, де ми можемо змінити вказівник на функцію, щоб вказував на функцію перемоги, а потім використовувати після вивільнення note1, щоб викликати новий вказівник на функцію.

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

  • У цьому випадку потрібно записати 4 всередині конкретного чанку, який є першим, що виділяється (навіть після примусового вивільнення всіх них). При кожному новому виділеному чанку його номер у масиві зберігається. Потім виділіть 4 чанки (+ початково виділений), останній матиме всередині себе 4, вивільніть їх і примусово виділіть знову перший, який використає останній вивільнений чанк, який має всередині себе 4.

Last updated