В области компьютерной безопасности и программирования, переполнения буфера (англ. buffer overflow или англ. buffer overrun), это явление, при котором программа, при записи данных в буфер, перезаписывает данные за пределами буфера. Это может вызвать неожиданное поведение, включая ошибки доступа к данным, неверными результатами, сбоем программы или дырой в системе безопасности.
Переполнение буфера может быть вызвано недостаточной проверкой входных данных. Оно является базой для многих уязвимостей в программных продуктах и может быть злонамерено использовано. Дополнительная проверка может предотвратить переполнение буфера, хотя такая проверка отразится на быстродействии программы.
Языки программирования, обычно упоминаемые в связи с переполнением буфера, это в основном C и C++. Они не имеют встроенного механизма против доступа или перезаписи данных в любой части памяти и не осуществляют автоматическую проверку данных, записываемых в массив, на выход за границы массива.
Техническое описание
Переполнение буфера происходит, когда данные, записываемые в буфер, из-за недостаточной проверки, повреждают данные, расположенные за соседними в буфер адресами. Часто это происходит, когда копируется строка из одного буфера в другой.
Базовый пример
В следующем примере программа определила два смежных объекта в памяти: строка, 8 байт длиной, A, и двухбайтовое целое B. Изначально А содержит нулевые байты, а В содержит число 1979. Символы имеют размер один байт.
имя переменной |
A |
B |
значение |
[ пустая строка] |
1979 |
шестнадцатеричное значение |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
07 |
BB |
Теперь, программа пытается сохранить Си-строку excessive в буфер A. Из-за отсутствия проверки на допустимую длину строки, он затирает значение B:
имя переменной |
A |
B |
значение |
'E' |
'X' |
'C' |
'E' |
'S' |
'S' |
'I' |
'V' |
25856 |
шестнадцатеричное значение |
65 |
78 |
63 |
65 |
73 |
73 |
69 |
76 |
65 |
00 |
Хотя программист не собирался изменять значение B, это значение было перезаписано и теперь содержит число, образованное частью строки. В этом случае, на big-endian системе, использующей ASCII , есть и нулевой байт, который сформирует число 25856. Если за B следует недоступный для записи участок памяти, запись еще более длинной строки может привести к ошибке сегментации, что прервет процесс.
Использование
Техники использования уязвимости из-за переполнения буфера зависят от архитектуры, операционной системы и участка памяти. Например, использование кучи отличается от использования стека вызовов.
Использование стека
Технически освещенный и злонамеренный пользователь может использовать стековое переполнение буфера так:
- Для перезаписи локальной переменной, изменив тем самым ход программы на более выгодный для нападающего.
- Для перезаписи адреса возврата в стековом кадре. Когда будет выполнен возврат из функции, выполнение программы возобновится по адресу, указанному нападающим (обычно это адрес буфера поля ввода). Такой способ наиболее распространен в архитектурах, где стек растет вниз (например, в архитектуре x86).
- Для перезаписей указателя на функцию, или обработчика исключений, которые будут выполнены позже.
С методом «трамполайнинга» (англ. trampolining , буквально «прыжки на батуте»), если адрес данных, который ввел пользователь, неизвестен, но их местонахождение хранится в реестре, тогда адрес возврата может быть перезаписан в адрес опкода, который выполнит переход к данным, введенных пользователем. Если их местонахождения хранится в реестре R, тогда нужен скачок в опкод для прыжка R, это вызовет выполнение пользовательских данных. Расположение необходимых опкодов или байт в памяти может быть найдено в динамических библиотеках или самой программе. Адреса опкодов могут меняться между приложениями и версиями ОС. Metasploit Project - одна из баз данных нужных опкодов для Windows.
Не стоит путать стековое переполнение буфера с переполнением стека.
Также заметим, что наличие таких уязвимостей обычно проверяется с помощью фаззинга.
Использование переполнения в куче
Переполнение буфера в куче используется отлично от переполнения в стеке. Память в куче динамически распределяется приложением во время выполнения, как правило, содержит данные программы. Использование происходит из-за повреждения данных особым образом, что приводит к перезаписи внутренних структур данных, таких как связной список указателей.
Уязвимость Microsoft GDI + при обработке JPEG , пример насколько опасной может быть переполнение в куче.
Один из методов предотвращения – использование безопасных библиотек.
Проблема переполнения буфера характерна для языков программирования С и C + +, потому что они не скрывают детали низкоуровневого представления буферов как контейнеров для типов данных. Таким образом, во избежание переполнения буфера, нужно обеспечить высокий уровень контроля за созданием и изменением программного кода, который осуществляет управление буферами. Использование библиотек
абстрактных типов данных, которые выполняют централизованное автоматическое управление буферами и включают в себя проверку на переполнение - один из подходов для предотвращения переполнения буфера.
Два основных типа данных, которые позволяют осуществить переполнение буфера в этих языках - строки и массивы. Таким образом, использование библиотек для строк и списочных структур данных, которые были разработаны для предотвращения и / или выявления переполнений буфера, позволит избежать многих уязвимостей.
Защита пространства машинного кода для Windows
Сейчас существует несколько различных решений, предназначенных для защиты исполняемого кода в системах Windows, которые предлагает компания Майкрософт и сторонние компании.
Майкрософт предложила свое решение под названием DEP (от англ. Data Execution Prevention - «предотвращение выполнения данных»), включил его в пакеты обновления для Windows XP и Windows Server 2003. DEP использует дополнительные возможности новых процессоров Intel и AMD, для преодоления ограничения в 4 ГБ, присущее 32-разрядным процессорам. Для этих целей служебные структуры были увеличены. Эти структуры теперь содержат зарезервированный бит NX. DEP использует этот бит для предотвращения атак, связанным с изменением адреса обработчика исключений (так называемый SEH-эксплойт). DEP обеспечивает только защиту от SEH-эксплойта, он не защищает страницы памяти с исполняемым кодом.
До того, Майкрософт разработала механизм защиты стека, предназначенный для Windows Server 2003. Стек обозначается с помощью элементов (англ. canary), целостность которых проверяется. Если такая отметка была изменена, значит, стек поврежден.
Существуют также решения от других компаний, которые предотвращают выполнению кода, расположенного в областях памяти, предназначенных для данных или реализующих механизм ASLR.