Stack Canaries
Reading time: 5 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
StackGuard та StackShield
StackGuard вставляє спеціальне значення, відоме як canary, перед EIP (Розширений вказівник інструкцій), зокрема 0x000aff0d
(що представляє null, новий рядок, EOF, повернення каретки) для захисту від переповнень буфера. Однак функції, такі як recv()
, memcpy()
, read()
, і bcopy()
, залишаються вразливими, і це не захищає EBP (Базовий вказівник).
StackShield використовує більш складний підхід, ніж StackGuard, підтримуючи Глобальний стек повернень, який зберігає всі адреси повернень (EIPs). Ця конфігурація забезпечує, що будь-яке переповнення не завдає шкоди, оскільки дозволяє порівняти збережені та фактичні адреси повернень для виявлення випадків переповнення. Крім того, StackShield може перевіряти адресу повернення на відповідність граничному значенню, щоб виявити, чи EIP вказує за межі очікуваного простору даних. Однак цей захист можна обійти за допомогою технік, таких як Return-to-libc, ROP (Програмування, орієнтоване на повернення) або ret2ret, що вказує на те, що StackShield також не захищає локальні змінні.
Stack Smash Protector (ProPolice) -fstack-protector
:
Цей механізм розміщує canary перед EBP і реорганізовує локальні змінні, щоб розмістити буфери на вищих адресах пам'яті, запобігаючи їх перезапису інших змінних. Він також безпечно копіює аргументи, передані на стеку вище локальних змінних, і використовує ці копії як аргументи. Однак він не захищає масиви з менш ніж 8 елементами або буфери в структурі користувача.
Canary є випадковим числом, отриманим з /dev/urandom
або значенням за замовчуванням 0xff0a0000
. Він зберігається в TLS (Локальне зберігання потоків), що дозволяє спільним просторам пам'яті між потоками мати специфічні для потоків глобальні або статичні змінні. Ці змінні спочатку копіюються з батьківського процесу, а дочірні процеси можуть змінювати свої дані, не впливаючи на батьківський або братні процеси. Проте, якщо fork()
використовується без створення нового canary, всі процеси (батьківський і дочірні) ділять один і той же canary, що робить його вразливим. На архітектурі i386 canary зберігається за адресою gs:0x14
, а на x86_64 - за адресою fs:0x28
.
Цей локальний захист ідентифікує функції з буферами, вразливими до атак, і впроваджує код на початку цих функцій для розміщення canary, а в кінці для перевірки його цілісності.
Коли веб-сервер використовує fork()
, це дозволяє провести грубу атаку для вгадування байта canary по одному. Однак використання execve()
після fork()
перезаписує простір пам'яті, заперечуючи атаку. vfork()
дозволяє дочірньому процесу виконуватися без дублювання, поки він не намагається записати, в цей момент створюється дублікат, пропонуючи інший підхід до створення процесів і обробки пам'яті.
Довжини
У бінарних файлах x64
cookie canary є 0x8
байтовим qword. Перші сім байтів випадкові, а останній байт - нульовий байт.
У бінарних файлах x86
cookie canary є 0x4
байтовим dword. Перші три байти випадкові, а останній байт - нульовий байт.
caution
Найменший значущий байт обох canary є нульовим байтом, оскільки він буде першим у стеку, що походить з нижчих адрес, і тому функції, які читають рядки, зупиняться перед його читанням.
Обходи
Витік canary і потім перезапис його (наприклад, переповнення буфера) своїм значенням.
- Якщо canary розгалужується в дочірніх процесах, може бути можливим грубо вгадати його по одному байту:
BF Forked & Threaded Stack Canaries
- Якщо в бінарному файлі є якийсь цікавий витік або вразливість довільного читання, може бути можливим витік його:
- Перезапис вказівників, що зберігаються в стеку
Стек, вразливий до переповнення стека, може містити адреси рядків або функцій, які можуть бути перезаписані для експлуатації вразливості без необхідності досягати canary. Перевірте:
- Модифікація як майстерного, так і потокового canary
Переповнення буфера в потоковій функції, захищеній canary, може бути використано для модифікації майстерного canary потоку. В результаті, пом'якшення є марним, оскільки перевірка використовується з двома canary, які є однаковими (хоча модифікованими).
Більше того, переповнення буфера в потоковій функції, захищеній canary, може бути використано для модифікації майстерного canary, збереженого в TLS. Це тому, що може бути можливим досягти позиції пам'яті, де зберігається TLS (а отже, і canary) через bof у стеку потоку.
В результаті, пом'якшення є марним, оскільки перевірка використовується з двома canary, які є однаковими (хоча модифікованими).
Ця атака виконується в описі: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
Перевірте також презентацію https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015, яка згадує, що зазвичай TLS зберігається за допомогою mmap
, і коли створюється стек потоку, він також генерується за допомогою mmap
, що може дозволити переповнення, як показано в попередньому описі.
- Модифікація запису GOT
__stack_chk_fail
Якщо бінарний файл має Partial RELRO, то ви можете використовувати довільний запис для модифікації запису GOT __stack_chk_fail
на фіктивну функцію, яка не блокує програму, якщо canary буде модифіковано.
Ця атака виконується в описі: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
Посилання
- https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html
- http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
- https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.