House of Roman
Основна інформація
Це була дуже цікава техніка, яка дозволяла виконати RCE без витоку інформації через фейкові fastbins, атаку на unsorted_bin та відносні перезаписи. Однак це було виправлено.
Код
Приклад можна знайти за посиланням https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Мета
RCE шляхом зловживання відносними вказівниками
Вимоги
Редагування вказівників fastbin та unsorted bin
Потрібно перебрати 12 бітів випадковості (шанс 0,02%), щоб все працювало
Кроки атаки
Частина 1: Fastbin Chunk вказує на __malloc_hook
Створіть кілька чанків:
fastbin_victim
(0x60, зміщення 0): пізніше UAF чанк для редагування вказівника кучі, щоб вказувати на значення LibC.chunk2
(0x80, зміщення 0x70): для хорошого вирівнюванняmain_arena_use
(0x80, зміщення 0x100)relative_offset_heap
(0x60, зміщення 0x190): відносне зміщення на чанку 'main_arena_use'
Потім free(main_arena_use)
, що помістить цей чанк у список unsorted та отримає вказівник на main_arena + 0x68
як у вказівниках fd
та bk
.
Тепер виділений новий чанк fake_libc_chunk(0x60)
, оскільки він буде містити вказівники на main_arena + 0x68
у вказівниках fd
та bk
.
Потім вільні relative_offset_heap
та fastbin_victim
.
fastbin_victim
маєfd
, що вказує наrelative_offset_heap
relative_offset_heap
- це зміщення відfake_libc_chunk
, який містить вказівник наmain_arena + 0x68
Просто змінивши останній байт
fastbin_victim.fd
, можна зробити так, щобfastbin_victim вказував
наmain_arena + 0x68
Для попередніх дій зловмиснику потрібно мати можливість змінювати вказівник fd fastbin_victim
.
Потім, main_arena + 0x68
не настільки цікавий, тому змінимо його так, щоб вказівник вказував на __malloc_hook
.
Зверніть увагу, що __memalign_hook
зазвичай починається з 0x7f
і нулі перед ним, тому можна підробити його як значення в 0x70
швидкій біні. Оскільки останні 4 біти адреси випадкові, існує 2^4=16
можливостей для того, щоб значення закінчувалося там, де ми зацікавлені. Тому тут виконується атака BF, щоб частина закінчувалася так: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)
.
(Для отримання додаткової інформації про решту байтів перевірте пояснення в how2heapприкладі). Якщо BF не працює, програма просто аварійно завершується (тому почніть знову, поки не вдасться).
Потім виконуються 2 виклики malloc для видалення 2 початкових швидких бінів, і третій виклик виконується для отримання частини в __malloc_hook:
Частина 2: Атака на unsorted_bin
Для отримання додаткової інформації ви можете перевірити:
Unsorted Bin AttackАле в основному це дозволяє записати main_arena + 0x68
в будь-яке місце, вказане в chunk->bk
. І для атаки ми вибираємо __malloc_hook
. Потім, після перезапису, ми використаємо відносний перезапис, щоб вказати на one_gadget
.
Для цього ми починаємо отримувати частину та поміщаємо її в unsorted bin:
Використовуйте UAF у цьому фрагменті, щоб вказати unsorted_bin_ptr->bk
на адресу __malloc_hook
(ми раніше брутфорсили це).
Зверніть увагу, що цей атака порушує невпорядкований бін (тому ми можемо використовувати виділення лише зі швидкого біна тепер) (більш складна програма може робити інші виділення та аваріювати), і для того, щоб спровокувати це, ми повинні виділити ту саму кількість або програма аваріюється.
Таким чином, для спровокування запису main_arena + 0x68
в __malloc_hook
ми виконуємо після встановлення __malloc_hook
в unsorted_bin_ptr->bk
просто потрібно зробити: malloc(0x80)
Крок 3: Встановлення __malloc_hook на систему
На першому кроці ми закінчили контролювати частину, що містить __malloc_hook
(у змінній malloc_hook_chunk
), а на другому кроці нам вдалося записати main_arena + 0x68
сюди.
Тепер ми використовуємо частковий перезапис в malloc_hook_chunk
, щоб використати адресу libc, яку ми там записали (main_arena + 0x68
), для вказівки адреси one_gadget
.
Тут потрібно брутфорсити 12 бітів випадковості (докладніша інформація в how2heapприкладі).
Нарешті, коли правильна адреса перезаписана, викличте malloc
та спровокуйте one_gadget
.
Посилання
Last updated