8.5 KiB
Raw Blame History

WWW2Exec - GOT/PLT

{{#include ../../banners/hacktricks-training.md}}

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

GOT: Глобальна таблиця зсувів

Глобальна таблиця зсувів (GOT) - це механізм, що використовується в динамічно зв'язаних двійкових файлах для управління адресами зовнішніх функцій. Оскільки ці адреси не відомі до часу виконання (через динамічне зв'язування), GOT надає спосіб динамічно оновлювати адреси цих зовнішніх символів після їх розв'язання.

Кожен запис у GOT відповідає символу в зовнішніх бібліотеках, які може викликати двійковий файл. Коли функція викликається вперше, її фактична адреса розв'язується динамічним зв'язувачем і зберігається в GOT. Наступні виклики тієї ж функції використовують адресу, збережену в GOT, таким чином уникаючи накладних витрат на повторне розв'язання адреси.

PLT: Таблиця зв'язування процедур

Таблиця зв'язування процедур (PLT) тісно співпрацює з GOT і служить як трамплін для обробки викликів до зовнішніх функцій. Коли двійковий файл викликає зовнішню функцію вперше, управління передається до запису в PLT, пов'язаного з цією функцією. Цей запис PLT відповідає за виклик динамічного зв'язувача для розв'язання адреси функції, якщо вона ще не була розв'язана. Після розв'язання адреси вона зберігається в GOT.

Отже, записи GOT використовуються безпосередньо після того, як адреса зовнішньої функції або змінної розв'язана. Записи PLT використовуються для полегшення початкового розв'язання цих адрес через динамічний зв'язувач.

Отримання виконання

Перевірка GOT

Отримайте адресу таблиці GOT за допомогою: objdump -s -j .got ./exec

Зверніть увагу, як після завантаження виконуваного файлу в GEF ви можете бачити функції, які є в GOT: gef➤ x/20x 0xADDR_GOT

Використовуючи GEF, ви можете почати сесію відлагодження і виконати got, щоб побачити таблицю got:

GOT2Exec

У двійковому файлі GOT має адреси функцій або до сектора PLT, який завантажить адресу функції. Мета цього довільного запису - перезаписати запис GOT функції, яка буде виконана пізніше з адресою PLT функції system наприклад.

Ідеально, ви будете перезаписувати GOT функції, яка буде викликана з параметрами, контрольованими вами (так що ви зможете контролювати параметри, що передаються функції системи).

Якщо system не використовується двійковим файлом, функція системи не матиме запису в PLT. У цьому сценарії вам потрібно спочатку витікати адресу функції system, а потім перезаписати GOT, щоб вказати на цю адресу.

Ви можете побачити адреси PLT за допомогою objdump -j .plt -d ./vuln_binary

Записи GOT libc

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

Звичайні функції libc будуть викликати інші внутрішні функції, адреси GOT яких можуть бути перезаписані для отримання виконання коду.

Знайдіть більше інформації про цю техніку тут.

Free2system

У експлуатації купи CTF часто можна контролювати вміст частин і в якийсь момент навіть перезаписати таблицю GOT. Простий трюк для отримання RCE, якщо один гаджет недоступний, - це перезаписати адресу GOT free, щоб вказати на system, і записати в частину "/bin/sh". Таким чином, коли ця частина буде звільнена, вона виконає system("/bin/sh").

Strlen2system

Ще одна поширена техніка - це перезаписати адресу GOT strlen, щоб вказати на system, так що якщо ця функція викликається з введенням користувача, можливо передати рядок "/bin/sh" і отримати оболонку.

Більше того, якщо puts використовується з введенням користувача, можливо перезаписати адресу GOT strlen, щоб вказати на system і передати рядок "/bin/sh", щоб отримати оболонку, оскільки puts викликатиме strlen з введенням користувача.

One Gadget

{{#ref}} ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}}

Зловживання GOT з купи

Звичайний спосіб отримати RCE з вразливості купи - це зловживати fastbin, щоб можна було додати частину таблиці GOT у швидкий бін, так що щоразу, коли ця частина виділяється, буде можливість перезаписати вказівник функції, зазвичай free.
Потім, вказуючи free на system і звільняючи частину, де було записано /bin/sh\x00, буде виконано оболонку.

Можна знайти приклад тут.

Захисти

Захист Full RELRO призначений для захисту від такого роду технік, розв'язуючи всі адреси функцій, коли двійковий файл запускається, і роблячи таблицю GOT тільки для читання після цього:

{{#ref}} ../common-binary-protections-and-bypasses/relro.md {{#endref}}

Посилання

{{#include ../../banners/hacktricks-training.md}}