hacktricks/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md

7.2 KiB
Raw Permalink Blame History

WWW2Exec - __malloc_hook & __free_hook

{% hint style="success" %} Вивчайте та практикуйте хакінг AWS: Навчання HackTricks AWS Red Team Expert (ARTE)
Вивчайте та практикуйте хакінг GCP: Навчання HackTricks GCP Red Team Expert (GRTE)

Підтримайте HackTricks
{% endhint %}

Malloc Hook

Як ви можете прочитати на офіційному сайті GNU, змінна __malloc_hook є вказівником, який вказує на адресу функції, яка буде викликана кожного разу, коли викликається malloc(), збережена в розділі даних бібліотеки libc. Тому, якщо цю адресу перезаписати, наприклад, з One Gadget, і викликати malloc, то буде викликано One Gadget.

Для виклику malloc можна зачекати, коли програма його викличе, або викликати printf("%10000$c"), що виділяє багато байтів, що змушує libc викликати malloc для їх виділення в купі.

Додаткова інформація про One Gadget:

{% content-ref url="../rop-return-oriented-programing/ret2lib/one-gadget.md" %} one-gadget.md {% endcontent-ref %}

{% hint style="warning" %} Зверніть увагу, що гачки вимкнені для GLIBC >= 2.34. Існують інші техніки, які можна використовувати в сучасних версіях GLIBC. Див.: https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md. {% endhint %}

Free Hook

Це було зловживано в одному з прикладів на сторінці, використовуючи атаку на швидкий бін після атаки на неупорядкований бін:

{% content-ref url="../libc-heap/unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}

Можливо знайти адресу __free_hook, якщо у бінарному файлі є символи за допомогою наступної команди:

gef➤  p &__free_hook

У пості ви можете знайти крок за кроком посібник з тим, як знайти адресу гачка free без символів. У відомостях, у функції free:

gef➤  x/20i free
0xf75dedc0 <free>: push   ebx
0xf75dedc1 <free+1>: call   0xf768f625
0xf75dedc6 <free+6>: add    ebx,0x14323a
0xf75dedcc <free+12>:  sub    esp,0x8
0xf75dedcf <free+15>:  mov    eax,DWORD PTR [ebx-0x98]
0xf75dedd5 <free+21>:  mov    ecx,DWORD PTR [esp+0x10]
0xf75dedd9 <free+25>:  mov    eax,DWORD PTR [eax]--- BREAK HERE
0xf75deddb <free+27>:  test   eax,eax ;<
0xf75deddd <free+29>:  jne    0xf75dee50 <free+144>

У зазначеному місці в попередньому коді в $eax буде розташована адреса гачка free.

Тепер виконується швидка атака на бін:

  • По-перше, виявлено, що можна працювати зі швидкими частинами розміром 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

  • Якщо нам вдасться отримати швидку частину розміром 0x200 на цьому місці, буде можливо перезаписати вказівник функції, яка буде виконана
  • Для цього створюється нова частина розміром 0xfc і двічі викликається функція злиття з цим вказівником, таким чином ми отримуємо вказівник на вивільнену частину розміром 0xfc*2 = 0x1f8 у швидкому біні.
  • Потім в цій частині викликається функція редагування, щоб змінити адресу fd цієї швидкої частини, щоб вказувати на попередню функцію __free_hook.
  • Потім створюється частина розміром 0x1f8, щоб отримати зі швидкого біна попередню непотрібну частину, тому створюється ще одна частина розміром 0x1f8, щоб отримати швидку частину біна в __free_hook, яка перезаписується адресою функції system.
  • І, нарешті, вивільняється частина, що містить рядок /bin/sh\x00, викликаючи функцію видалення, що спрацьовує функцію __free_hook, яка вказує на систему з параметром /bin/sh\x00.

Посилання