ASLR
Last updated
Вивчайте та практикуйте взлом AWS: Навчання HackTricks AWS Red Team Expert (ARTE) Вивчайте та практикуйте взлом GCP: Навчання HackTricks GCP Red Team Expert (GRTE)
Випадкове розташування простору адрес (ASLR) - це техніка безпеки, яка використовується в операційних системах для випадкового розташування адрес пам'яті, які використовуються системними та програмними процесами. Це значно ускладнює передбачення місця конкретних процесів та даних, таких як стек, купа та бібліотеки, тим самим запобігаючи певним типам експлойтів, зокрема переповненням буфера.
Щоб перевірити статус ASLR в системі Linux, ви можете прочитати значення з файлу /proc/sys/kernel/randomize_va_space
. Значення, збережене в цьому файлі, визначає тип застосованого ASLR:
0: Відсутнє випадкове розташування. Все статичне.
1: Консервативне випадкове розташування. Рандомізуються спільні бібліотеки, стек, mmap(), сторінка VDSO.
2: Повне випадкове розташування. Крім елементів, які рандомізуються консервативним варіантом, пам'ять, керована через brk()
, рандомізується.
Ви можете перевірити статус ASLR за допомогою наступної команди:
Для вимкнення ASLR встановіть значення /proc/sys/kernel/randomize_va_space
на 0. Зазвичай не рекомендується вимикати ASLR, крім випадків тестування або налагодження. Ось як це можна зробити:
Ви також можете вимкнути ASLR для виконання за допомогою:
Для увімкнення ASLR можна записати значення 2 у файл /proc/sys/kernel/randomize_va_space
. Зазвичай для цього потрібні привілеї root. Повне випадкове розташування можна ввімкнути за допомогою наступної команди:
Зміни, внесені за допомогою команд echo
, є тимчасовими і будуть скинуті при перезавантаженні. Щоб зробити зміну стійкою, вам потрібно відредагувати файл /etc/sysctl.conf
та додати або змінити наступний рядок:
Після редагування /etc/sysctl.conf
застосуйте зміни за допомогою:
Це забезпечить, що ваші налаштування ASLR залишаться після перезавантаження.
PaX розділяє простір адрес процесу на 3 групи:
Код та дані (ініціалізовані та неініціалізовані): .text
, .data
та .bss
—> 16 біт ентропії у змінній delta_exec
. Ця змінна випадково ініціалізується з кожним процесом та додається до початкових адрес.
Пам'ять, виділена за допомогою mmap()
та спільні бібліотеки —> 16 біт, позначена як delta_mmap
.
Стек —> 24 біти, позначена як delta_stack
. Однак фактично використовує 11 біт (від 10-го до 20-го байта включно), вирівняні на 16 байт —> Це призводить до 524,288 можливих реальних адрес стеку.
Попередні дані для 32-бітних систем, а зменшена кінцева ентропія дозволяє обійти ASLR, спробувавши виконання знову і знову, поки експлойт успішно завершиться.
Якщо у вас достатньо велике переповнення для розміщення великого NOP-ковзання перед кодом оболонки, ви можете просто грубо насильно перебирати адреси в стеку, поки потік перескочить деяку частину NOP-коду.
Ще один варіант для цього у випадку, якщо переповнення не настільки велике і експлойт може бути запущений локально, це можливо додати NOP-код та код оболонки в змінну середовища.
Якщо експлойт локальний, ви можете спробувати грубо насильно визначити базову адресу libc (корисно для 32-бітних систем):
Якщо ви атакуєте віддалений сервер, ви можете спробувати перебрати адресу функції usleep
у libc
, передаючи як аргумент 10 (наприклад). Якщо в якийсь момент сервер витрачає додаткові 10 секунд на відповідь, ви знайшли адресу цієї функції.
На 64-бітних системах ентропія набагато вища, і це не повинно бути можливим.
Можливо зайняти велику частину стеку змінними середовища, а потім спробувати зловживати бінарним файлом сотні/тисячі разів локально, щоб експлуатувати його. Наступний код показує, як можна просто вибрати адресу в стеці і кожні кілька сотень виконань ця адреса буде містити інструкцію NOP:
/proc/[pid]/stat
)Файл /proc/[pid]/stat
процесу завжди доступний для читання кожному і він містить цікаву інформацію, таку як:
startcode & endcode: Адреси вище і нижче з TEXT бінарного файлу
startstack: Адреса початку стеку
start_data & end_data: Адреси вище і нижче, де знаходиться BSS
kstkesp & kstkeip: Поточні адреси ESP та EIP
arg_start & arg_end: Адреси вище і нижче, де знаходяться аргументи командного рядка
env_start & env_end: Адреси вище і нижче, де знаходяться змінні середовища
Отже, якщо зловмисник знаходиться на тому ж комп'ютері, що і бінарний файл, який використовується, і цей бінарний файл не очікує переповнення від сирої аргументації, але від іншого вводу, який може бути створений після читання цього файлу. Для зловмисника можливо отримати деякі адреси з цього файлу та побудувати з них зміщення для експлойту.
Для отримання додаткової інформації про цей файл перегляньте https://man7.org/linux/man-pages/man5/proc.5.html, шукаючи /proc/pid/stat
Завдання полягає в наданні витоку
Якщо вам надано витік (легкі завдання CTF), ви можете розрахувати зміщення з нього (припускаючи, наприклад, що ви знаєте точну версію libc, яка використовується в системі, яку ви експлуатуєте). Цей приклад експлойту взято з прикладу звідси (перевірте цю сторінку для отримання додаткових деталей):
ret2plt
Зловживанням переповненням буфера можливо використати ret2plt для витіснення адреси функції з libc. Перевірте:
Формат рядків довільного читання
Точно так само, як у випадку з ret2plt, якщо у вас є довільне читання через вразливість формату рядків, можливо витіснити адресу функції libc з GOT. Наступний приклад звідси:
Ви можете знайти більше інформації про довільне читання форматних рядків за посиланням:
Спробуйте обійти ASLR, зловживаючи адресами всередині стеку:
Механізм vsyscall
призначений для підвищення продуктивності, дозволяючи виконувати певні системні виклики в просторі користувача, хоча вони фундаментально належать ядру. Критичною перевагою vsyscalls є їх фіксовані адреси, які не піддаються ASLR (випадкове розташування простору адрес). Ця фіксована природа означає, що зловмисники не потребують уразливості на витік інформації для визначення їх адрес та використання їх у експлойті.
Однак тут не буде знайдено дуже цікавих гаджетів (хоча, наприклад, можливо отримати еквівалент ret;
)
(Наступний приклад та код взято з цього опису)
Наприклад, зловмисник може використовувати адресу 0xffffffffff600800
у своєму експлойті. Хоча спроба безпосередньо перейти до інструкції ret
може призвести до нестабільності або аварійного завершення після виконання кількох гаджетів, перехід на початок syscall
, наданої розділом vsyscall, може бути успішним. Ретельно розмістивши гаджет ROP, який веде виконання до цієї адреси vsyscall, зловмисник може досягти виконання коду, не потребуючи обходу ASLR для цієї частини експлойту.
Зверніть увагу, яким чином можливо обійти ASLR, зловживаючи vdso, якщо ядро скомпільоване з CONFIG_COMPAT_VDSO, оскільки адреса vdso не буде випадковою. Для отримання додаткової інформації перегляньте: