Если ваш стек и куча не исполняются, как ваш код может работать?
Я прочитал книгу о переполнении буфера, и это предлагает следующее:
Выполнение неиспользуемого стека (и кучи) обеспечивает высокую степень защита от многих типов атак переполнения буфера для существующих программы.
Но я не понимаю, как мы можем это сделать - где выполняется выполнение, если не в куче или в стеке?
Ответы
Ответ 1
Если я правильно понимаю ваш вопрос, ни один из других ответов не обращается к нему. Ответ заключается в том, что выполнение происходит в секции кода, которая не является ни стеком, ни кучей. В типичной системе выгружаемой памяти код из файла программы (например,.exe в Windows) загружается в исполняемые, но только для чтения страницы. Дополнительные записываемые (и исполняемые) страницы выделяются процессу для стека и кучи. Предложение здесь состоит в том, что операционная система и аппаратное обеспечение должны взаимодействовать, чтобы отметить эти страницы, доступные для записи, но не исполняемые (ответ rgngl объясняет, как это сделать в Windows).
Даже при неисполняемой куче и стеке все еще возможны эксплойты, которые используют обратное ориентированное программирование, упомянутое в ответе Алексея Фрунзе, но есть методы защиты, которые замалчивают даже такие, как ранняя ранжирование с разбивкой по стеклу и адресная пространственная компоновка - см. http://en.wikipedia.org/wiki/Return-to-libc_attack#Protection_from_return-to-libc_attacks
Ответ 2
Вот что называется подпрограммой типа "обратное ориентированное программирование" (AKA ROP).
Злоумышленник находит, как сделать его злой код из разных частей используемой программы.
Он находит используемые байтовые последовательности (инструкции) перед байтами (-ами) возврата, которые могут делать полезные операции над регистрами или памятью, например, перемещать значение в местоположение, добавлять значения, сравнивать значения и т.д. Это те микро-подпрограммы, которые эксплоит строится из.
Затем, используя ошибку кода, злоумышленник заставляет программу начать выполнение цепочки тех микро-подпрограмм, которые выполняют все зло.
Итак, теперь хороший код превращается в злой код. Ничего не выполняется в стеке или в куче.
Также следует отметить, что на процессорах, где инструкции охватывают несколько байтов и имеют переменную длину, даже непосредственные операнды команд (IOW, численные константы), которые являются частью инструкций, могут стать кодом, и поэтому шансы найти используемые байтовые последовательности выше, чем на "более простых" процессорах.
Также часто можно создавать вредоносный код, который изменит защиту памяти, и эксплойт уже не будет ограничиваться существующим кодом приложения.
Ответ 3
Очень конкретный пример: упорядочьте адрес возврата, чтобы указать на system
, а следующий слот в стеке (или первый регистр аргумента на перекрестных регистрах) должен быть указателем на строку "/bin/sh"
.
Ответ 4
Такая защита обеспечивается ОС и не может быть выполнена на прикладном уровне.
См. статью wikipedia, в которой также рассказывается, как включить ее под Windows: http://en.wikipedia.org/wiki/Data_Execution_Prevention
Ответ 5
вы можете перейти в любое другое место, которое является исполняемым сегментом, и запустить ваш злой код...
В конце концов, все данные на любом хранилище, память - это биты и биты, которые могут быть инструкциями для процессора.
Ответ 6
Вы можете использовать переполнение для перезаписывания обратного адреса функции, которая может перейти на какой-то известный адрес с вашим кодом на нем. Но тогда авторы ОС ответили, что рандомизация кода адреса выполняется на...
Ответ 7
Ваш код выполняется в текстовом сегменте, а не в стеке или куче (оба из них предназначены для хранения данных). Таким образом, организация:
<highest addresses>
stack
...
heap
data section (initialized data & bss - uninitialized data)
code section (text)
<lowest addresses>
Раздел кода является исполняемым, но неизменным. Эта статья в Википедии содержит более подробную информацию: https://en.wikipedia.org/wiki/Data_segment