
- •Томский государственный университет систем управления и радиоэлектроники (тусур)
- •Обзор уязвимостей программной части. Способы их обнаружения и устранения
- •Содержание
- •1 Введение
- •2 Классификация уязвимостей
- •3 Методы обнаружения уязвимостей
- •3.1 Ручной поиск
- •3.2 Поиск по шаблонам
- •3.3 Фазинг
- •4 Способы устранения уязвимостей
- •4.1 Корректировка исходных кодов программ
- •4.2 Использование неисполняемых буферов
- •4.3 Применение проверок выхода за границы
- •4.4 Решение проблемы неинициализированных данных
- •4.5 Защита от sql-инъекций
- •4.6 Защита от xss-инъекций
- •4.7 Шифрование паролей
- •Заключение
- •Список использованных источников
4 Способы устранения уязвимостей
После того как уязвимости программы были найдены их необходимо устранить. Ликвидировать найденные уязвимости приходиться в основном самому разработчику программы или просто обычному кодировщику в чьи руки попала данная программа, но не обходится и без использования алгоритмов или даже целых программ или утилит.
Самой распространенной уязвимостью программы всегда являлось переполнение буфера памяти. Для решения данной проблемы используется несколько способов защиты.
4.1 Корректировка исходных кодов программ
Переполнение буфера происходит, прежде всего, из-за неправильного алгоритма работы программы, который не предусматривает проверок выхода за границы буферов. Также особую роль здесь играют C-подобные языки программирования (такие как C++, Fortran, Java и др.). Так как они не содержат средств контроля соответствия типов, то в переменную одного типа можно занести значение другого типа. Стандартные функции этих языков, например для C это strcpy, sprintf, gets, работают со строками символов и не имеют в качестве аргументов их размеров, что легко приводит к переполнению буфера. Сложившийся годами стиль программирования более ориентированный на производительность программ, без выполнения дополнительных проверок также является причиной распространения данной уязвимости. В результате чего, для программистов выработан ряд методик и указаний по написанию программ, не содержащих уязвимостей. Сформированы рекомендации по исправлению уже существующих программ. Созданы и постоянно возникают новые команды-объединения программистов по аудиту и исправлению кода существующих программ. Существуют гибкие средства, автоматически выполняющие действия имитирующие переполнение буфера на этапе отладки программы. Также следует упомянуть об утилитах автоматического поиска уязвимостей в исходном коде программы. Указанные методы и средства позволяют создавать более защищенные программы, но не решают проблему в принципе, а лишь минимизируют число уязвимостей по переполнению буфера. К недостаткам следует отнести и то, что данный подход ориентирован непосредственно на разработчиков программного обеспечения и не является инструментом конечного пользователя или системного администратора.
4.2 Использование неисполняемых буферов
Суть метода заключается в запрещении исполнения кода в сегментах данных и стека, т.е. параметры сегментов данных и стека содержат только атрибуты записи и чтения, но не исполнения. Однако ограничение на исполнение данных приводит к проблеме несовместимости. Исполняемый стек необходим для работы многим программам, так как на его основе генерируется код компиляторами, реализуются системные функции операционных систем, реализуется автоматическая генерация кода. Защита с использованием неисполнимых буферов предотвратит только атаки с внедрением кода, но не поможет при других видах атак.
4.3 Применение проверок выхода за границы
В основе данного метода лежит выполнение проверок выхода за границы переменной при каждом обращении к ней. Это предотвращает все возможные атаки по переполнению буфера, так как полностью исключает само переполнение. Проверки выхода за границы переменной опционально реализованы в некоторых компиляторах языков программирования, например, в таких как C, C++, Java и др. Следует отметить, что реализованные проверки ограничены только точными ссылками на элементы массивов, но не производятся для указателей. Существует также “заплатка” для gcc, которая позволяет компилировать программы с полностью реализованной (включая проверку указателей) проверкой выхода за границы массивов. Однако, у этого решения есть существенный недостаток – значительное (до 30 раз) снижение производительности программы. Другие системы осуществляют проверки при доступе к памяти, выполняя вставки дополнительного объектного кода проверок во все места программы, где есть обращения к памяти. Такие проверки сказываются на производительности с ее уменьшением от 2 до 5 раз и скорее подходят для отладки.