Атаки переполнения стековой памяти


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

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

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

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


Что такое стек?



Стек - структура данных, где содержится важная информация для активных процессов. Стек работает наподобие сверхоперативной памяти системы. Система делает необходимые ей пометки, которые нужно сохранить, и помещает их в стек - специальную зарезервированную область памяти. Стеки похожи на стопку посуды, так как работают по принципу «последним вошел, первым вышел» (Last-In, Firts-Out - LIFO).

Когда вы собираете стопку посуды, вы кладете одну тарелку на другую. Когда же требуется убрать тарелку из стопки, сначала вы возьмете верхнюю тарелку - ту, которую вы положили последней. Аналогично, если система помещает данные в стек, элементы стека один за другим перемещаются вниз. При необходимости получить данные из стека система возьмет сначала последний помещенный ею в стек элемент.

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

Когда начинается работа программы, выполняется процедура main. Первое, что делает эта процедура, - вызывает функцию sample_function. Теперь реализация программы представляет собой взаимодействие процедуры main и функции sample_function. Система должна запомнить, когда приостановилось выполнение процедуры main, потому что после завершения sample_function программа к ней вернется. Стек помогает организовать переход к функции и возврат к процедуре.

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

Программа представляет собой набор битов в памяти компьютера, группу команд для процессора. У процессора есть регистр (небольшая часть быстродействующей памяти процессора), который называется указателем команды (instruction pointer): он обозначает команду, которую должен выполнить процессор.

Во время выполнения программы значение этого указателя постепенно возрастает, переходя от одной команды программы к другой, а при вызове функции увеличивается на определенное число. Для вызова процедуры система должна запомнить величину указателя команды, чтобы знать, к какой части процедуры main возвращаться после завершения функции. Указатель команды записывается в стек в качестве указателя возврата.

Затем система отправляет в стек указатель фрейма. Данная величина позволяет обращаться к различным элементам стека. И наконец, в стеке освобождается место для переменных, которые могут использоваться функцией. В нашем примере в стек была помещена локальная переменная buffer. Такие локальные переменные применяются только функцией, которая хранит в них данные и обрабатывает их значения.

После завершения работы функции (в нашем примере на печать будет выведено радостное сообщение) контроль возвращается к основной программе. При этом из стека убираются локальные переменные (в примере - переменная buffer). Для большей эффективности часть памяти, выделенная под переменные, не стирается. Данные убираются из стека, при этом значение указателя изменяется - теперь оно становится равным значению, которое было до вызова функции.

Сохраненный указатель фрейма также удаляется из стека и передается процессору. Затем из стека извлекается указатель возврата, который помещается в регистр указателя команды процессора. И наконец, удаляются аргументы вызова функции, стек возвращается в исходное положение. С этого момента система продолжает выполнение процедуры main - так требует указатель команды.


Автор: pimka21

Еще советуем:
  • Безопасность компьютера: обман IDS
  • Что такое переполнение буфера памяти
  • Защита от переполнения буфера памяти
  • Стековая память: как защитить ее от переполнения
  • Безопасность компьютера: атаки на приложения и операционные системы