Unsorted Bin Attack

Reading time: 7 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

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

Basic Information

Для отримання додаткової інформації про те, що таке unsorted bin, перегляньте цю сторінку:

Bins & Memory Allocations

Unsorted lists можуть записувати адресу в unsorted_chunks (av) у адресі bk частини. Тому, якщо зловмисник може модифікувати адресу вказівника bk у частині всередині unsorted bin, він може записати цю адресу в довільну адресу, що може бути корисним для витоку адрес Glibc або обходу деяких захистів.

Отже, в основному, ця атака дозволяє встановити велике число за довільною адресою. Це велике число є адресою, яка може бути адресою купи або адресою Glibc. Типовою мішенню є global_max_fast, щоб дозволити створювати fast bin з більшими розмірами (і перейти з атаки unsorted bin до атаки fast bin).

tip

T> акіть на приклад, наведений у https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle, і використовуючи 0x4000 і 0x5000 замість 0x400 і 0x500 як розміри частин (щоб уникнути Tcache), можна побачити, що сьогодні помилка malloc(): unsorted double linked list corrupted викликається.

Отже, ця атака unsorted bin тепер (серед інших перевірок) також вимагає можливості виправити подвійну зв'язку, щоб це було обійдено victim->bk->fd == victim або не victim->fd == av (arena), що означає, що адреса, куди ми хочемо записати, повинна мати адресу фальшивої частини в її позиції fd, а фальшива частина fd вказує на арену.

caution

Зверніть увагу, що ця атака пошкоджує unsorted bin (отже, маленькі та великі також). Тому ми можемо лише використовувати алокації з fast bin зараз (більш складна програма може виконувати інші алокації та аварійно завершитися), і для цього ми повинні алокувати той же розмір, інакше програма аварійно завершиться.

Зверніть увагу, що перезапис global_max_fast може допомогти в цьому випадку, довіряючи, що fast bin зможе впоратися з усіма іншими алокаціями, поки експлуатація не буде завершена.

Код від guyinatuxedo пояснює це дуже добре, хоча якщо ви модифікуєте malloc для алокації пам'яті достатнього розміру, щоб не закінчити в Tcache, ви можете побачити, що раніше згадана помилка з'являється, запобігаючи цій техніці: malloc(): unsorted double linked list corrupted

Unsorted Bin Infoleak Attack

Це насправді дуже базова концепція. Частини в unsorted bin будуть мати вказівники. Перша частина в unsorted bin насправді буде мати fd та bk посилання вказуючи на частину основної арени (Glibc).
Отже, якщо ви можете помістити частину всередину unsorted bin і прочитати її (використання після звільнення) або знову алокувати її, не перезаписуючи принаймні 1 з вказівників, щоб потім прочитати її, ви можете отримати витік інформації Glibc.

Схожа атака, використана в цьому описі, полягала в зловживанні структурою з 4 частин (A, B, C та D - D лише для запобігання консолідації з верхньою частиною), тому для переповнення нульовим байтом у B було використано, щоб зробити C вказувати, що B не використовується. Також у B дані prev_size були модифіковані, тому розмір замість розміру B був A+B.
Потім C було звільнено і консолідовано з A+B (але B все ще використовувалася). Була алокована нова частина розміру A, а потім адреси, витіковані з libc, були записані в B, звідки вони були витіковані.

References & Other examples

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • Мета полягає в тому, щоб перезаписати глобальну змінну значенням, більшим за 4869, щоб отримати прапор, і PIE не увімкнено.
  • Можливо генерувати частини довільних розмірів, і є переповнення купи з бажаним розміром.
  • Атака починається зі створення 3 частин: chunk0 для зловживання переповненням, chunk1 для переповнення та chunk2, щоб верхня частина не консолідувала попередні.
  • Потім chunk1 звільняється, і chunk0 переповнюється, щоб вказівник bk частини 1 вказував на: bk = magic - 0x10
  • Потім chunk3 алокуються з таким же розміром, як chunk1, що викликає атаку unsorted bin і змінює значення глобальної змінної, що робить можливим отримання прапора.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • Функція злиття вразлива, оскільки якщо обидва передані індекси однакові, вона перерозподілить їх і потім звільнить, але повертаючи вказівник на цю звільнену область, яку можна використовувати.
  • Отже, створюються 2 частини: chunk0, яка буде злитою сама з собою, і chunk1, щоб запобігти консолідації з верхньою частиною. Потім функція злиття викликається з chunk0 двічі, що викличе використання після звільнення.
  • Потім функція view викликається з індексом 2 (який є індексом частини, що використовується після звільнення), що викликатиме витік адреси libc.
  • Оскільки бінарний файл має захисти, щоб лише malloc розміри більші за global_max_fast, тому жоден fastbin не використовується, буде використана атака unsorted bin для перезапису глобальної змінної global_max_fast.
  • Потім можливо викликати функцію редагування з індексом 2 (вказівник, що використовується після звільнення) і перезаписати вказівник bk, щоб вказувати на p64(global_max_fast-0x10). Потім, створення нової частини використає раніше скомпрометовану адресу (0x20), що викличе атаку unsorted bin, перезаписуючи global_max_fast, що є дуже великим значенням, що дозволяє тепер створювати частини в fast bins.
  • Тепер виконується атака fast bin:
  • Перш за все, виявлено, що можливо працювати з fast частинами розміру 200 в місці __free_hook:
  • gef➤  p &__free_hook
    

$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000

  • Якщо нам вдасться отримати fast chunk розміру 0x200 у цьому місці, буде можливим перезаписати вказівник функції, яка буде виконана.
  • Для цього створюється нова частина розміру 0xfc, і функція злиття викликається з цим вказівником двічі, таким чином ми отримуємо вказівник на звільнену частину розміру 0xfc*2 = 0x1f8 у fast bin.
  • Потім функція редагування викликається в цій частині, щоб змінити адресу fd цього fast bin, щоб вказувати на попередню функцію __free_hook.
  • Потім створюється частина розміру 0x1f8, щоб отримати з fast bin попередню непотрібну частину, тому створюється ще одна частина розміру 0x1f8, щоб отримати fast bin chunk у __free_hook, який перезаписується адресою функції system.
  • І нарешті, частина, що містить рядок /bin/sh\x00, звільняється, викликаючи функцію видалення, що викликає функцію __free_hook, яка вказує на system з /bin/sh\x00 як параметром.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Ще один приклад зловживання переповненням на 1B для консолідації частин в unsorted bin і отримання витоку інформації libc, а потім виконання атаки fast bin для перезапису malloc hook з адресою одного гаджета.
  • Robot Factory. BlackHat MEA CTF 2022
  • Ми можемо алокувати лише частини розміру більше 0x100.
  • Перезаписати global_max_fast, використовуючи атаку Unsorted Bin (працює 1/16 разів через ASLR, оскільки нам потрібно модифікувати 12 біт, але ми повинні модифікувати 16 біт).
  • Атака Fast Bin для модифікації глобального масиву частин. Це дає примітив довільного читання/запису, що дозволяє модифікувати GOT і вказувати деяку функцію на system.

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

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