Методика динамического анализа уязвимостей в бинарном коде
Автор: Шудрак Максим Олегович, Золотарев Вячеслав Владимирович, Лубкин Иван Александрович
Журнал: Сибирский аэрокосмический журнал @vestnik-sibsau
Рубрика: Математика, механика, информатика
Статья в выпуске: 4 (50), 2013 года.
Бесплатный доступ
Описывается методика и ее реализация в виде программного продукта, осуществляющая обнаружение уязвимостей в бинарном коде с использованием сочетания технологий динамической бинарной инструментации, анализа покрытия кода и так называемого фаззинга - технологии генерации потенциально ошибочных данных и мониторинга результата. В результате было разработано программное средство для поиска уязвимостей в сетевых и файловых приложениях, позволяющая значительно оптимизировать процесс динамического тестирования.
Динамический анализ, уязвимость, фаззинг, бинарная инструментация
Короткий адрес: https://sciup.org/148177165
IDR: 148177165
Текст научной статьи Методика динамического анализа уязвимостей в бинарном коде
На сегодняшний день компании-разработчики ПО сталкиваются с серьёзнейшими рисками, связанными с безопасностью собственных продуктов. Эти риски возникают вследствие того, что процесс разработки невозможен без тех или иных ошибок и недочетов. Так, за предыдущий год эксперты обнаружили более 9 000 различных уязвимостей «нулевого дня», а это 26 уязвимостей в день! Для решения этой проблемы используется множество различных методик и подходов, которые могут эффективно применяться на том или ином этапе разработки и эксплуатации ПО [1]. В данной статье мы остановимся лишь на динамическом анализе, являющемся наиболее эффективным для анализа бинарного кода, так как метод взаимодействует с реально работающим приложением [2; 3]. Наиболее существенным недостатком динамического анализа на сегодняшний день является сложность и высокая ресурсозатратность для полноценного поиска уязвимостей. Мы попытаемся частично решить эти проблемы.
Методика гибридного анализа бинарного кода. Методика динамической бинарной инструментации предусматривает проведение тестирования приложения в процессе его исполнения. Как правило, уязвимость в ПО возникает в процессе обработки внешних или пользовательских данных. Для тестирования корректности обработки этих данных часто используется так называемая технология фаззинга, базовая схема которого приведена на рис. 1.

Рис. 1. Базовая схема системы
Опишем технологию динамического анализа и проведем сравнительный анализ полученного решения. Процесс динамического анализа ПО подразумевает анализ продукта в процессе его работы. Такой подход позволяет обнаружить ошибки и уязвимости, возникающие в процессе работы, которые непосредственно доступны для эксплуатации. Для этого система на основе предварительно описанного протокола автоматически генерирует тестовые данные и посылает их в выбранный интерфейс. Затем специальный модуль производит мониторинг исполняемых инструкций (строк кода) и ошибок в процессе выполнения программы. Однако необходимо отметить, что ис- пользование такой технологии значительно снижает производительность анализируемой программы. Для решения этой проблемы в рамках проекта было предложено использовать методику динамической бинарной инструментации (DBI) анализируемого модуля. Основная схема методики приведена на рис. 2.
kfctidlwriMtai hacked пт
_______Jl_______
! Itatapplcation 1
Launcher (main application)
Instruction 1
Jmp ^addrldll
Instruction 2

DB DLL
Wte sixrriri hank and П11
Рис. 2. Описание технологии DBI
Ее идея заключается в возможности перехвата и анализа графа потока управления программы с помощью вставки специальных инструкций в бинарный код анализируемого приложения. Эксперименты показали, что применение DBI позволяет анализировать программу на несколько порядков быстрее, чем при использовании классических методик автоматизированной отладки. Сравнение производительности выбранного решения приведено на рис. 3.
Для повышения гибкости описываемая платформа должна обладать возможностью описания протокола генерации тестовых кейсов с помощью специального языка. Для решения этой задачи был задействован хорошо зарекомендовавший себя ранее блоковый подход к описанию данных. Такой подход частично схож с описанием скриптов в классических языках программирования, однако в значительно урезанном виде. Тестовый пример и общее описание языковых конструкций приведено на рис. 4.
Помимо динамического анализа в процессе тестирования используются элементы методики статического анализа на этапе оценки степени опасности найденной ошибки. Для этого участок исходного или декомпилированного кода, на котором произошла ошибка, сравнивается с шаблонами уязвимого кода и в случае наличия совпадений производится классификация степени опасности данной уязвимости в соответствии с CVSS (Common Vulnerability Scoring System).
Отдельно необходимо остановиться на системе декомпиляции бинарного кода (декомпиляция – процесс восстановления относительно эквивалентного исходного кода из исполняемого модуля) в случае отсутствия исходного. Анализ бинарного кода является нетривиальной задачей в силу того, что в процессе компиляции исходного кода программы теряется важная с точки зрения анализа информация. Процесс анализа бинарного кода требует некоторого уровня его абстракции от машинного кода к человеку. Таким образом, основная идея заключается в том, что декомпиляция бинарного кода не требует представления машинного кода на языке высокого уровня, достаточно восстановить алгоритм функционирования участка анализируемого кода (тем самым добиться соответствующего уровня абстракции). Для решения этой задачи необходимо рассматривать бинарные инструкции как совокупность элементарных операций над ресурсами, где в качестве ресурса могут выступать регистры, память или регистры флагов процессора.
Апробация технологии. Одним из самых важных требований, предъявляемых к системе, является возможность ее использования в различных операцион- ных системах. Для этого было принято решение максимально (где это возможно) использовать кросс-платформенный язык программирования Python, а где невозможно – C/C++. Такой выбор был продиктован тем, что наряду со своими широкими возможностями, язык Python позволяет легко интегрироваться в проекты на C/C++. Для решения задачи отображения информации была реализована библиотека визуализации графа потока выполнения программы с возможностью фильтрации необходимой информации об уязвимых участках тестируемой программы. Пример детектирования уязвимости в тестовом FTP-сервере приведен на рис. 4.

Рис. 3. Сравнение производительности решения

Рис. 4. Пример детектирования уязвимости
Ключевым этапом, отображенным на схеме, является генерация данных и анализ покрытия кода, который необходим для оценки эффективности проведенного тестирования. Не будем подробно останавливаться на каждом этапе работы системы, лишь отметим, что цель анализатора – сгенерировать данные, которые приведут к ошибке в тестируемом приложении. Для оценки эффективности такого тестирования необходимо оценить степень покрытия бинарного кода тестами. В ходе работы над программным средством были протестированы различные решения оценки покрытия кода: от отладки до динамической бинарной инструментации [4]. Последняя технология показала наиболее значительный прирост к скорости анализа (на 3–4 порядка в сравнении с отладкой). DBI-технология использует виртуальную машину уровня процесса ОС, в которую внедряется специальная dll, описывающая то, как необходимо проводить анализ тестируемой программы. Такая схема позволяет в значительной степени оптимизировать анализ, так как операционной системе нет необходимости в переключении контекста процессора между анализатором и тестируемой программой.
Разработанная система была реализована с использованием следующих фреймворков:
-
1) Sulley-фреймворк – для генерации тестовых данных [5].
-
2) Intel PIN – DBI фреймворк для виртуализации тестируемого приложения [6].
-
3) библиотека PyDBG – для отладки тестируемого приложения и перехвата исключений.
Таким образом, авторами была разработана методика и программное средство, обладающее возможностью тестирования различных приложений, обрабатывающих сетевой трафик и различные пользовательские файлы. На данный момент проект находится в стадии альфа-тестирования. Дальнейшая работа пред- полагает расширение числа доступных протоколов для тестирования, использование более эффективных методик анализа покрытия кода, а также применение интеллектуальных алгоритмов для генерации тестовых данных с учетом результатов покрытия кода тестами.
В заключение хотелось бы отметить, что поиск уязвимостей является на сегодняшний день очень важным и необходимым этапом жизненного цикла разработки и поддержки ПО.