House of Roman
Reading time: 5 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Basic Information
Це була дуже цікава техніка, яка дозволяла отримати RCE без leaks через фейкові fastbins, атаку unsorted_bin та відносні перезаписи. Однак вона була виправлена.
Code
- Ви можете знайти приклад у https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Goal
- RCE шляхом зловживання відносними вказівниками
Requirements
- Редагувати вказівники fastbin та unsorted bin
- 12 біт випадковості повинні бути перебрані (0.02% шанс) на успіх
Attack Steps
Part 1: Fastbin Chunk points to __malloc_hook
Створіть кілька чанків:
fastbin_victim
(0x60, offset 0): UAF chunk, який пізніше редагуватиме вказівник купи, щоб вказувати на значення LibC.chunk2
(0x80, offset 0x70): Для хорошого вирівнюванняmain_arena_use
(0x80, offset 0x100)relative_offset_heap
(0x60, offset 0x190): відносний зсув на чанку 'main_arena_use'
Потім free(main_arena_use)
, що помістить цей чанк у неупорядкований список і отримає вказівник на main_arena + 0x68
в обох вказівниках fd
та bk
.
Тепер виділяється новий чанк fake_libc_chunk(0x60)
, оскільки він міститиме вказівники на main_arena + 0x68
у fd
та bk
.
Потім relative_offset_heap
та fastbin_victim
звільняються.
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
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:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Частина 2: Атака на Unsorted_bin
Для отримання додаткової інформації ви можете перевірити:
Але в основному це дозволяє записати main_arena + 0x68
в будь-яке місце, вказане в chunk->bk
. І для атаки ми вибираємо __malloc_hook
. Потім, після перезапису, ми використаємо відносний перезапис, щоб вказати на one_gadget
.
Для цього ми починаємо отримувати шматок і поміщаємо його в unsorted bin:
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
Використайте UAF в цьому блоці, щоб вказати unsorted_bin_ptr->bk
на адресу __malloc_hook
(ми раніше це брутфорсили).
caution
Зверніть увагу, що ця атака пошкоджує несортований бін (отже, і малий, і великий також). Тому ми можемо використовувати лише алокації з швидкого біна зараз (більш складна програма може виконувати інші алокації і зламатися), і щоб викликати це, ми повинні алокувати той же розмір, інакше програма зламається.
Отже, щоб викликати запис main_arena + 0x68
в __malloc_hook
, ми виконуємо після встановлення __malloc_hook
в unsorted_bin_ptr->bk
, нам просто потрібно зробити: malloc(0x80)
Крок 3: Встановіть __malloc_hook на system
На першому кроці ми закінчили контроль над шматком, що містить __malloc_hook
(в змінній malloc_hook_chunk
), а на другому кроці нам вдалося записати main_arena + 0x68
сюди.
Тепер ми зловживаємо частковим перезаписом в malloc_hook_chunk
, щоб використовувати адресу libc, яку ми записали там (main_arena + 0x68
), щоб вказати адресу one_gadget
.
Ось тут потрібно брутфорсити 12 біт випадковості (більше інформації в how2heap приклад).
Нарешті, коли правильна адреса буде перезаписана, викличте malloc
і активуйте one_gadget
.
Посилання
- https://github.com/shellphish/how2heap
- https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.