Атака переполнения буфера в Windows приводит к нарушению прав доступа

Я только начал изучать, как работают атаки переполнения буфера, и попытался смоделировать атаку на Windows 7 с помощью Visual C 2010. Атака переполнения буфера очень хитрая, она просто перезаписывает адрес возврата на адрес локальной переменной "buffer". Буфер содержит строку шеллкода.

Независимо от того, запускаю я программу в Visual Studio 2010 Debug или нет, программа перейдет к шелл-коду и почти начнет его выполнение, но я получаю сообщение об ошибке нарушения прав доступа, и программа не будет продолжать выполнение шеллкод.

Почему я получаю эту ошибку? Это какая-то защита от переполнения буфера в Windows?

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

изменить:

Ганс (ответ) правильный. Это обсуждается в главе «Безопасность» Windows Internals 5th, и причиной ошибки является реализация Microsoft исполняемого файла Executable. Защита космоса.

Если этот вопрос кому-то помог, любые голоса будут оценены.

void execute_my_shellcode()
{
    char buffer[24];
    memcpy(buffer, "\x6A\x21\xFF\x15\x40\x62\x40\x00\x83\xC4\x04\x6A\x0A\xFF\x15\x40\x62\x40\x00\x83\xC4\x04\xC3", 24); 
    printf("current return address: %p\n", *(int*)((char*)&buffer + 24 + 4));   
    *(int*)((char*)&buffer + 24 + 4) = (int)&buffer; 
    printf("return address is now : %p\n\n", (int*)*(int*)((char*)&buffer + 24 + 4) );
}

person Community    schedule 10.04.2011    source источник
comment
Как только вы решите проблему NX, не могли бы вы сделать мне одолжение и опубликовать, что происходит, когда вы запускаете исполняемый файл с включенным ASLR на самом исполняемом файле?   -  person user470379    schedule 13.04.2011


Ответы (4)


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

person Hans Passant    schedule 10.04.2011
comment
Нет, их не исправили, их обработали. - person ninjalj; 11.04.2011
comment
Эм, да, массивы C будут сломаны навсегда. - person Hans Passant; 11.04.2011
comment
Ганс, так какая форма защиты используется, когда я получаю это исключение нарушения прав доступа (в режиме отладки Visual Studio)? Это бит неисполнения или что-то еще? Это специфично для Windows? - person T. Webster; 11.04.2011
comment
Вы спрашиваете подробности, на которые может ответить только тот, кто сидит в 3 футах от вашей машины. Я даже не знаю, какой версией Windows вы пользуетесь. Не уверен, почему это важно, разве бит NX недостаточно? - person Hans Passant; 11.04.2011
comment
Бит NX, безусловно, полезен для меня, но я не знаю, является ли это ответом для этого случая, и я просто ищу, какая форма защиты может использоваться в этой ситуации, для понимания, а не для проверки. знание сообщества SO. Я использую Windows 7, программа скомпилирована для платформы Win32. - person T. Webster; 11.04.2011
comment
Это ответ на ваш вопрос. Найдите понимание в Windows Internals 5th edition, отличная книга. - person Hans Passant; 11.04.2011
comment
Ваше понимание приветствуется, как всегда Ганс. Надеюсь, я скоро смогу ответить на свой вопрос. - person T. Webster; 11.04.2011

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

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

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

person Tony The Lion    schedule 10.04.2011

Во-первых, в вашем шеллкоде есть нули. Вернитесь к своему шелл-коду и найдите инструкции, которые не создают нулевые коды операций (0x00), чтобы ваш шелл-код не рассматривался как строка.

Во-вторых, нарушение прав доступа не обязательно означает, что оно является причиной какой-либо схемы защиты. Возможно (по прихоти), ваш обратный адрес или шелл-код пытаются заставить регистр EIP перейти в место, которое не может быть выполнено в памяти.

Вам придется истечь больше. Каждый компилятор и компьютер будут разными. Есть способы обойти почти все. Возможно, вы захотите больше изучить эту тему в целом, но первое, что я бы посоветовал, это создать повторяющийся адрес возврата, который указывает на NOP-след в буфере перед шелл-кодом, чтобы ваш шелл-код выполнялся более эффективно и, вероятно, был более точный.

Защита исполняемого пространства верна, как вы сказали, но мои ответы выше являются неформальными и необходимыми в большинстве случаев. Удачного взлома :)

person Community    schedule 07.05.2012

Где именно ломается программа? Пробовали ли вы использовать OllyDbg для выполнения инструкций по сборке, чтобы увидеть, запускаете ли вы хотя бы выполнение буфера или провал до этого? Если вы не выполняете даже первую инструкцию в буфере, то, вероятно, страница стека (или раздел данных в этом случае, поскольку вы предоставляете его как строковый литерал) помечен как неисполняемый, и вам придется использовать другой метод. . Может быть способ сказать Windows, чтобы сделать страницу стека исполняемой (или раздел данных в этом случае) для целей тестирования/обучения (я знаю, что двоичные файлы ELF имеют исполняемый флаг стека, а Linux предоставляет утилиту execstack для редактирования флага).

Если он ломается после нескольких инструкций из вашего буфера, то, вероятно, инструкции в вашем буфере пытаются (косвенно) вызвать абсолютный адрес (0xff 0x15 0x40 0x62 0x40 x00 => call dword ptr ds:[406240]), а в W7 рандомизация макета адресного пространства (ASLR) может быть включена (я не уверен, что компоновщик VS2010 устанавливает бит IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE в заголовке PE по умолчанию).

Изменить

Основываясь на дополнительной информации, которую вы добавили к вопросу, может показаться, что проблема с неисполняемым стеком, упомянутая в моем первом абзаце, является виновником. Однако, даже если вы обойдете это, вторая проблема все еще может быть проблемой, поскольку вы понятия не имеете, что будет по адресу 0x00406240, если ASLR включен.

person user470379    schedule 10.04.2011
comment
Я добавил уточнение в вопрос, который может помочь. - person T. Webster; 11.04.2011
comment
@Т. Webster Последнее уточнение: самая первая инструкция (0x6a 0x21 => push 21) не работает? Также этот код не будет правильно вызывать puts, предполагая, что 0x00406240 является правильным адресом в таблице адресов импорта для puts. puts принимает один аргумент char*, который вы сначала предоставляете как 0x21, а второй раз как 0x0a. Это означает, что puts попытается вывести строку, расположенную по адресу памяти 0x00000021. Вероятно, вам нужно putchar, которое принимает один 32-битный символ вместо char*? - person user470379; 11.04.2011
comment
ага, я имел в виду путчар. 0x21 - это символ '!'. Ваш ответ полезен, поэтому я проголосовал. - person T. Webster; 11.04.2011
comment
рандомизация макета адресного пространства (ASLR), похоже, здесь не проблема. Я напрямую сохраняю значение адреса буфера [] в местоположении адреса возврата стека. - person T. Webster; 11.04.2011
comment
-1 Он получает фактический адрес &buffer, поэтому ASLR не действует в этой ситуации. - person rook; 11.04.2011
comment
@Rook На самом деле он получает адрес &buffer, но в игру вступают и другие факторы. Если ASLR включен, то базовый адрес образа также может перемещаться, что приведет к перемещению как функций в исполняемом файле, так и записей в IAT. Включение жестко закодированного адреса в IAT (или другой функции в исполняемом файле, что, как я думал, имело место в то время) в большинстве случаев будет вызывать нарушения прав доступа. - person user470379; 11.04.2011
comment
@user470379 шеллкод должен быть независимым от адреса, вам просто нужно найти его в памяти. Но смотри, у нас есть: &buffer, проблема решена. - person rook; 11.04.2011
comment
Шелл-код @Rook не зависит от адреса. Именно в этом суть!!! Разобрать код с начала -- [\x6A\x21 =› push 21; \xFF\x15\x40\x62\x40\x00 => call [00406240]] и так далее. call [00406240] НЕ не зависит от адреса. Предполагается, что IAT всегда находится в одном и том же месте, что НЕ в случае с ASLR. Этот код выполнит ошибку, даже если страница стека помечена как исполняемая, когда для приложения включен ASLR (если только вам не повезет). Это не универсальный шеллкод, либо его написал OP, либо взял нестандартный пример из учебника. - person user470379; 11.04.2011
comment
@Rook Я не оспариваю тот факт, находит ли OP начало шелл-кода. Он, очевидно, есть. Проблема в том, что шеллкод ссылается на абсолютные адреса. Как только OP выполняет вторую инструкцию в адресном пространстве исполняемого файла с включенным ASLR, все ставки снимаются. - person user470379; 11.04.2011