House of Roman

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

Основна інформація

Це була дуже цікава техніка, яка дозволяла виконати RCE без витоку інформації через фейкові fastbins, атаку на unsorted_bin та відносні перезаписи. Однак це було виправлено.

Код

Мета

  • 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.

/*
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

Для отримання додаткової інформації ви можете перевірити:

Unsorted Bin Attack

Але в основному це дозволяє записати 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 (ми раніше брутфорсили це).

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

Таким чином, для спровокування запису 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