Отключите защиту стека в Ubuntu для переполнения буфера без флагов компилятора C

10

Я хотел бы попробовать некоторые шелл-коды и отключить защиту Linux.

Я знаю, что могу компилировать, используя флаги, но я знаю, что существует другой способ отключить эти защиты в общем, я просто не могу вспомнить. Вы можете помочь мне?

Фейт
источник

Ответы:

6

Защита стека осуществляется компилятором (добавьте некоторые дополнительные данные в стек и спрячьте некоторые при вызове, проверьте работоспособность при возврате). Не могу отключить это без перекомпиляции. Это часть дела, правда ...

vonbrand
источник
6
ASLR требует, чтобы ОС делала это во время выполнения. Биты NX также требуют системной поддержки. Какую часть нельзя отключить во время выполнения?
Джефф Ферланд
25

Чтобы расширить то, что сказал vonbrand (правильно, +1), есть две части защиты стека Linux.

Стек канареек

Канарские стеки - это обязательная для компилятора функция, на которую ссылается vonbrand. Они не могут быть отключены без перекомпиляции.

Чтобы доказать это себе и посмотреть, как они работают, возьмите следующий код:

#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]);
}

Теперь скомпилируйте this ( 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]и сравнивает его со значением в 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

Это может быть сделано на произвольных программах без необходимости перекомпиляции, но не будет автоматически отключать канареек стека, так как они запекаются при компиляции.

Добавленный бонус: aslr:

Чтобы отключить это echo 0 > /proc/sys/kernel/randomize_va_space.

Ты только что рассказал кому-нибудь, как эксплуатировать моего драгоценного пингвина?

Нет. Любой эксплойт должен работать с канареками стека (очень нетривиально) и либо находить программу с execstackset, либо устанавливать ее (то есть она может выполнять произвольные команды в любом случае), либо использовать более сложные методы, такие как return to libc / return. ориентированное программирование.

Джонатан Леффлер
источник
0

С помощью этих опций вы можете отключить некоторые средства защиты (обнаружение разрушения стека и сделать исполняемый стек).

--z execstack
-f no-stack-protector

Вы также можете отключить ASLR (рандомизацию размещения адресного пространства) с помощью Bash с помощью команды:

echo 0 > /proc/sys/kernel/randomize_va_space
gotoat
источник