Відповіді:
Захист стеку здійснює компілятор (додайте кілька додаткових даних у стек та приховайте дещо під час виклику, перевірте розумність при поверненні). Неможливо відключити це без перекомпіляції. Це справді частина справді ...
Щоб розширити те, про що говорив vonbrand (правильно, +1), до захисту стека Linux є дві частини.
Канальні стеки - це функція, яку підтримує компілятор, на яку посилається Фон. Їх неможливо відключити без перекомпіляції.
Щоб довести це собі і побачити, як вони працюють, візьміть наступний код:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int mybadfunction(char* a_bad_idea)
{
char what[100];
strcpy(what, a_bad_idea);
printf("You passed %s\n", what);
}
int main(int argc, char** argv)
{
printf("Tralalalaala\n");
mybadfunction(argv[1]);
}
Тепер компілюйте це ( gcc -fstack-protector -masm=intel -S test.c
) у щось gnu, як було б радий зібрати та прочитати вихід. Важливим моментом є те, що при виході з mybadfunction
функції є цей маленький фрагмент коду:
mov edx, DWORD PTR [ebp-12]
xor edx, DWORD PTR gs:20
je .L2
call __stack_chk_fail
Як ви здогадаєтесь, це отримання файлу cookie стека [ebp-12]
та порівняння його зі значенням at gs:20
. Не відповідає? Потім він викликає функцію __stack_chk_fail
в glibc, яка вбиває вашу програму саме там.
Існують способи подолати це з точки зору написання подвигів, але простий спосіб з точки зору побудови тестового коду оболонки - це складання вашої програми -fno-stack-protector
.
Є деякі інші міркування щодо сучасних систем Linux. Якщо ви берете звичайну заглушку для тестування оболонок:
char buffer[] = {...};
typedef void (* func)(void);
int main(int argc, char** argv)
{
func f = (func) buffer;
f();
return 0;
}
сучасний GCC / Linux буде відображати .rodata
розділ файлу PE, який читається лише без дозволів на виконання. Вам потрібно вимкнути це, що можна зробити за допомогою зразка коду з цієї публікації в блозі . Основна ідея: ви використовуєте mprotect
для додавання потрібних дозволів до сторінок, на яких знаходяться дані оболонки.
Якщо ви збираєтеся перевірити традиційний сценарій експлуатації, наприклад, мій поганий код вище, з вашим кодом оболонки, то вам також потрібно забезпечити виконання стека для простих випадків. Формат файлу PE містить поле для визначення того, чи є стек виконуваним - ви можете запитувати і керувати цим за допомогою execstack . Щоб увімкнути виконуваний стек, запустіть
execstack -s /path/to/myprog
Це можна зробити в довільних програмах без необхідності перекомпіляції, але автоматично не відключати канали стеків, оскільки вони записуються під час компіляції.
Для того, щоб перетворити це геть, echo 0 > /proc/sys/kernel/randomize_va_space
.
Ні. Будь-який експлуататор повинен працювати навколо каналів стеків (дуже нетривіально) і або знаходити програму з execstack
набором, або встановлювати її (це означає, що вона вже може виконувати довільні команди в будь-якому випадку) або використовувати інші складніші методи, наприклад повернення до libc / return орієнтоване програмування.
За допомогою цих параметрів можна відключити деякі захисти (виявлення розбиття стека та зробити стек виконаним).
--z execstack
-f no-stack-protector
Ви також можете вимкнути ASLR (рандомізація розташування адресного простору) за допомогою Bash за допомогою команди:
echo 0 > /proc/sys/kernel/randomize_va_space