выполнение простого переполнения буфера на Mac OS 10.6 - PullRequest
4 голосов
/ 12 июня 2010

Я пытаюсь узнать о переполнении базы стека и написать простой код для использования стека.Но почему-то это не работает вообще, а показывает только прерывание прерывания на моей машине (Mac OS Leopard)

Я думаю, Mac OS обрабатывает переполнение по-другому, это не позволит мне перезаписать память через код c.например,

strcpy(buffer, input) // lets say char buffer[6] but input is 7 bytes 

на компьютере с Linux, этот код успешно перезаписывает следующий стек, но предотвращается на Mac OS (прерывание прерывания)

Кто-нибудь знает, как выполнить простое переполнение базы стека наMac машина?

Ответы [ 4 ]

11 голосов
/ 12 июня 2013

@ joveha ответ правильный, с GCC вы должны скомпилировать с -fno-stack-protector чтобы включить защиту от переполнения буфера.

Однако дополнительно вам необходимо отключить параметр FORTIFY_SOURCE, в противном случае вы получите «Прерывание прерывания», если попытаетесь выполнить переполнение буфера, использующее что-то вроде strcpy или memcpy.

Чтобы отключить его, просто скомпилируйте с флагом -D_FORTIFY_SOURCE=0, например:

gcc -g -fno-stack-protector -D_FORTIFY_SOURCE=0 -o overflow overflow.c

Источник: Отключение защиты от переполнения буфера в GCC .

6 голосов
/ 12 июня 2010

включает

int main(int argc, char **argv) {
    char buffer[4];
    puts("Hello");
    gets(buffer);
    return 0;)
}

и назовите его так:

printf "0123456789abcdefghij\260\037" | ./a.out

\ 260 \ 037 - это адрес main (здесь 0x1fb0) в восьмеричном и младшем порядковом порядке.

Вы должны увидеть hello print два раза перед ошибкой шины. Хитрость заключается в том, чтобы использовать отладчик (даже подойдет gdb), чтобы узнать, где вы хотите оказаться и где находится адрес возврата. Это не будет так же, как в Linux!

MacOS X для i386 (на самом деле большинство ОС для i386, включая Linux и Windows) и особенно <= Leopard - не самая безопасная ОС. </p>

РЕДАКТИРОВАТЬ: только что понял, что я использовал Clang в качестве компилятора. Поэтому вам нужно будет адаптировать его к gcc, но я могу сказать, что он работает с небольшими изменениями: p.

4 голосов
/ 12 июня 2010

Переполнение стека?

Термин переполнение стека относится к ситуации, когда размер стека пытается выйти за пределы максимального предела, допустимого текущей платформой и / или конфигурацией.То, что вы пытаетесь сделать, не имеет никакого отношения к переполнению стека.Если вы хотите увидеть переполнение стека, напишите бесконечно рекурсивную функцию, выполните ее и просто подождите, пока она не переполнится:

void foo() {
  foo();
}

(надеясь, что компилятор не оптимизирует хвостовую рекурсию в цикл. Если это произойдет, сделайте его немного сложнее, не хвостовой рекурсивностью.)

То, что вы, похоже, пытаетесь сделать, это воспроизвести печально известный переполнение буфера эксплойт.Хотя предполагается, что рассматриваемый буфер размещен в стеке, эксплойт никогда не назывался «переполнением стека».Чтобы на самом деле продемонстрировать эксплойт, недостаточно просто выйти за границы некоторого буфера.Все дело в том, чтобы установить заранее определенное значение в области стека, изначально занятой сохраненным адресом возврата, чтобы после завершения функции она «возвращалась» к другому (предположительно вредоносному) коду вместо исходного вызывающего кода..

Итак, что вы пытаетесь сделать?Переполнение стека?Или переполнение буфера?

3 голосов
/ 12 июня 2010

Ваш компилятор в Mac OS скомпилирован в канарейку стека , которая дает вам ловушку прерывания.Найдите в руководстве по компилятору, как его отключить.

С GCC эта опция -fno-stack-protector.

В отдельном примечании переполнение 1 байтом, безусловно, будет недостаточным для запуска чего-либо, кроме проверки стека компилятора.Используйте что-то вроде 12 байтов:)

...