Сокрушительная атака Андрей Семенюченко Спецвыпуск: Хакер, номер #058, стр. 058-010-2 Поскольку большинство эксплойтов содержат инструкции NOP в своих массивах, многие средства обнаружения атак могут идентифицировать злоумышленника по этим инструкциям. Переполнение буфера Итак, что же это за зверь - "переполнение буфера"? Это понятие появилось одновременно с архитектурой Фон Неймана. Впервые широкую известность оно получило в 1988 году вместе с интернет-червем Мурса. Во многих языках программирования, например в распространенном С, не выполняется автоматическая проверка границ в массивах или указателях – вот это и есть проблема переполнения буфера. Кроме того, стандартная библиотека С полна очень опасных функций, примеры которых есть на соответствующей врезке. При автоматическом выделении памяти для передачи аргументов процедурам и сохранения локальных переменных используется хранилище, называемое стеком и которое является буфером типа LIFO (последним вошел - первым вышел). Когда программа вызывает функцию, создается новая "граница стека", которая состоит из аргументов, переданных в функцию, а также динамического количества пространства локальных переменных. Существует несколько регистров процессора по управлению стеком. "Указатель стека" является регистром, хранящим текущее положение вершины стека. С помещением новых значений переменных в стек значение этого регистра изменяется, поэтому был реализован регистр "указатель границы", который расположен около начала стека, так что локальные переменные можно легко адресовать относительно этого значения. Адрес возврата из функции также сохраняется в стеке, что вызывает нарушение безопасности, связанное с переполнением стека, так как перезаписывание локальной переменной в функции может изменить адрес возврата из этой функции, потенциально позволяя злоумышленнику выполнить любой код. Для ядра Linux существуют патчи (PaX и ExecShield), препятствующие выполнению большинства эксплойтов. Виды переполнения Уже был рассмотрен частный случай переполнения буфера - переполнение стека, которое может произойти при автоматическом выделении памяти. Переполнения автоматических буферов наиболее распространены. Размер таких буферов определяется на этапе компиляции. Процедура проверки корректности обрабатываемых данных в этом случае ложится на плечи программистов, часто отсутствует или реализована с грубыми ошибками. Переполнение происходит из-за присутствия в непосредственной близости от автоматических буферов адреса возврата из функции, модификация которого позволяет злоумышленнику осуществить передачу управления на произвольный код. При статическом выделении памяти происходит выделение памяти под данные внутри сегмента данных программы. Такие данные существуют на протяжении всей жизни программы до ее завершения. В случае неосторожного обращения программист может сильно облегчить работу хакера, так как при данном подходе к выделению памяти это единственный тип буферов, адреса которых явно задаются еще на этапе компиляции. В результате может произойти переполнение в секции данных. |