BROP - Blind Return Oriented Programming

Reading time: 6 minutes

tip

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

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

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

Мета цієї атаки полягає в тому, щоб зловживати ROP через переповнення буфера без будь-якої інформації про вразливий бінарний файл.
Ця атака базується на наступному сценарії:

  • Вразливість стека та знання про те, як її викликати.
  • Серверний додаток, який перезапускається після збою.

Атака

1. Знайти вразливий офсет відправляючи ще один символ, поки не буде виявлено збій сервера

2. Брутфорс канарки для її витоку

3. Брутфорс збережених адрес RBP та RIP у стеку для їх витоку

Ви можете знайти більше інформації про ці процеси тут (BF Forked & Threaded Stack Canaries) та тут (BF Addresses in the Stack).

4. Знайти стоп-гаджет

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

5. Знайти гаджет BROP

Ця техніка використовує гаджет ret2csu. І це тому, що якщо ви отримуєте доступ до цього гаджета посеред деяких інструкцій, ви отримуєте гаджети для контролю rsi та rdi:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

Це будуть гаджети:

  • pop rsi; pop r15; ret
  • pop rdi; ret

Зверніть увагу, як з цими гаджетами можна контролювати 2 аргументи функції для виклику.

Також зверніть увагу, що гаджет ret2csu має дуже унікальний підпис, оскільки він буде витягувати 6 регістрів зі стеку. Тому відправляючи ланцюг, як:

'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP

Якщо STOP виконується, це в основному означає, що адреса, яка витягує 6 регістрів зі стеку, була використана. Або що використана адреса також була адресою STOP.

Щоб усунути цю останню опцію, виконується новий ланцюг, як наступний, і він не повинен виконувати гаджет STOP, щоб підтвердити, що попередній дійсно витягнув 6 регістрів:

'A' * offset + canary + rbp + ADDR

Знаючи адресу гаджета ret2csu, можна вивести адресу гаджетів для контролю rsi та rdi.

6. Знайти PLT

Таблицю PLT можна шукати з 0x400000 або з витягнутої адреси RIP зі стеку (якщо PIE використовується). Записи таблиці відокремлені на 16B (0x10B), і коли викликається одна функція, сервер не зривається, навіть якщо аргументи неправильні. Також перевірка адреси запису в PLT + 6B також не призводить до збою, оскільки це перший код, що виконується.

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

  • 'A' * offset + canary + rbp + ADDR + STOP -> немає збою
  • 'A' * offset + canary + rbp + (ADDR + 0x6) + STOP -> немає збою
  • 'A' * offset + canary + rbp + (ADDR + 0x10) + STOP -> немає збою

7. Знайти strcmp

Функція strcmp встановлює регістр rdx на довжину рядка, що порівнюється. Зверніть увагу, що rdx є третім аргументом, і нам потрібно, щоб він був більше 0, щоб пізніше використовувати write для витоку програми.

Можна знайти місце розташування strcmp в PLT на основі його поведінки, використовуючи той факт, що ми тепер можемо контролювати 2 перші аргументи функцій:

  • strcmp(<non read addr>, <non read addr>) -> збій
  • strcmp(<non read addr>, <read addr>) -> збій
  • strcmp(<read addr>, <non read addr>) -> збій
  • strcmp(<read addr>, <read addr>) -> немає збою

Це можна перевірити, викликавши кожен запис таблиці PLT або використовуючи PLT повільний шлях, який в основному полягає в виклику запису в таблиці PLT + 0xb (що викликає dlresolve) з наступним у стеку номер запису, який потрібно перевірити (починаючи з нуля), щоб просканувати всі записи PLT з першого:

  • strcmp(<non read addr>, <read addr>) -> збій
  • b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP -> Призведе до збою
  • strcmp(<read addr>, <non read addr>) -> збій
  • b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP
  • strcmp(<read addr>, <read addr>) -> немає збою
  • b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP

Пам'ятайте, що:

  • BROP + 0x7 вказує на pop RSI; pop R15; ret;
  • BROP + 0x9 вказує на pop RDI; ret;
  • PLT + 0xb вказує на виклик dl_resolve.

Знайшовши strcmp, можна встановити rdx на значення більше 0.

tip

Зверніть увагу, що зазвичай rdx вже міститиме значення більше 0, тому цей крок може бути не обов'язковим.

8. Знайти Write або еквівалент

Нарешті, потрібен гаджет, який ексфільтрує дані, щоб ексфільтрувати бінарний файл. І в цей момент можна контролювати 2 аргументи та встановити rdx більше 0.

Є 3 загальні функції, які можна зловживати для цього:

  • puts(data)
  • dprintf(fd, data)
  • write(fd, data, len(data)

Однак оригінальна стаття згадує лише про write, тому давайте поговоримо про це:

Поточна проблема полягає в тому, що ми не знаємо, де функція write знаходиться всередині PLT і ми не знаємо номер fd, щоб надіслати дані до нашого сокету.

Однак ми знаємо, де знаходиться таблиця PLT, і можна знайти write на основі його поведінки. І ми можемо створити кілька з'єднань з сервером і використовувати високий FD, сподіваючись, що він відповідає деяким з наших з'єднань.

Поведінкові сигнатури для знаходження цих функцій:

  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Якщо є дані, що виводяться, тоді було знайдено puts
  • 'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Якщо є дані, що виводяться, тоді було знайдено dprintf
  • 'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP -> Якщо є дані, що виводяться, тоді було знайдено write

Автоматичне експлуатація

Посилання

tip

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

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