Методологическое обеспечение автоматизированного обнаружения ошибок и недокументированных возможностей в программном обеспечении тема диссертации и автореферата по ВАК РФ 00.00.00, доктор наук Самарин Николай Николаевич
- Специальность ВАК РФ00.00.00
- Количество страниц 278
Оглавление диссертации доктор наук Самарин Николай Николаевич
ВВЕДЕНИЕ
1 СРАВНИТЕЛЬНЫЙ АНАЛИЗ МЕТОДОВ ПОИСКА ОШИБОК И НДВ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ, ПРЕДСТАВЛЕННОМ В ВИДЕ БИНАРНЫХ ФАЙЛОВ
1.1 Классификация методов поиска ошибок и НДВ в ПО
1.2 Исследования, посвящённые применению методов статического анализа для обнаружения ошибок и НДВ в ПО
1.3 Исследования, посвящённые применению методов динамического анализа для обнаружения ошибок и НДВ в ПО
1.4 Фаззинг-тестирование
1.5 Выводы
2 Методология автоматизированного поиска ошибок и НДВ в программном обеспечении, представленном в виде бинарных файлов
2.1 Графовая модель функционирования бинарного ПО
2.1.1 Анализ источников по заданной тематике
2.1.2 Описание графовой модели
2.2 Постановка задачи поиска ошибок и НДВ в ПО, представленном в виде бинарных файлов
2.3 Описание методологии автоматизированного поиска ошибок и НДВ в программном обеспечении
2.3.1 Метод поиска ошибок и НДВ в программном коде на основе точечного фаззинг-тестирования и механизма общих симуляций
2.3.2 Метод оценки достижимости фрагментов программного кода на основе сочетания прямого и обратного символьного исполнения
2.3.3 Принципы, методы и процедуры, используемые при построении методологии
2.3.4 Практические аспекты реализации методологии
2.4 Представление программы в терминах графовой модели
2.5 Выводы
3 Подготовка данных для проведения фаззинг-тестирования
3.1 Анализ источников, посвящённых задаче формирования наборов данных для фаззинг-тестирования
3.1.1 Метод случайных мутаций
3.1.2 Мутации с обратной связью
3.1.3 Техники машинного обучения и глубокого обучения
3.1.4 Эволюционные мутации
3.2 Интеллектуальный метод мутации входных корпусов с обратной связью
3.2.1 Процесс мутации входных корпусов
3.2.2 Возможности искусственной нейронной сети с долгой краткосрочной памятью
3.2.3 Описание метода мутации
3.2.4 Примеры работы метода
3.3 Метод генерации некорректных данных для проведения фаззинг-тестирования приложений с помощью NFC
3.3.1 Передача данных с помощью NFC
3.3.2 Создание конфликтов
3.3.3 Описание работы метода
3.4 Выводы
4 Метод поиска ошибок и НДВ в программном коде на основе точечного фаззинг-тестирования и механизма общих симуляций
4.1 Описание метода
4.2 Механизм общих симуляций
4.3 Стратегии выбора фрагментов программного кода для фаззинга
4.4 Примеры работы метода
4.5 Выводы
5 Метод оценки достижимости фрагментов программного кода на основе сочетания прямого и обратного символьного исполнения
5.1 Удаление недостижимых фрагментов программного кода
5.2 Описание метода
5.2.1 Описание работы метода в терминах теории графов
5.2.2 Техническое описание работы метода
5.2.3 Пример работы предлагаемого метода
5.3 Выводы
6 Архитектура и принципы функционирования ПАК автоматизированного обнаружения ошибок и НДВ в программном обеспечении
6.1 Анализ существующих работ по тематике
6.2 Требования к предлагаемому ПАК для поиска ошибок и НДВ в программном обеспечении
6.3 Архитектура ПАК автоматизированного обнаружения ошибок и НДВ в программном обеспечении как технологический стек
6.3.1 Модуль сбора и предварительной обработки данных
6.3.2 Модуль определения множества фрагментов программного кода, подлежащих тестированию
6.3.3 Модуль фаззинг-тестирования
6.3.4 Модуль оценки достижимости
6.3.5 Модуль обработки и представления результатов
6.4 Оценка покрытия кода при проведении фаззинг-тестирования
6.4.1 Аппаратная виртуализация
6.4.2 Методы оценки покрытия кода на базе виртуализации
6.4.3 Описание метода
6.5 Экспериментальные исследования метода фаззинг-тестирования
6.5.1 Фаззер AFL++ как образец сравнения с разработанным ПАК
6.5.2 Результаты тестирования предлагаемого программного комплекса поиска ошибок и уязвимостей в программном обеспечении
6.6 Выводы
ЗАКЛЮЧЕНИЕ
СПИСОК ЛИТЕРАТУРЫ
ПРИЛОЖЕНИЕ А Пример небезопасного кода, содержащего уязвимость типа «запись за границами массива»
ПРИЛОЖЕНИЕ Б Пример небезопасного кода, содержащего уязвимость
типа «переполнение буфера»
ПРИЛОЖЕНИЕ В Акт о внедрении результатов работы в научно-
исследовательскую деятельность в/ч
ПРИЛОЖЕНИЕ Г Акт об использовании результатов работы в деятельности
МЧС России
ПРИЛОЖЕНИЕ Д Акт о внедрении результатов работы в проектную
деятельность «Специальное агентство «ОМЕГА»
ПРИЛОЖЕНИЕ Е Акт об использовании результатов работы в проектной
деятельности ООО «НТП «Криптософт»
ПРИЛОЖЕНИЕ Ж Акт об использовании результатов работы в научной и
проектной деятельности ООО «ЭР СИ О»
ПРИЛОЖЕНИЕ И Акт об использовании результатов работы в проектной
деятельности АО «Синтелс»
ПРИЛОЖЕНИЕ К Акт об использовании результатов работы в учебном процессе МТУСИ
Рекомендованный список диссертаций по специальности «Другие cпециальности», 00.00.00 шифр ВАК
Методы оптимизации алгоритмов статического и динамического анализа программ2024 год, доктор наук Саргсян Севак Сеникович
Поиск ошибок в бинарном коде методами динамической символьной интерпретации2022 год, кандидат наук Вишняков Алексей Вадимович
Метод генерации семантически корректного кода для фаззинг-тестирования JavaScript-интерпретаторов на основе мутации АСД фрагментов кода2024 год, кандидат наук Ерохина Наталья Сергеевна
Разработка нового метода автоматизированного тестирования программных библиотек2023 год, кандидат наук Чан Ти Тхиен
Высокопараллельная система выявления сетевых уязвимостей на основе генетических алгоритмов2013 год, кандидат наук Печенкин, Александр Игоревич
Введение диссертации (часть автореферата) на тему «Методологическое обеспечение автоматизированного обнаружения ошибок и недокументированных возможностей в программном обеспечении»
ВВЕДЕНИЕ
Актуальность темы исследования. Цифровизация технологической инфраструктуры, автоматизация процессов, мониторинг и контроль функционирования сложных систем различных отраслей деятельности реализуются с использованием сложного многофункционального программного обеспечения (ПО).
Необходимость в разработке и внедрении ПО возникает практически на любой стадии работы информационно-технической системы. При этом в отношении отечественного рынка ПО наблюдается тенденция к импортозамещению и созданию программных решений всех типов, что делает актуальными задачи повышения качества разрабатываемого ПО, обеспечения совместимости с другими программными решениями и различным аппаратным оборудованием, созданием экосистем, направленных на обеспечение непрерывного развития и поддержки создаваемых решений. Исследования компании Notamedia [1] демонстрируют устойчивый рост российского рынка разработки ПО, также прогнозируется ускорение темпов роста до 13-15% в год до 2028 года.
Однако высокий темп создания новых программных решений ведет к увеличению объёма программного кода, повышению его сложности за счёт многочисленных внутренних связей и зависимостей, риску возникновения различного рода дефектов - ошибок, уязвимостей, недокументированных возможностей (НДВ). Все эти дефекты могут быть использованы злоумышленниками при реализации компьютерных атак на инфраструктуру организаций, что может привести к неблагоприятным последствиям разной степени критичности - от финансового ущерба в связи с нарушением операционной деятельности организаций до раскрытия конфиденциальной
информации, составляющей государственную тайну, при использовании дефектов в программных решениях, интегрированных с инфраструктурой государственных учреждений. Опасность такой угрозы подчеркивается всё большим числом регистрируемых CVE [2]: так, по данным компании по информационной безопасности Qualys, за первое полугодие 2024 года число зарегистрированных общих уязвимостей и рисков (CVE) выросло на 30% по сравнению с 2023 годом и составило 22 254.
Таким образом, активный перенос бизнес- и функциональной логики на ПО в совокупности с остростоящими вопросами импортозамещения и доверенности программно-аппаратной базы, защищенности информационных систем от киберугроз определяет высокую актуальность проблемы обнаружения ошибок и НДВ в ПО.
Решение поставленной технической проблемы затруднено в связи с большим объёмом программного кода, сильной разветвлённостью структуры современного ПО, сложностью автоматизации современных техник обнаружения ошибок и НДВ в ПО, а также их недостаточной эффективностью с точки зрения полноты покрытия кода, скорости анализа ПО и достоверности обнаруженных ошибок.
Вышеобозначенные проблемы требуют создания комплекса научно -технических решений, совокупно обеспечивающих высокую производительность поиска ошибок и НДВ, полноту покрытия целевых участков кода и оценку достоверности обнаруженных ошибок и НДВ наряду с минимизацией вовлеченности в данный процесс человека.
В настоящей работе предпринята попытка создания методологии обнаружения ошибок и НДВ в бинарных файлах ПО, направленной на производительный автоматизированный анализ бинарного кода и обеспечивающей целенаправленность тестирования с единовременной оценкой достижимости для подтверждения достоверности выявленных дефектов.
В основе методологии лежит модифицированная техника фаззинг-тестирования в памяти в сочетании с прямым и обратным символьным исполнением, что в совокупности с графовым описанием процесса функционирования ПО делает её применимой для бинарного ПО различного назначения.
Степень разработанности темы исследования. Научным и методологическим вопросам автоматизированного обнаружения ошибок и НДВ в ПО посвящены работы таких ученых как Румянцев К.Е., Котенко И.В., Язов Ю.К., Тихонова А.Ю., Seas, C. и др. Математические аспекты формального представления задач безопасности, в том числе, графовые методы для моделирования сетевых структур рассмотрены в работах Бурдонова И.Б., Звонарева С.В. Wang H. и др. Вопросы безопасной разработки и применение техники фаззинга для выявления ошибок и НДВ были рассмотрено в работах Басараба М.А., Падаряна В.А., Епишкиной А.В., Reiter А., Böhme M. и др.
Объектом исследования является ПО, представленное в виде исполняемых бинарных файлов.
Предметом исследования являются методы поиска ошибок и НДВ в ПО, представленном в виде исполняемых бинарных файлов, в частности, методы фаззинг-тестирования и подходы к их автоматизации.
Цель исследования состоит в единовременном увеличении скорости анализа ПО, представленного в виде бинарных файлов, обеспечении целенаправленного тестирования заданных участков программного кода и подтверждении достоверности найденных ошибок и НДВ за счёт применения техники фаззинг-тестирования в памяти в сочетании с прямым и обратным символьным исполнением.
В данной работе под достоверностью ошибок и НДВ следует понимать возможность создания злоумышленником условий, потенциально позволяющих ему достигнуть целевого участка кода и воздействовать на соответствующие регистры и области памяти таким образом, что возникнет искомая ошибка/НДВ.
Для достижения вышеуказанной цели представляется необходимым решить следующие задачи:
1. Выполнить сравнение современных методов поиска ошибок и НДВ в ПО, представленном в виде бинарных файлов, обосновать перспективность техники фаззинг-тестирования и выделить методы фаззинг-тестирования, наиболее перспективные с точки зрения увеличения производительности и целенаправленности тестирования.
2. Описать ключевые положения методологии автоматизированного поиска ошибок и НДВ в программном коде бинарных образцов ПО, обеспечивающей целенаправленное тестирование отдельных участков кода и оценку достоверности найденных дефектов.
3. Разработать математическую модель функционирования бинарного ПО, универсальную относительно типа ПО и обеспечивающую построение на её основе методов поиска ошибок и НДВ в ПО с применением фаззинг-тестирования.
4. Разработать метод поиска ошибок и НДВ в программном коде бинарных образцов ПО на основе модифицированной техники фаззинг-тестирования в памяти, расширяющей спектр обнаруживаемых ошибок.
5. Разработать метод оценки достижимости фрагментов программного кода с применением прямого и обратного символьного исполнения, определяющий достоверность выявленных ошибок и НДВ.
6. Спроектировать архитектуру программного-аппаратного комплекса (ПАК) автоматизированного обнаружения ошибок и НДВ в ПО, обеспечивающую возможность функционального расширения и снижающую сложность фаззинг-тестирования.
7. Реализовать экспериментальный прототип ПАК для оценки результативности предложенной методологии выявления ошибок и НДВ в ПО, представленном в виде бинарных файлов.
Научная новизна результатов:
1. Впервые предложена методология автоматизированного поиска ошибок в программном коде бинарных образцов ПО, в основе которой лежат
универсальная графовая модель функционирования бинарного ПО, модифицированная техника фаззинг-тестирования в памяти и сочетание прямого и обратного символьного исполнения, совокупно обеспечивающие автоматизацию и целенаправленность тестирования ПО на предмет обнаружения ошибок и НДВ, а также оценку достижимости найденных дефектов.
2. Впервые предложена графовая модель, обеспечивающая возможность единовременного описания процессов фаззинг-тестирования в памяти и символьного исполнения (прямого и обратного) за счёт низкоуровневого описания функционирования ПО на уровне базовых блоков, регистров процессора и памяти.
3. Предложен новый метод оценки достижимости фрагментов программного кода с применением прямого и обратного символьного исполнения, определяющий достоверность выявленных ошибок и НДВ, за счёт чего достигается снижение числа ложных срабатываний, характерных для фаззинг-тестирования в памяти.
4. Предложен метод точечного фаззинг-тестирования, расширяющий возможности фаззинга в памяти и устраняющий ряд его значимых недостатков за счёт использования механизма общих симуляций, в результате чего обеспечивается возможность обнаружения ошибок различных типов и целенаправленное тестирование заданных участков программного кода.
Теоретическая значимость работы заключается в создании оригинальной методологии, обеспечивающей возможность универсального тестирования бинарного ПО за счёт: графового представления функционирования ПО в его низкоуровневом виде; техники точечного фаззинга, представляющей собой модификацию фаззинг-тестирования в памяти, наследующую достоинства и устраняющую недостатки, присущие данной технике тестирования; взаимосвязанного использования прямого и обратного символьного исполнения, определяющего достоверность выявленных ошибок и НДВ.
Практическая значимость работы определяется: разработанной модульной архитектурой ПАК автоматизированного обнаружения ошибок и НДВ в ПО, универсальной относительно различных процессорных архитектур за счёт использования библиотеки Unicorn Engine; возможностью интеграции реализованного ПАК с крупномасштабными средствами анализа безопасности ПО; ориентированностью на использование специалистами различной квалификации, в том числе не обладающими компетенциями в части фаззинг-тестирования.
Методология и методы исследования. При выполнении работы использовались методы теории алгоритмов, теории графов, теории построения вычислительных архитектур, принципы тестирования ПО.
Положения, выносимые на защиту:
1. Методология автоматизированного поиска ошибок в программном коде бинарных образцов ПО [57, 63].
2. Графовая модель функционирования ПО, представленного в бинарном виде [52].
3. Метод поиска ошибок и НДВ в программном коде на основе точечного фаззинг-тестирования и механизма общих симуляций [29, 58, 63].
4. Метод оценки достижимости фрагментов программного кода на основе сочетания прямого и обратного символьного исполнения [63, 64].
5. Архитектура ПАК автоматизированного обнаружения ошибок и НДВ в ПО [132].
Соответствие специальности научных работников. Полученные научные результаты соответствуют следующим пунктам паспорта специальности научных работников 2.3.6. «Методы и системы защиты информации, информационная безопасность»: принципы и решения (технические, математические, организационные и др.) по созданию новых и совершенствованию существующих средств защиты информации и обеспечения информационной безопасности (п. 15) и методы, модели и средства разработки безопасного ПО, выявления в нём дефектов безопасности, противодействия скрытым каналам
передачи данных и выявления уязвимостей в компьютерных системах и сетях (п. 17).
Степень достоверности результатов исследования подтверждается их внутренней непротиворечивостью и адекватностью физическим представлениям об исследуемом процессе.
Внедрение результатов работы. Полученные основные научные результаты диссертационного исследования используются в деятельности в/ч 43753, МЧС России, АО «Специальное агентство «Омега», ООО «НТП «Криптософт», ООО «ЭР СИ О», АО «Синтелс»). Также результаты работы использованы в учебном процессе ордена Трудового Красного Знамени ФГБОУ ВО МТУСИ при организации дисциплины «Защита информации от вредоносного программного обеспечения» в виде методических рекомендаций по проведению лекционных и практических занятий для бакалавров направления 10.03.01 «Информационная безопасность».
Апробация результатов. Основные результаты исследований и научных разработок докладывались и обсуждались на следующих конференциях: Санкт-Петербургская научно-практическая конференция «Проблемы подготовки кадров в сфере инфокоммуникационных технологий» (Санкт-Петербург, 2011 г.), Всероссийская научно-техническая конференция «Методы и технические средства обеспечения безопасности информации» (Санкт-Петербург, 2012 г., 2013 г., 2022-2024 гг.), Международная научно-техническая конференция «Фундаментальные проблемы радиоэлектронного приборостроения» (ШТЕЯМАТЮ - 2013) (Москва, 2013 г.), Международная научная школа молодых ученых и специалистов «Проблемы освоения недр в XXI веке - глазами молодых» (Москва, 2014 г.), Всероссийская научно-практической конференции «Теория и практика обеспечения информационной безопасности» (Москва, 2022 г.), Всероссийская научно-техническая конференция «Фундаментальные и прикладные аспекты компьютерных технологий и информационной безопасности» (Таганрог, 2023-2024 гг.), Неделя науки ИКНК (Санкт-Петербург, 2024 г.).
Публикации по теме диссертации. Результаты диссертационной работы отражены в 39 публикациях, в том числе 22 публикации в рецензируемых научных изданиях из перечня ВАК и 3 свидетельства о государственной регистрации программы для электронно-вычислительной машины (ЭВМ).
Структура и объём диссертации. Диссертация состоит из введения, шести глав, заключения, списка использованных источников из 157 наименований. Общий объём работы составляет 278 страниц, в том числе 20 рисунков и 18 таблиц.
Во введении обоснована актуальность темы диссертационного исследования, сформулирована цель, определены основные задачи, научная новизна и практическая значимость полученных результатов, а также положения, выносимые на защиту.
В первой главе представлены результаты сравнительного анализа методов поиска ошибок и НДВ в ПО, представленном в виде бинарных файлов. Техника фаззинг-тестирования, не теряющая своей актуальности уже многие годы, до сих пор является одной из наиболее перспективных.
Вторая глава содержит описание предлагаемой методологии автоматизированного обнаружения ошибок и НДВ в ПО, представленном в виде бинарных файлов. Описание методологии предваряет постановка задачи обнаружения ошибок и НДВ в ПО, состоящей в целенаправленном тестировании заданных функций ПО, получении списка потенциальных ошибок и НДВ и оценке их достоверности как возможности формирования условий, позволяющих достигнуть выполнения заданных функций и повлиять на соответствующие регистры и области памяти таким образом, что возникнет искомая ошибка/НДВ.
Третья глава посвящена подготовке к процессу фаззинга, в частности, работе с наборами входных данных. Рассмотрены научно-технические источники, посвящённые данной тематике, представлены методы подготовки входных наборов данных для фаззинг-тестирования, разработанные автором. Первый метод базируется на использовании искусственных нейронных сетей
(ИНС) с долгой краткосрочной памятью, за счёт чего обеспечивается запоминание экземпляров наборов входных данных, при использовании которых удалось выявить дефект анализируемой программы. Второй метод предназначен для бинарных приложений, работающих по технологии NFC, он основан на намеренном внесении конфликтов в сообщения (структуру и очередность), которыми обмениваются приложения.
В четвертой главе представлено описание разработанного метода поиска ошибок и НДВ в программном коде бинарных образцов ПО. Отправной точкой является техника фаззинга в памяти, однако предлагаемый метод оперирует не только базовыми блоками программы, но и информацией об их достижимости, что в совокупности предлагается называть «точками». Ключевой особенностью метода является использование механизма общих симуляций.
В пятой главе представлен метод оценки достижимости фрагментов программного кода на основе сочетания прямого и обратного символьного исполнения, работающий взаимосвязано с методом поиска ошибок и НДВ в программном коде бинарных образцов ПО и предоставляющий ему требуемую для успешного завершения работы информацию. Помимо этого, оценка анализа достижимости позволит удалить недостижимые фрагменты программного кода, пометив их как недостоверные ошибки/НДВ. Оценка достижимости фрагментов программного кода - процесс анализа ПО на факт достижимости выбранных базовых блоков при стандартном течении потока исполнения данного ПО. Как правило, оценка достижимости необходима не только для ответа на вопрос о достижимости конкретного базового блока в целом, но и для определения стартового контекста и точки входа ПО, которые необходимы для достижимости данного блока.
В шестой главе представлены: архитектура и принципы функционирования ПАК, обеспечивающего выявление ошибок и НДВ в ПО с помощью модели и методов, представленных в предыдущих главах; описаны функции и взаимосвязь модулей, составляющих программный комплекс;
представлены результаты экспериментальных исследований работоспособности и эффективности комплекса.
В заключении приведены результаты и выводы, полученные автором в ходе выполнения работы.
1 СРАВНИТЕЛЬНЫЙ АНАЛИЗ МЕТОДОВ ПОИСКА ОШИБОК
И НДВ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ, ПРЕДСТАВЛЕННОМ
В ВИДЕ БИНАРНЫХ ФАЙЛОВ
Задача поиска ошибок и уязвимостей в ПО не теряет актуальности уже многие годы и для её решения создан широкий спектр различных подходов.
В данной главе представлена классификация методов поиска ошибок и НДВ в ПО, отдельно рассмотрены подходы на основе статического и динамического анализа. В условиях необходимости работы с бинарными файлами исследуемого ПО особенное внимание уделено методам фаззинг-тестирования, представляющего собой мощную технику анализа, которая может быть подстроена под условия тестирования.
1.1 Классификация методов поиска ошибок и НДВ в ПО
Задача поиска ошибок и НДВ в ПО актуальна на протяжении всех этапов эволюции информационных технологий. В рамках решения данной задачи выполняется всесторонний анализ исходного кода каждой составляющей ПО с целью выявления таких программных инструкций, которые могут быть проэксплуатированы злоумышленниками для реализации компьютерных атак, кражи конфиденциальных данных, вывода системы из строя.
С этой целью разработчики создают специализированные программные или программно-аппаратные комплексы, способные самостоятельно или с помощью оператора выполнять анализ безопасности ПО. Согласно исследованию [3] целесообразно классифицировать методы анализа безопасности
ПО с целью поиска ошибок и НДВ относительно типа анализа ПО, а именно:
1. Экспертный анализ - метод анализа ПО, который подразумевает исследование всей доступной информации об объекте анализа из различных источников, в том числе официальной документации ПО, научных работ, результатов тестирования, а также применение специализированных технических программ, выполняющих автоматический поиск ошибок и НДВ. Выводы о безопасности ПО формирует эксперт, тем самым подтверждая полноту списка обнаруженных ошибках и НДВ.
2. Статический анализ - метод анализа ПО, который подразумевает, что выводы о наличии ошибок и НДВ в программном коде будут сделаны только по результатам анализа, выполненного сторонними программами. В качестве таких программ используют синтаксические анализаторы кода, инструменты формального моделирования и др.
3. Динамический анализ - метод анализа ПО, который подразумевает, что выводы о наличии ошибок и НДВ в программном коде будут сформированы по результатам исполнения самого кода в условиях близких к реальной эксплуатации ПО. Отличительной особенностью считается возможность отправки различных наборов входных данных, которые позволяют выполнить анализ всех случаев работы ПО, в том числе краевых.
4. Ручной анализ - метод анализа ПО, который подразумевает исследование исходного или восстановленного в результате динамического анализа кода. В данном случае выводы о наличии ошибок и НДВ так же, как и в экспертном анализе, формирует человек по результатам проведенной экспертизы программного кода.
Каждый из перечисленных типов анализа ПО на наличие ошибок и НДВ имеет свои преимущества и недостатки. Их более подробных обзор представлен в таблице 1.1 и в статье автора [4].
Таблица 1.1 - Обзор преимуществ и недостатков методов анализа ПО
Тип метода Преимущества Недостатки
- возможность - требует наличия
исследования данных, квалифицированного
которые не представлены эксперта, способного
в программном коде выполнить всесторонний
(архитектура ПО, изменения анализ;
исходного кода, размеры - человеческий фактор;
Экспертный анализ файлов и др.); - число открытых
- возможность источников может быть
обнаружения уязвимостей, ограничено;
связанных - высокие затраты
с версиями сервисов, относительно времени
ошибками конфигурации и выполнения
др.
- возможность выполнять - исполняемый файл
проверку на наличие не запускается, исследуется
ошибок и НДВ на любых только текст программного
стадиях разработки ПО; кода;
- процесс анализа может - нет возможности
быть осуществлен без учета проанализировать краевые
Статический анализ аппаратных особенностей случаи работы ПО;
устройства, на базе которого - анализ
выполняется анализ ПО. обфусцированного
К ним относится: программного кода
архитектура центрального трудновыполним в связи
процессора и графических с увеличением сложности
ускорителей его синтаксического дерева
Динамический - обнаружение - процесс анализа
Тип метода Преимущества Недостатки
анализ уязвимостей, которые зависит от технических
проявляются только при характеристик устройства,
исполнении программного на базе которого
кода; выполняется анализ ПО;
- условия анализа ПО - высокие затраты
близкие к реальным; относительно требуемых
- выполнение анализа вычислительных ресурсов
обфусцированного
программного кода
- глубокий и тщательный - требует наличия
анализ сложных участков квалифицированного
кода; эксперта, способного
- возможность анализа выполнить всесторонний
Ручной анализ тех частей кода, которые анализ;
не были проанализированы - человеческий фактор;
при статическом - высокие затраты
и динамическом анализе относительно времени
выполнения
На основе информации, представленной в таблице 1.1, и статистики [5], которая отражает увеличение объёма программного кода, не представляется возможным применять методы экспертного и ручного анализа для анализа программного кода на наличие ошибок и НДВ. Обусловлено это тем, что человеку для анализа десятков тысяч кода потребуется значительное количество времени, в течение которого злоумышленники могут проэксплуатировать имеющиеся уязвимости.
Методы статического и динамического анализа кода ПО являются наиболее перспективными для своевременного обнаружения уязвимостей
за счёт возможности автоматизации процесса и возможности сформировать более полную и детальную оценку состояния безопасности ПО. Несмотря на это, стоит отметить, что полный отказ от привлечения эксперта невозможен, так как окончательный вердикт о наличии ошибок и НДВ в ПО и уровне его защищенности должен принимать человек.
1.2 Исследования, посвящённые применению методов статического
анализа для обнаружения ошибок и НДВ в ПО
Статический анализ является важным этапом проведения комплексной проверки защищенности ПО. Его ключевой особенностью является возможность обнаружения ошибок и НДВ в ПО до выполнения тестирования или исполнения ПО, что является преимуществом не только с точки зрения обеспечения безопасности, но и с экономической точки зрения, так как это способствует снижению затрат относительно времени и финансов.
Данной теме посвящено большое количество научных работ [6-15], которые расширяют возможности статического анализа за счёт интеграции различных методов и инструментов, таких как искусственный интеллект (ИИ), метрики схожести кода, абстрактная интерпретация исходного кода и др. Они позволяют провести более детальный анализ и выявить скрытые закономерности. Так, например, авторы [6] предлагают продукт AIBugHunter, который предназначен для обнаружения уязвимостей в коде ПО, написанного на языках программирования C и C++. Настоящий продукт основан на технологиях машинного обучения, применяемых для обнаружения и классификации уязвимостей в программном коде, и интегрирован в среду разработки VisualStudio Code [7]. Сочетание указанных методов позволяет не только автоматизировать процесс анализа кода, но также определять уязвимости и указывать пользователю на них в коде ещё до исполнения ПО,
в момент разработки. Разработчики утверждают, что их продукт в среднем достигает около 60% правильно обнаруженных уязвимостей на основе анализа Топ-25 наиболее опасных CWEs [8], что указывает на значительную часть ложных срабатываний. Из этого следует, что для повышения точности обнаружения требуется выполнять постоянное дообучение модели машинного обучения, а также более тщательно изучать пользовательский опыт, что также указано в тексте исследования. Помимо этого, авторами отмечается проблема несбалансированности данных относительно различных CWE, что также влияет на точность обнаружения.
В работе [9] исследователи предлагают инструмент FUNDED (Flow-sensitive vUlNerability coDE Detection), основанный на применении графовой нейронной сети (ГНС). Он принимает на вход исходный код программы и строит на его основе направленный граф, иллюстрирующий структуру программы и связи между её компонентами, передаваемыми данными. После этого модель ГНС выполняет анализ полученного графа с целью обнаружения уязвимостей ПО на уровне функций. Анализ графового представления программного кода позволяет оценить его с точки зрения структурных особенностей и потоков передачи данных, что положительно влияет на точность обнаружения по сравнению с подходами, основанными на последовательном анализе кода. Авторы утверждают, что их продукт может быть применён для любой ранее неизвестной программы и продемонстрирует успешный результат обнаружения. Однако в исследовании также акцентирована проблема ограниченности обучаемых данных, которая напрямую влияет на качество обучения и точность предсказаний. Ещё одной трудностью является необходимость масштабирования модели для анализа ПО с объёмной кодовой базой.
Похожие диссертационные работы по специальности «Другие cпециальности», 00.00.00 шифр ВАК
Методы и алгоритмы оценки защищенности встроенного программного обеспечения на основе нечеткой логики2020 год, кандидат наук Югансон Андрей Николаевич
Поиск ошибок переполнения буфера в исходном коде программ с помощью символьного выполнения2019 год, кандидат наук Дудина Ирина Александровна
Классификация предупреждений о программных ошибках методом динамического символьного исполнения программ2019 год, кандидат наук Герасимов Александр Юрьевич
Разработка метода оценки эксплуатируемости программных дефектов2017 год, кандидат наук Федотов Андрей Николаевич
Современные методы статического и динамического анализа программ для автоматизации процессов повышения качества программного обеспечения2012 год, доктор физико-математических наук Аветисян, Арутюн Ишханович
Список литературы диссертационного исследования доктор наук Самарин Николай Николаевич, 2025 год
Использование
графового представления
Задача моделирования заданного объекта в терминах теории графов
Метод поиска ошибок и НДВ в ПО Метод теории графов Задача теории графов, которая может быть решена с использованием данного метода
дефектов программ. программы
Отслеживание помеченных данных (1ат1-анализ). Тат1-анализ ориентирован на отслеживание потока входных данных и маркировку тех участков программы, выполнение которых будет затронуто этими данными. Для выполнения 1ат1-анализа высокую эффективность демонстрирует подход, в рамках которого при поступлении входных данных в точку программы сначала определяется множество ближайших точек, в которые данные могут попасть из рассматриваемого узла. Метод поиска в ширину в сочетании с методами разметки (раскраски) графа Задача обхода графа из заданной (корневой) вершины с посещением каждой вершины не более одного раза, усложненная раскраской графа для посещенных вершин.
Моделирование атак. Как правило, при моделировании кибератак задаётся набор целевых участков кода, в которые необходимо попасть. Использование графового представления программы Задачи: - моделирования заданного объекта в терминах теории графов;
Метод поиска ошибок и НДВ в ПО Метод теории графов Задача теории графов, которая может быть решена с использованием данного метода
Поиск в глубину - обхода графа из заданной (корневой) вершины с посещением каждой вершины не более одного раза.
Сканирование уязвимостей. Поиск заданного подграфа в графе большей размерности Задачи: - поиска определённого подграфа, характеризующегося заданным числом вершин и дуг, степенной последовательностью, в графе большей размерности; - поиска изоморфных графов, которые можно получить из исходного путем нахождения для него функции перенумерации вершин и дуг.
Поиск изоморфных графов
Метод поиска ошибок и НДВ в ПО Метод теории графов Задача теории графов, которая может быть решена с использованием данного метода
Анализ активности и потоков взаимодействия программы. Данный метод поиска ошибок и НДВ направлен на анализ того, какие пути исполнения программы зависят друг от друга, какие пути в зависимости от условий и входных данных влияют друг на друга, и можно ли вызвать ошибку, влияя на взаимодействующие потоки. Поиск максимального потока в сети (с использованием алгоритма Форда-Фалкерсона) Задача нахождения такого потока в транспортной сети, что сумма потоков из истока максимальна.
Систематизировав связь методов теории графов и методов поиска ошибок и НДВ в ПО, можно сделать вывод о том, что задачи анализа ПО на предмет наличия разного рода дефектов могут быть представлены в виде различных задач на графах. Это позволяет говорить о том, что в работе получен значимый научный результат, открывающий фундаментальный задел для создания новых методов анализа ПО на предмет безопасности (поиска ошибок, уязвимостей, НДВ и т.п.) на основе различных графовых задач.
2.3 Описание методологии автоматизированного поиска ошибок и
НДВ в программном обеспечении
Термин «методология» может трактоваться различным образом, в диссертационной работе использовано определение Э.Г. Юдина, в рамках которого методология представляет собой совокупность методов, принципов исследования и процедур, применяемых в той или иной специальной научной дисциплине.
Предлагаемая в работе методология поиска ошибок и НДВ в ПО, представленном в виде бинарных файлов, описана в работе [57] автора и основана на применении эффективной техники фаззинг-тестирования в памяти в совокупности с научно-техническими методами, способными устранить недостатки, характерные для данного вида фаззинг-тестирования.
Согласно предлагаемой методологии в качестве входных данных принимаются бинарные файлы, на основе которых будет выполнен анализ ПО. Однако анализу подлежит не весь код, а лишь отобранные методами статического анализа фрагменты (базовые блоки). Такое решение позволяет выполнять направленное тестирование тех частей кода, которые представляют наибольший интерес.
Предлагаемая методология направлена на решение следующих задач:
1. Представление процесса функционирования бинарного ПО на низком уровне (с учётом состояний памяти и регистров) в виде ориентированного графа, атрибуты вершин и дуг которого характеризуют состояние программы.
2. Анализ графа на предмет наличия для заданной вершины смежных с ней вершин. Решение задачи осложняется тем, что часть дуг в графе задана благодаря статическим адресам, а часть дуг становится известной непосредственно при исполнении программы.
3. Поиск пути на графе между заданной парой вершин с учётом проблемы непостоянных дуг (из-за динамических адресов), требующей определения смежных вершин на каждом шаге поиска и необходимости сократить время анализа в связи с большим числом потенциальных ошибок.
Значимым этапом предложенной методологии является оценка достижимости выявленных в процессе фаззинг-тестирования ошибок. Характерной особенностью фаззинг-тестирования в памяти является большое число ложных срабатываний, вследствие чего актуальной является задача анализа достоверности ошибок. Математически она представляет собой оценку достижимости базовых блоков, то есть поиска пути между парой вершин с учётом их характеристик.
Одним из вариантов решения задачи может являться сочетания методов поиска в ширину и поиска максимального потока в сети, поскольку для оценки достижимости целесообразно использовать метод символьного исполнения. Однако предложенная графовая модель позволяет сделать решение более простым за счёт вычисления значения функции д(у^, Vу), требующего выполнения некоторых операций над кортежами < А^^ > и < >.
Методология также обеспечивает оптимизацию всего процесса фаззинг-тестирования за счёт повышения скорости процесса оценки достижимости. В терминах теории графов предлагается выполнять поиск в ширину из обеих вершин - начальной ^ и конечной V] , дополнив поиск методом встречи посередине.
Поиск в ширину уже отчасти является оптимизацией, поскольку он обеспечивает нахождение именно кратчайших путей, демонстрирующих наиболее простой с точки зрения злоумышленника способ эксплуатации обнаруженной ошибки или НДВ и дают достоверный ответ на вопрос, эксплуатируем ли данный дефект.
Далее представлено более подробное описание работы ключевых методов предлагаемой методологии - метода точечного фаззинг-тестирования и метода оценки достижимости, которые имеют математическое выражение в терминах теории графов и находят практическое отражение в использовании техник фаззинг-тестирования, прямого и обратного символьного исполнения.
2.3.1 Метод поиска ошибок и НДВ в программном коде на основе точечного фаззинг-тестирования и механизма общих симуляций
Значимую часть методологии составляет метод проведения фаззинг-тестирования в памяти. По результатам сравнительного анализа различных техник фаззинг-тестирования было выявлено, что техника фаззинг-тестирования в памяти содержит ряд ограничений, которые не позволяют применять её в исходном виде для решения задачи поиска ошибок и НДВ. Связано это с тем, что характерное для этой техники большое число ложных срабатываний способствует увеличению затрат относительно вычислительных ресурсов, а также снижает уровень доверия исследователя к результатам обнаружения. В связи с этим в сочетании с данной техникой фаззинг-тестирования применяются механизм общих симуляций и метод оценки достижимости базовых блоков анализируемого ПО.
Общий метод фаззинг-тестирования получил название точечного фаззинг-тестирования, он детально описан в работе [58] автора и в главе 4 настоящей диссертационной работы.
Применяемый совместно с фаззинг-тестированием в памяти механизм общих симуляций отвечает за учет информации о потоках исследуемого ПО в момент проведения фаззинг-тестирования. Помимо этого, в рамках метода предлагаются стратегии отбора точек, подлежащих фаззинг-тестированию. Такое решение позволяет сосредоточиться на обнаружении ошибок и НДВ только в отдельных фрагментах кода и решить проблему зависимости результатов анализа от покрытия программного кода, которая характерна для классических техник фаззинг-тестирования.
Использование графового представления ПО в данном случае требуется для определения «точек» тестирования - базовых блоков, представляющих собой определённые вершины графа. При проведении фаззинг-тестирования исследуются именно заданные вершины графа с учётом опредёленных ограничений, накладываемых на их атрибуты. Для заданной вершины с использованием статических адресов между базовыми блоками могут быть частично найдены и смежные с ней вершины, представляющие собой постоянные дуги.
Для определения наличия динамических дуг вершин (наличия перекрёстной ссылки между парой базовых блоков) для каждого базового блока анализируются инструкции с целевыми адресами, определяющими, куда из данного блока можно перейти. Целевые адреса либо являются константами, либо они вычислены на этапе загрузки и релокации (в обоих случаях - это постоянные дуги), либо они принимают значения, вычисляемые во время исполнения программы (это и есть случай с неизвестными переменными дугами графа). Таким образом, за описание перехода между базовыми блоками (смежности вершин) во многом отвечает кортеж < А^,!^ >.
Тогда задача определения смежных вершин сводится к следующему: на ориентированном графе £ =<У,Е > для заданной вершины ^ найти путь в вершину V] , если такой существует, с учётом наличия непостоянных дуг в графе. На практике определение наличия либо отсутствия достижимости
между парой блоков реализуется путем разрешения символьных ограничений. Введём функцию f:
, Л (TRUE, 3 еи = (Vi,Vi)
f(vt, Vj) = f(< Al, h >, < A]l ,J>) = {FALSEi э ^ = {Vb ) (2.1)
Функция f представляет собой некоторое обобщённое описание процесса разрешения символьных ограничений, а принятие ею значения TRUE говорит о наличии дуги между заданной парой вершин и, следовательно, об их смежности.
Разработанный метод базируется на графовой модели и использует модифицированный метод поиска в ширину. За счёт использования поиска в ширину обеспечивается увеличение покрытия графа ещё на самых первых шагах работы алгоритма. В дополнение к этому сразу же будет решаться техническая проблема, заключающаяся в том, что между базовыми блоками ПО могут быть динамические адреса. Для решения этой проблемы на каждом шаге алгоритма поиска в ширину реализуется исследование вершин, смежных с текущей. Но такой метод требует дополнения, позволяющего оценивать достижимость выявленных ошибок и НДВ. Это реализуется с использованием метода оценки достижимости фрагментов программного кода.
2.3.2 Метод оценки достижимости фрагментов программного кода на основе сочетания прямого и обратного символьного исполнения
С целью снижения числа ложных срабатываний необходимо обеспечить проверку достижимости базовых блоков путем внедрения эффективного механизма, способного оценить данную возможность. Однако текущий уровень развития подобных механизмов свидетельствует о том, что задача разработки
подобных механизмов не решена окончательно. Обусловлено это тем, что подходы [59-62], опубликованные по данной тематике, обладают ограничениями, которые не позволяют снизить число ложных срабатываний.
В терминах разработанной графовой модели и математической постановки задачи в терминах теории графов задача оценки достоверности выявленной ошибки/НДВ сформулирована в виде теоремы, которая также является частью методологии и представлена в работе [63] автора.
Теорема о необходимых условиях достоверности выявленного дефекта
в ПО.
Дано: ПО, представленное в виде кортежа S = < G,P > , где G -ориентированный граф, каждая дуга которого имеет: неотрицательное значение пропускной способности; выявленный в результате тестирования дефект, локализованный в базовом блоке v't; множество входных точек в программу
Vstart.
Доказать, что необходимыми условиями достоверности выявленного дефекта в базовом блоке v't являются:
1) наличие хотя бы одного пути до него;
2) возможность передачи по этому пути сетевого потока величины Ifl, обеспечивающего воспроизведение дефекта (эксплуатацию уязвимости/ повторение ошибки).
Доказательство.
Докажем теорему от противного.
1. Пусть в графе не существует ни одного пути между вершинами v[ Е V'
и ylstart Е Vstart: path(v[; vjtart) = го Это означает, что злоумышленник не имеет
возможности попадания в целевую вершину v[ из текущей v]start, следовательно, дефект не является достоверным (ошибка не может быть воспроизведена/ уязвимость не может быть проэксплуатирована).
2. Пусть существует путь между вершинами Е V' и у}зШг1 Е УзЫП : ра£к(у[) Уз1аг1.) = р. Здесь р - максимальное значение сетевого потока, которое может быть пущено по пути ра1Ъ.(у[)
Пусть рр^п) включает дуги {(р^, "к), (ук, у1),... (уг, у')}.
Если хотя бы одна из дуг имеет пропускную способность f(vа,vb) < Сехр, а,ЬЕУ,а^Ь , сетевой поток величины не дойдет полностью до у\ , следовательно, дефект не является достоверным (ошибка не может быть воспроизведена/уязвимость не может быть проэксплуатирована).
Таким образом, выполнение обоих условий является необходимым для подтверждения достоверности выявленного дефекта в базовом блоке , что и требовалось доказать.
Показано, что математически задача оценки достоверности представляет собой обход графа, моделирующего функционирование исследуемого ПО, с учётом значения сетевого потока, который может быть пущен по этому графу.
В техническом плане это соответствует проверке возможности многошагового перехода из стартового базового блока в целевой, причём с учётом ограничений, накладываемых на регистры и память. Однако решение классической задачи поиска путей на графе неприменимо в данном случае, поскольку:
- при решении поставленной задачи нет необходимости обнаруживать кратчайшие пути;
- веса дуг, отражающие расстояние между вершинами графа, могут принимать любое значение из некоторого известного диапазона, который изменяется в зависимости от образов ПО.
При этом стоит отметить, что расстояние между вершинами может быть по-разному интерпретировано ввиду того, что связи между базовыми блоками могут рассматриваться как:
ссылка одного базового блока на другой;
- следующие друг за другом инструкции, выполняющиеся в опредёленном порядке, что подразумевает отсутствие явной ссылки на блок.
Поэтому математическое описание метода представляет собой в большей степени модифицированную задачу поиска путей на графе с учётом пропускной способности дуг.
Ключевая техническая идея предлагаемого метода оценки достижимости заключается в том, чтобы объединить преимущества прямого и обратного символьного исполнения с целью формирования и разрешения множеств символьных ограничений, связанных с потоком исполнения исследуемого ПО. Используя прямое символьное исполнение, метод обрабатывает базовые блоки ПО, а, используя обратное символьное исполнение, становится возможным определить условия достижимости выявленных базовых блоков, ранее считавшихся недостижимыми. Таким образом, данное решение позволяет выполнить оценку достижимости некоторого базового блока из другого базового блока.
2.3.3 Принципы, методы и процедуры, используемые при построении
методологии
Методология как теоретический результат исследования должна отвечать ряду фундаментальных требований и принципов, чтобы можно было утверждать о её применимости к различным объектам рассматриваемой предметной области.
Принципы, которым соответствует создаваемая методология:
1. Принцип системности. В контексте решаемой научной задачи данный принцип означает, что описание предмета исследования (бинарного ПО) в терминах методологии может быть распространено на любые его экземпляры, как более простые, так и более сложные структурно.
2. Принцип адекватности и непротиворечивости. В соответствии с этим принципом представление объекта исследования учитывает присущие ему особенности и не противоречит его реальному поведению. В рамках созданной методологии за это отвечает графовая модель функционирования ПО, способная адекватно характеризовать все низкоуровневые изменения, происходящие с базовыми блоками программы при её выполнении.
3. Принцип целенаправленности. Принцип означает, что исследование выполняется в соответствии с задачей поиска достоверных ошибок и НДВ в ПО. Действительно, этапы методологии охватывают как теоретические, так и практические аспекты решаемой задачи и четко следуют один за другим: на основе графовой модели функционирования ПО построены методы фаззинг-тестирования (обеспечивает выявление ошибок и НДВ) и оценки достижимости фрагментов программного кода (обеспечивает выделение подмножества ошибок и НДВ из всех зафиксированных, которые действительно могут быть воспроизведены/проэксплуатированы злоумышленником).
В рамках методологии используются следующие методы:
1. Метод математического моделирования - функционирование ПО, представленного в виде бинарных файлов, моделируется ориентированным графом с изменяемыми характеристиками (параметрами вершин и дуг).
2. Метод поиска путей на графе - классическая задача теории графов, которая может быть решена с использованием различных подходов. В диссертационной работе используются методы поиска в ширину и модифицированного поиска максимального потока в сети.
3. Метод автоматизированного поиска ошибок и НДВ в ПО, представленном в виде бинарных файлов. В его основе лежит техника фаззинг-тестирования (в памяти). Частичный перенос задачи на человека заключается в получении экспертного мнения относительно целевых участков программы, которые в первую очередь должны быть протестированы.
4. Метод символьного исполнения, применяемый для оценки достоверности найденных ошибок и НДВ в ПО.
Процедуры, используемые в рамках методологии:
1. Процедура представления образца ПО в виде графа.
2. Процедура формализации задачи поиска ошибок и НДВ в ПО для дальнейшего тестирования.
3. Процедура автоматизированного тестирования и получения списка потенциальных ошибок и НДВ.
4. Процедура оценки достоверности выявленных ошибок и НДВ.
Общая схема методологии, характеризующая взаимосвязь между теоретическими аспектами и практической реализацией методов, представлена на рисунке 2.1.
Рисунок 2.1 - Общая схема разработанной методологии
2.3.4 Практические аспекты реализации методологии
На практике при реализации метода оценки достижимости особенное внимание следует уделить разрешению ограничений, которое может быть успешно выполнено с применением прямого символьного исполнения.
Суть данного подхода состоит в использовании абстрактных символьных переменных вместо переменных с конкретными значениями в качестве входных данных. Для того чтобы покрыть сразу все возможное множество входных данных, при выполнении программы на символьные переменные в точках ветвления накладываются определённые ограничения, тогда задача сводится к решению системы уравнений, число которых соответствует числу ветвлений. Однако использования только символьного исполнения недостаточно для эффективного анализа обнаруженных фаззинг-тестированием ошибок, поскольку в случае большой по объёму программы с сильно ветвящейся структурой число уравнений будет крайне велико, и задача становится всё более трудоёмкой.
В связи с этим в рамках метода оценки достижимости, предложенного автором в работе [64] и построенного на базе графовой модели и решенной на графе задачи поиска путей, предложено реализовать также обратное символьное исполнение. Оно ориентировано на сокращения числа ветвлений внутри кода и позволяет дополнять некоторые функции собственными наборами ограничений.
Объединение данных подходов реализовано за счёт их последовательного соединения по множеству накладываемых ограничений при прохождении графа (при реализации поиска в ширину). Удобство сочетания прямого и обратного символьного исполнения также подчеркивается тем, что форматы выходных методов сопоставимы, и выходные данные одного метода можно использовать как входные для второго (и наоборот). Метод встречи посередине помогает сопоставить выходные данные методов прямого и обратного символьного исполнения; он будет успешно применим в случае независимого задания для каждого метода входных данных и ограничений на них, а также точки встречи этих методов.
Результатом является вычисленное множество ограничений, являющегося пересечением множеств ограничений на выходах обоих методов. Затем
происходит упрощение вычислений и представление итогового результата (в случае недостижимости целевого базового блока множество будет пустым).
2.4 Представление программы в терминах графовой модели
Представим в терминах модели фрагмент программы, написанной на языке программирования С, этот фрагмент содержится в листинге 2.1. Листинг 2.2 содержит соответствующий ему ассемблерный код архитектуры armv8-a, полученный в результате компиляции с помощью средства clang 17.0.1 (адреса инструкций упрощены). Данный фрагмент кода содержит недекларированную возможность: в случае, если одно из чисел кратно «магическому числу», функция возвращает результат «-1».
Листинг 2.1 - Рассматриваемый фрагмент ПО, содержащий недекларированную возможность
int gcd (int a, int b)
{
int result = ((a < b) ? a b);
while (result > 0) {
if (a % result == 0 && b % result == 0) {
break;
}
result--;
}
if (a % 11241224 == 0 || b % 54421141 == 0)
{ return -1;
}
return result;
}
Листинг 2.2 - Соответствующий фрагменту ассемблерный код
int gcd(int a, int b):
LBB0 0:
0x00 sub sp, sp, #32
0x01 .cfi _def_ cfa offset 32
0x02 str w0, [sp, #24]
0x03 str w1, [sp, #20]
0x04 ldr w8, [sp, #24]
0x05 ldr w9, [sp, #20]
0x06 subs w8, w8, w9
0x07 cset w8, ge
0x08 tbnz w8, #0, LBB0 2
0x09 b LBB0 _1
LBB0 1:
0x0A ldr w8, [sp, #24]
0x0B str w8, [sp, #12]
0x0C b LBB0 _3
LBB0 2:
0x0D ldr w8, [sp, #20]
0x0E str w8, [sp, #12]
0x0F b LBB0 _3
LBB0 3:
0x10 ldr w8, [sp, #12]
0x11 str w8, [sp, #16]
0x12 b LBB0 _4
LBB0 4:
0x13 ldr w8, [sp, #16]
0x14 subs w8, w8, #0
0x15 cset w8, le
0x16 tbnz w8, #0, LBB0 9
0x17 b LBB0 _5
LBB0 5:
0x18 ldr w8, [sp, #24]
0x19 ldr w10, [sp, #16]
0x1A sdiv w9, w8, w10
0x1B mul w9, w9, w10
0x1C subs w8, w8, w9
0x1D subs w8, w8, #0
0x1E cset w8, ne
0x1F tbnz w8, #0, LBB0_8
0x20 b LBB0_6 LBB0_6:
0x21 ldr w8, [sp, #20]
0x22 ldr w10, [sp, #16]
0x23 sdiv w9, w8, w10
0x24 mul w9, w9, w10
0x25 subs w8, w8, w9
0x26 subs w8, w8, #0
0x27 cset w8, ne
0x28 tbnz w8, #0, LBB0_8
0x29 b LBB0_7
LBB0_7:
0x2A b LBB0_9 LBB0_8:
0x2B ldr w8, [sp, #16]
0x2C subs w8, w8, #1
0x2D str w8, [sp, #16] 0x2E b LBB0_4 LBB0_9:
0x2F ldr w8, [sp, #24]
0x30 mov w10, #34568
0x31 movk w10, #171, lsl #16
0x32 sdiv w9, w8, w10
0x33 mul w9, w9, w10
0x34 subs w8, w8, w9
0x35 subs w8, w8, #0
0x36 cset w8, eq
0x37 tbnz w8, #0, LBB0 11
0x38 b LBB0 10
LBB0 10:
0x39 ldr w8, [sp, #20]
0x3A mov w10, #26261
0x3B movk w10, #830, lsl #16
0x3C sdiv w9, w8, w10
0x3D mul w9, w9, w10
0x3E subs w8, w8, w9
0x3F subs w8, w8, #0
0x40 cset w8, ne
0x41 tbnz w8, #0, LBB0 12
0x42 b LBB0 11
LBB0 11:
0x43 mov w8, #-1
0x44 str w8, [sp, #28]
0x45 b LBB0 13
LBB0 12:
0x46 ldr w8, [sp, #16]
0x47 str w8, [sp, #28]
0x48 b LBB0 13
LBB0 13:
0x49 ldr w0, [sp, #28]
0x4A add sp, sp, #32
0x4B ret
Получившийся в результате компиляции ассемблерный код состоит из четырнадцати базовых блоков (рисунок 2.2).
Рисунок 2.2 - Представление программы в терминах графовой модели
Множества V и Е графа G, описывающие данный ассемблерный код, будут иметь вид: V = [v0,v2, ...,v13}, Е = {е1,е2, ...,е19], где вершины графа - базовые блоки (рис. 1), v1 =< {0x00,0x01,... ,0x09}, {'sub sp,sp,40,,... ,'tbnz w8} , а e1 = < 0x08,0x0D > . Остальные элементы множеств V и Е формируются по аналогии.
Программный код, его базовые блоки и их взаимосвязь представлены на рисунке 2.3.
Рисунок 2.3 - Граф, построенный с использованием блоков программного кода
Другие примеры программного кода и его представление в терминах графовой модели будут вынесены в приложения.
2.5 Выводы
Данная глава диссертационной работы содержит описание созданной методологии автоматизированного обнаружения ошибок и НДВ в ПО в терминах теории графов. Основу методологии составляет графовая модель функционирования ПО, способная характеризовать все изменения, происходящие с ПО в процессе его исполнения, независимо от типа и размера ПО, с учётом низкоуровневых характеристик. Графовая модель позволяет представить взаимодействие всех его базовых блоков во время фаззинг-тестирования с возможностью отображения низкоуровневых характеристик. Также была доказана адекватность, универсальность и непротиворечивость модели.
Отталкиваясь от математического описания процесса функционирования ПО, выполнена математическая постановка задачи, заключающаяся в сведении технической задачи поиска ошибок и НДВ в ПО, представленном
в виде бинарных файлов, к математической задаче поиска путей на графах, модифицированной с учётом пропускной способности дуг графа.
При сравнении двух задач сразу видна аналогия между обходом путей выполнения программы с одновременной подачей специально сформированных данных, направленных на вызов ошибки в работе программы или активацию НДВ, и между задачей обхода графа и поиска всех возможных путей для каждой из заданного набора вершин до некоторой целевой. Уточнить схожесть задач также позволяет необходимость передачи в целевой базовый блок определённого контекста (полезной нагрузки) для вызова ошибки или НДВ. Это позволяет говорить уже не об абстрактном графе, а о сети -ориентированном графе с заданной неотрицательной пропускной способностью дуг. Эта пропускная способность характеризует ограничения на переходы между блоками.
Технически основная идея методологии заключается в модификации классической техники фаззинг-тестирования в памяти путем её дополнения механизмом общих симуляций (их сочетание далее будет называться «точечный фаззинг»), а также выполнении оценки достижимости базовых блоков, содержащих обнаруженные ошибки и НДВ, методом, сочетающим техники прямого и обратного символьного исполнения.
При описании методологии показано, что она соответствует принципам системности, адекватности и непротиворечивости, а также целенаправленности. Также рассмотрены практические аспекты, значимые при технической имплементации методологии.
3 ПОДГОТОВКА ДАННЫХ ДЛЯ ПРОВЕДЕНИЯ ФАЗЗИНГ-
ТЕСТИРОВАНИЯ
Исследования, представленные в данной главе, не являются ключевой задачей диссертационного исследования, однако имеют высокую значимость для повышения производительности и эффективности процесса фаззинг-тестирования. Как правило, фаззинг-тестирование представляет собой длительный процесс, во многом его скорость снижается за счёт формирования таких наборов (корпусов) входных данных, при подаче которых на вход программе будет вызвана ошибка или обнаружен какой-либо иной дефект. Для этого целесообразно отбирать наиболее результативные с точки зрения числа обнаруживаемых дефектов входные данные, однако эта результативность должна быть получена с учётом структуры входных данных, которые обрабатывает ПО. В противном случае программа будет некорректно завершаться из-за несоответствия входного формата, в то время как при тщательном формировании корпусов данных будут достигнуты опредёленные точки и ветви программы, представляющие особенный интерес для злоумышленников.
В главе представлен обзор научно-технических источников, в которых предложены различные подходы к генерации наборов данных для фаззинг-тестирования. Также в главе описаны два разработанных автором метода генерации данных для фаззинг-тестирования бинарных файлов. Первый метод [65] базируется на ИНС, а второй метод [66] ориентирован на мобильные приложения для работы по технологии NFC, вследствие чего он опирается на структуру сообщений NDEF, которые используются приложениями для обмена данными в двоичном формате.
3.1 Анализ источников, посвящённых задаче формирования наборов
данных для фаззинг-тестирования
Ключевым этапом проведения фаззинг-тестирования является формирование тестовых наборов данных, позволяющих выполнить всеобъёмлющий анализ ПО на наличие уязвимостей. При этом стоит отметить, что от качества этих данных зависит не только процент покрытия программного кода, но и точность обнаружения.
Согласно таблице 1.2 п. 1.4 настоящей диссертационной работы процесс генерации входных данных фаззинг-тестирования может быть выполнен следующими методами:
1. Порождающий фаззинг.
2. Мутационный фаззинг.
3. Фаззинг на основе ИИ.
На сегодняшний день техники мутационного фаззинга считаются наиболее применимыми на практике. Обусловлено это тем, что основной целью современного общества является автоматизация рабочих процессов, особенно тех, которые связаны с безопасностью населения. Для выполнения мутационного фаззинга, в отличие от порождающего фаззинга, не требуется наличие информации о структуре и формате входных данных и её предварительное изучение. Помимо этого, актуальным направлением является совмещение преимуществ мутационного фаззинга и фаззинга на основе ИИ с целью увеличения процента покрытия программного кода.
Согласно источнику [67], подходы к выполнению мутационного фаззинга можно классифицировать относительно методов выбора эталонного образца входных данных и методов внесения возможных мутаций. Наибольший интерес исследования представляет второй класс методов. Среди существующих техник внесения мутаций в эталонный образец входных данных авторами выделены следующие:
4. Случайные мутации - это техника внесения модификаций, которая подразумевает случайные изменения входных данных без учета их специфики. Например:
- замена байтов на случайные значения;
- перестановка байтов местами;
- вставка случайных байтов и др.
Примером такого фаззера является zzuf [68], способный перехватывать файловые и сетевые операции приложений и случайным образом изменять биты в командах их запуска.
5. Мутации с обратной связью - это техника внесения модификаций, которая подразумевает применение алгоритмов сбора обратной связи о предыдущих исполнениях для улучшения входных данных. Примером такого фаззера является LibFuzzer [27], собирающий информацию о пройденных базовых блоках с целью определения возможности анализа ранее недостижимых участков кода.
6. Техники машинного обучения и глубокого обучения - это техники внесения модификаций, которые подразумевают применение методов ИИ с целью оптимизации процесса выбора операций мутации. Примером такого фаззера является NEUZZ [69], который использует методы градиентной оптимизации для обнаружения наиболее перспективных мутаций.
7. Эволюционные мутации - это техника внесения модификаций, которая подразумевает применение генетических алгоритмов для формирования эффективной выборки входных данных. Примером такого фаззера является AFL [70], который использует эволюционные мутации на основе генетических алгоритмов (скрещивание, глобальный отбор и др.).
Правильно подобранные входные данные напрямую влияют на результат фаззинг-тестирования. В связи с этим в ходе выполнения диссертационной работы выполнен анализ научных исследований, описывающих применение выделенных техник внесения мутаций.
3.1.1 Метод случайных мутаций
Метод случайных мутаций наиболее применим в тех случаях, когда выполняется black-box фаззинг-тестирование, иными словами, когда об анализируемом ПО ничего неизвестно (структура, функциональные возможности и пр.) и нет возможности получить информацию. Однако применение одних только случайных мутаций может привести к снижению процента покрытия программного кода. Для решения данной проблемы авторы [71] разработали подход по оптимизации стратегии мутаций для фаззеров black-box.
Основная идея данного исследования заключается в том, что необходимо оценить целесообразность длительного фаззинга одних и тех же входных данных. Первым этапом работы данного подхода является формирование начальной выборки входных данных и применение к ним случайных мутаций с целью оценки их влияния на прогресс обнаружения уязвимостей. По результатам выполнения первого этапа выполняется оценка сгенерированных входных данных относительно корректного исполнения ПО, обнаружения новой уязвимости или сбоя ПО. В зависимости от полученных оценок, представленных в виде вероятности повторного применения мутации, выполняется перераспределение вычислительных ресурсов, после чего к входным данным применяются наиболее перспективные мутации. Таким образом, появляется возможность приоритизировать возможные случайные мутации без знаний об анализируемом ПО и увеличить точность обнаружения уязвимостей.
3.1.2 Мутации с обратной связью
Авторами [72] разработан фаззер Pythia, расширяющий возможности фаззинга на основе анализа грамматики REST API путем добавления обратной связи (относительно процента покрытия кода) и стратегии выбора мутаций на основе машинного обучения. Ключевая идея применения стратегии сбора обратной связи по результатам покрытия программного кода заключается в возможности выполнения приоритизации тестовых сценариев с целью увеличения вероятности обнаружения ошибок.
Первым этапом в работе фаззера является анализ спецификации API на основе исходных данных, что позволяет в дальнейшем создавать корректные относительно структуры запроса тестовые входные данные. Таким образом, формируется грамматическая модель запросов, по которой инициализируется первый набор тестовых данных с добавлением случайного шума. Все запросы отправляются на API с целью получения обратной связи о процессе анализа. На основе отзывов формируется набор наиболее удачных мутаций, с помощью которых удалось достигнуть прогресса в поиске уязвимостей. После этого заранее обученная модель автоэнкодер (seq2seq) обрабатывает полученные данные, чтобы выделить закономерности в данных, которые можно повторно использовать для улучшения стратегии мутации. Затем по результатам обратной связи и обучения производятся мутации, которые позволяют определить нестандартные входные данные, соответствующие структуре. В дальнейшем процесс мутации продолжается на основе отзывов о покрытии программного кода.
В рамках работы [73] выполнено исследование, направленное на расширение собираемой обратной связи с целью увеличения процента покрытия программного кода и обнаружения ошибок, которые не приводят к сбою работы ПО (логические и др.). Обеспечивается это за счёт сбора информации о нарушении условий инвариантов.
Для корректной работы предлагаемого подхода необходимо первоначально получить информацию о наличии в ПО инвариантов. После этого на основе обнаруженных инвариантов формируются условия, которые не должны нарушаться в процессе исполнения ПО, с целью их добавления в фаззер. Следующим шагом является формирование начального набора входных данных, их мутация и сбор обратной связи. На основе результатов выполненной проверки для каждой стратегии мутации формируется оценка. В том случае, если мутация привела к обнаружению уязвимости или увеличению покрытия кода, вероятность её дальнейшего применения возрастает. Аналогичным образом оцениваются мутации, которые позволили обнаружить нарушение условий инварианта. Для менее перспективных мутаций вероятность их повторного применения снижается.
Такое решение позволяет обнаружить нетривиальные ошибки, что приводит к увеличению точности анализа ПО на наличие уязвимостей.
3.1.3 Техники машинного обучения и глубокого обучения
В исследовании [74] авторы представили инструмент МСМ8Би77ег, основанный на стратегии многомерного управления процессом мутаций над входными данными с применением обучения с подкреплением.
Основная идея заключается в том, чтобы оптимизировать следующие аспекты выбора (измерения):
- место выполнения мутации;
- число изменений при выполнении мутации;
- алгоритм мутации.
Данные аспекты являются основой предлагаемой «трехмерной мутации».
Для начала работы МСМ8Би77ег необходимо выполнить инициализацию с целью определения первоначальных значений для указанных измерений
и начального образца входных данных. После этого запускается процесс фаззинга и динамически изменяется стратегия мутации методом обучения с подкреплением. Стратегия изменяется за счёт получения результатов тестирования от анализируемого ПО, на основе которых выполняется адаптация измерений. Для того чтобы данные действия позволили увеличить точность обнаружения, фаззер, адаптирующий тестовые данные, получает так называемую награду. В том случае, когда изменения привели к увеличению процента покрытия программного кода, обнаружению новых путей исполнения ПО и уязвимостей, награда является положительной. В ином случае награда является либо отрицательной, либо близкой к нулю. Таким образом, полученный опыт позволяет фаззеру корректировать стратегию, что в дальнейшем приводит к выбору только тех действий, которые дают положительный результат.
Результаты экспериментов продемонстрировали применимость данного инструмента и продемонстрировали увеличение процента покрытия программного кода и точности обнаружения уязвимостей.
Авторы [75] разработали мультизадачную нейронную сеть МТБи77, которая позволяет предсказывать и выбирать наиболее перспективные мутации входных данных. Для решения данных задач нейронная сеть обучена выполнению следующих подзадач:
оценка покрытия кода;
выявление потенциально опасных участков кода;
3) оценка вклада различных мутаций в процесс анализа.
Предложенный подход примечателен решением распределения возможностей оценки различных типов мутаций, что позволяет исключить случайные мутации и, соответственно, сократить время выполнения анализа.
Первоначально нейронная сеть выполняет инициализацию, которая включает в себя сбор и предварительную обработку данных о тестируемом ПО (покрытие кода, результаты работы в зависимости от мутаций и др.). После этого выполняется этап обучения нейронной сети и этап прогнозирования стратегий
мутаций по итогам выполнения тестов. Авторы утверждают, что MTFuzz обнаруживает ранее неизвестные ошибки и достигает большего покрытия кода.
В работе [76] рассматривается вопрос мутации сложноструктурированных входных данных при фаззинг-тестировании интерпретаторов языка программирования JavaScript. Автором предложен метод мутации с сохранением синтаксиса и семантики входных данных ввиду изменения AST-деревьев, соответствующих фрагментам исполняемого кода. Предложенная стратегия показывает большую скорость обнаружения новых путей исполнения за счёт подачи корректных
в контексте интерпретатора входных данных. Рост покрытия обусловлен именно сохранением синтаксиса и семантики входных данных, в результате чего интерпретатор корректно обрабатывает подаваемый на вход исполняемый код.
В статье [77] приведены предложения по построению универсального фаззера протоколов, который осуществляет мутацию входных данных на основе структуры полей протоколов, использующихся телекоммуникационным оборудованием. Ключевой особенностью рассматриваемого метода является модификация не всего пакета, а только его полей. Кроме того, авторами предлагается использование начальной популяции - исходного множества пакетов, в отношении которых применяются мутации, полученной в результате перехвата трафика. Рассматриваемый метод имеет два преимущества - отсутствие необходимости предварительной настройки (исходные данные выбираются из перехваченного трафика) и отсутствие зависимости от протокольной иерархии (модификация полей возможна как в самом протоколе, так и в протоколе, которой его инкапсулирует).
В статье [78] авторами рассматривается проблема мутации входных данных при проведении фаззинг-тестирования компиляторов. Особенностью проведения фаззинга компиляторов является низкая устойчивость к произвольным изменениям во входных данных ввиду привязки к синтаксису. Авторами предлагается представление образца входных данных в виде дерева, которое
помечается при обходе. Ключевой модификацией является генерация окончания последовательности, когда массив прочитан, а дерево ещё не завершено. Это обеспечивается с применением генератора случайных чисел с некоторым фиксированным начальным числом. Используя алгоритм, можно преобразовать каждый массив байтов в корректное абстрактное синтаксическое дерево, которое можно преобразовать в правильный исходный код. Таким образом, предлагается обеспечивать контролируемую устойчивость компилятора, находящегося в процесс е фаззинг-тестирования.
В работе [79] представлен метод фаззинг-тестирования с мутацией входных корпусов на основе грамматики. Автором предлагается использование форм Бэкуса-Наура для изменения входных корпусов таким образом, чтобы получать прирост покрытия при тестировании чувствительные к синтаксису программ. В качестве базы для описания форм автором выбрана платформа ANTLR (Another Tool for Language Recognition). По результатам проведенных экспериментальных исследований получен существенный прирост покрытия в сравнении с известными методами.
Методы ИИ в целом представляются перспективным инструментом для поиска уязвимостей, ошибок и НДВ в ПО [80], в частности, это актуально в условиях увеличения сложности современных систем и, как следствие, используемого в них программного кода.
3.1.4 Эволюционные мутации
Исследование [81] посвящено разработке инструмента планирования мутаций путем применения адаптированного под фаззинг-тестирование генетического алгоритма - DARWIN. Ключевой особенностью представленного подхода является использование эволюционных процессов (скрещивание видов, выживание и пр.) с целью оптимизации процесса выбора мутаций.
При этом становится возможным снизить уровень зависимости от участия пользователя в процессе настройки параметров.
При запуске инструмента выполняется инициализация набора базовых мутаций, которые применяются к входным данным. Следующим шагом является оценка результатов всех примененных мутаций и присвоение каждой из них определённого значения «fitness score». Такое решение позволяет «выживать» более перспективным мутациям и устранять те, действия которых не позволяют достичь прогресса. Помимо этого, DARWIN использует такие операторы генетических алгоритмов, как кроссовер (операция скрещивания генов) и модификация (процесс мутации генов) с целью формирования новых стратегий мутации входных данных.
Те мутации, которые приносят положительный эффект в процесс обнаружения уязвимостей, считаются наиболее пригодными и чаще применяются, в то время как менее удачные мутации постепенно исключаются.
Вопрос оптимизации процесса выбора мутаций актуален на протяжении нескольких лет, что мотивирует ученых стремиться к увеличению эффективности работы фаззеров. Так, например, в статье [82] предложена схема планирования мутаций MOpt, основанная на модифицированном алгоритме оптимизации роя частиц. Данное решение обусловлено возможностью выполнения поиска наиболее уместного распределения вероятностей выбора тех или иных мутаций и их порядка.
В MOpt также первым шагом является определение начального набора мутаций, по результатам применения которого выполняются первые мутации. В качестве целевой функции алгоритма роя частиц рассматривается увеличение процента покрытия программного кода и обнаружение уязвимостей. Таким образом, частицами в данном случае являются параметры мутаций (вероятность распределения и веса для каждой мутации), настройка которых приводит к оптимизации анализа. Каждая частица формирует свою последовательность применения различных видов мутаций (стратегия), которая оценивается с помощью MOpt для анализа исследуемых метрик
и сохранения наиболее оптимальных стратегий. Те частицы, чьи стратегии оказались менее успешными, изменяют свою стратегию и соответствующие вероятности на основе своих лучших исполнений и опыта других частиц.
3.2 Интеллектуальный метод мутации входных корпусов с обратной
связью
Несмотря на то, что в рамках методологии предполагается использование точечного фаззинг-тестирования, не предполагающего тестирование всех путей исполнений бинарного файла, одной из проблем, присущих фаззинг-тестированию, остается длительное время получения результата ввиду высокого показателя случайности мутации входных данных.
Возможность мутации входных данных присутствует в различных инструментах фаззинг-тестирования, в частности, в распространенном средстве AFL (American Fuzzy Lop) [83-85] есть модуль под названием «мутатор», задачей которого является подготовка нового входного корпуса на основе того, который подавался на вход ПО на прошлой итерации. Однако штатный мутатор AFL не обладает возможностями анализа входных корпусов [84, 86]: в нём реализованы только базовые операции, такие как инвертирование бита, подмена строки или подстроки, сокращение длины корпуса или его увеличение произвольными данными и т. д. Такой довольно узкий функционал по эффективности сравним с методом перебора - в обоих случаях время обнаружения ошибок и различных дефектов в ПО существенно увеличивается [84]. При этом отсутствует также возможность доработки того корпуса данных, который вызвал некорректное поведение, до полноценного подтверждения концепта. Вместо этого пользователь должен самостоятельно реализовать его, опираясь на такие характеристики корпуса, как его размер, семантические особенности и пр.
Одним из направлений исследований в рамках диссертационной работы являлось применение нейросетевых методов для генерации наборов входных данных (входных корпусов). В частности, в работе [65] автором диссертационной работы предложен метод мутации входных корпусов с обратной связью, в основе которого лежит ИНС на базе архитектуры долгой краткосрочной памяти (Long Short Term Memory, LSTM). Данный тип ИНС имеет ключевую особенность - вентили забывания, которыми может быть задано окно удержания опыта.
Реализация такого метода позволяет учитывать
предыдущий опыт, иными словами, удерживать контекст за счёт возможности обработки обратной связи, поступающей в качестве реакции тестируемого ПО на входной корпус, с преобразованием такого входного корпуса - мутацию в соответствии с полученной реакцией.
По результатам анализа известных работ можно сделать вывод, что для мутации входных корпусов ранее не применялись методы на основе рекуррентных нейронных сетей. Известные методы позволяют получить прирост покрытия, однако их применение ограничено спецификой тестируемого ПО.
Предлагаемый метод является интеллектуальным за счёт применения такого механизма ИИ, как нейронные сети. Обучение с использованием нейронной сети позволяет реализовать мутационный механизм фаззинга, обеспечивающий мутацию не всех корпусов входных данных, а только тех, которые ранее уже подвергались мутации, то есть наиболее перспективных с точки зрения тестирования, и с учётом контекста - реакции программы на подобные входные данные. Таким образом, реализуется интеллектуальная мутация входных данных, обеспечивается прирост покрытия и гарантируется возможность использования метода для различных образцов ПО.
3.2.1 Процесс мутации входных корпусов
При фаззинг-тестировании с применением мутации инструменту предоставляются сведения о полном наборе начальных входных корпусов: формат, максимальная и минимальная длина, наличия закономерностей или последовательностей в корпусе и т.д. На основе полученной информации мутатор - модуль преобразования создает новые образцы входных корпусов, которые изменены в соответствии с указанными правилами мутации [87, 88]. Штатный мутатор поддерживает базовые преобразования, например: инвертирование произвольного бита входного корпуса, дополнение входного корпуса под последовательностью, перестановка слов и групп слов входного корпуса. Общий принцип работы мутатора представлен на рисунке 3.1.
Рисунок 3.1 - Общий принцип работы мутатора
Совокупное применение данных преобразований позволяет получить огромное количество вариантов входных корпусов, однако базовый мутатор не учитывает их синтаксические и семантические особенности, вследствие чего уровень покрытия на протяжении долго времени может оставаться низким [88]. Прежде всего, это связано с тем, что для запуска ПО чаще всего требуется ввести
команду с заданными параметрами, которые стандартизированы разработчиком, а при получении в качестве аргументов сырых данных, ПО, вероятнее всего, будет выводить сообщение с поддерживаемыми командами.
В зависимости от целей фаззинг-тестирования создаются собственные мутаторы, расширяющие функционал штатных. Основной задачей мутатора является создание разнообразного множества входных корпусов с целью обеспечения прироста покрытия на каждой итерации фаззинг-тестирования. Таким образом, для выполнения, например, фаззинг-тестирования сетевого сокета необходимо реализовать мутатор сетевого трафика. Мутатор сырых данных будет модифицировать сетевой пакет без учета требований к его формату, что приведет к отбрасыванию сетевого пакета в стеке ТСР\1Р до его попадания в сетевой сокет и ПО.
Несмотря на такие преимущества мутационных фаззеров, как простота настройки и скорость создания новых входных корпусов, они имеют два существенных недостатка, обусловленных самим механизмом мутации:
1. Мутационные фаззеры могут пропустить комплексные уязвимости, требующие значительных изменений данных ввиду простоты выполняемых в отношении входных корпусов преобразований.
2. Мутационные фаззеры не смогут воспроизвести все возможные формы протокола или формата файла в соответствии со спецификацией ввиду отсутствия правил для модификации файла или кадра протокола.
Данные недостатки могут быть компенсированы разработкой собственного мутатора с заданным набором правил и применением комплексных операций в отношении корпусов, однако такой мутатор может быть применим только в отношении конкретного экземпляра или нескольких схожих экземпляров ПО, так как он не обеспечивает полной унификации. Для унификации мутатора необходимо использование механизма, который обеспечивает мутацию на основе контекста (например, принимаемых на вход типов данных) и обратной связи -реакции программы на входной корпус.
Решением такой проблемы является использование интеллектуального подхода к выбору стратегии мутации, который учитывает состояние тестируемого ПО после того, как ему на вход были поданы мутированные корпуса данных. Критерием отбора наиболее перспективных корпусов является нештатное поведение программы или её завершение с ошибкой. Тем не менее сам принцип модификации фрагментов входных корпусов, вызвавших нештатное поведение, также должен основываться на обратной связи, получаемой от программы.
3.2.2 Возможности искусственной нейронной сети с долгой краткосрочной
памятью
Для удержания контекста могут быть использованы, например, статистические методы, однако они, как правило, предполагают использование временных окон, что может повлиять на производительность системы ввиду большого количества вычислений, реализуемых параллельно с фаззинг-тестированием. Известно, что ИНС, использующие рекуррентный механизм, имеют возможность запоминания контекста ввиду архитектурных особенностей. Наиболее перспективной архитектурой для этого является ИНС с долгой краткосрочной памятью. В ходе анализа известных методов мутации входных корпусов установлено, что ранее данный подход не предлагался, что подчеркивает важность проведенных исследований.
Архитектура ИНС с долгой краткосрочной памятью основана на принципе удержания предыдущего опыта, полученного нейронной сетью, с помощью вентилей забывания. Такие сети являются разновидностью рекуррентных нейронных сетей, то есть сетей, имеющих обратную связь [89]. Благодаря этому LSTM-сети решают проблему долговременной зависимости - запоминания в рамках достаточно больших окон [90]. Традиционно LSTM сети используются
в обработке естественного языка, распознавании речи, а также в генерации музыки и текста [89, 91].
Как любая рекуррентная сеть, сеть LSTM состоит из цепочки повторяющихся модулей обычной нейронной сети, состоящей из четырех слоев. Ключевым компонентом модуля LSTM является состояние ячейки - аналога конвейерной ленты, которая проходит через все модули сети. В тракте состояния ячейки данные передаются свободно и в отношении них могут быть применены различного рода линейные операции.
Для контроля состояния ячейки применяются фильтры - вентили забывания, традиционно представляющие собой слой сигмоидальной нейронной сети и операции поточечного умножения. Данный слой возвращает значение в интервале от 0 до 1 включительно, означающее, какой объём данных пропустить в следующий модуль. В сети LSTM реализовано три таких фильтра, которые позволяют защищать данные от забывания и контролировать состояния ячейки.
В ходе обучения для минимизации ошибки на всём множестве тренировочных последовательностей применяется метод обратного распространения ошибки, развёрнутый во времени. Это, в свою очередь, позволяет корректировать веса пропорционально производной градиентного спуска в зависимости от величины ошибки.
Несмотря на один из важнейших недостатков применения градиентного спуска для обучения стандартных рекуррентных ИНС - градиенты ошибок уменьшаются с экспоненциальной скоростью по мере увеличения временной задержки между важными событиями - его применение для обучения LSTM сетей достаточно эффективно [92]. Это обусловлено механизмом контроля состояния ячейки. Когда величины ошибки распространяются в обратном направлении от выходного слоя, ошибка оказывается «заперта» в памяти блока, что создает ситуацию «карусели ошибок», которая непрерывно передает ошибку обратно каждому из вентилей, пока они не будут натренированы отбрасывать значение.
Принцип работы сетей с долгой краткосрочной памятью состоит из четырех этапов [91, 93].
1. Данные, поступающие в модуль сети, передаются на слой фильтра забывания, определяющий объём информации, который пропускается в следующий слой [92]. Значение предыдущего выхода кг-1 и текущего входа хг передаются в сигмоидальный слой и приобретают коэффициенты от 0 до 1. Значения с коэффициентами ближе к 0 забываются, ближе к 1 - передаются далее. Данный этап описывается формулой (3.1).
о(Шг*[к,-1>х,] + Ьг) (3Л)
2. Определяется, какая информация будет храниться в состоянии ячейки
[88].
Данный этап делится на два подэтапа. Сначала сигмоидальный слой - слой входного фильтра - определяет, какие значения должны быть обновлены (3.2).
1,= о( Ш1*[к,-1>х1] + Ьг) (3.2)
После чего слой гиперболического тангенса строит вектор новых значений кандидатов С [, которые могут быть добавлены в состояние ячейки (3.3).
С = t апк(Шс * [к,-1, х,] + Ьс) (3.3)
Далее, для того чтобы изменить старое состояние ячейки С г-1 на С г, необходимо умножить его на значение ^ и прибавить I * С [ (3.4). Таким образом, применяется механизм забывания в отношении состояния ячейки [93, 94]. Фактически, полученные значения будут являться кандидатами, умноженными на число необходимых изменений.
Сг= Ь* сг-1 + 4* С
(
(3.4)
3. Последний этап заключается в определении объёма выходной информации [94]. Значения предыдущего выхода и текущего входа хг проходят сигмоидальный слой, который определяет объём вывода из состояния ячейки (5).
оъ = о(Ш0 [к1-1,х1] + Ь0 I
(3.5)
После этого значения состояния ячейки проходят слой гиперболического тангенса для получения на выходе значений в диапазоне от 1 до -1, которые в свою очередь перемножаются с выходными значениями сигмоидального слоя (3.6).
= Ос* tanh(Ct) I
(3.6)
Полученные значения и передаются в следующий модуль цепочки.
3.2.3 Описание метода мутации
В рамках предлагаемого метода предполагается модификация штатного мутатора механизмом, получающим на вход предыдущий корпус \г-1 и трассу исполнения , которую этот корпус прошел в тестируемой программе. На основании значений кортежа входных данных (11-1,Т1) вычисляются необходимые для увеличения покрытия мутации М1, входящие во множество возможных операций преобразования (7).
М1 = фъ^, Ба,5й1
(7)
где:
- Рь (у) = чи - инвертирование бита, V - значение произвольного бита;
- К;(5) = ч - инвертирование подстроки, б - значение произвольной подстроки;
- Ба(5,й) = 5 + й - добавление подстроки, б - исходная строка, ё - подстрока;
- Ба(5,ф = б — й - удаление подстроки, б - исходная строка, ё - подстрока.
Объём необходимых мутаций при этом оценивается, исходя из длины трассы, фиксируемой в рамках заданного временного окна: если длина трассы не изменяется на протяжении N запусков, количество мутаций входного корпуса, осуществляемых в рамках одной итерации, увеличивается до тех пор, пока не будет зафиксирован прирост по покрытию. При обнаружении прироста количество мутаций снижается до исходного значения.
После того, как в ходе фаззинг-тестирования установлено нештатное завершение работы тестируемого ПО, мутация с целью увеличения покрытия прекращается. Вместо этого происходит загрузка второго блока входных корпусов, содержащих исполняемый код для создания подтверждения концепта. Входные корпуса второго блока состоят из двух частей: входного корпуса, вызвавшего нештатное завершение работы, и шелл-кода.
Мутация на данном этапе выполняется только в отношении шелл-кода в соответствии с заданными правилами М2 (9).
М2 = [Ыа,ЫфАт],
где:
На(п) - увеличение NOP-дорожки на значение п,
- Nd(n) - уменьшение NOP-дорожки на значение n,
- Am(amin, amax) - изменение адреса возврата на произвольный, в диапазоне [amin, amax]•
Данный этап выполняется до тех пор, пока шелл-код не будет выполнен, то есть пока не прекратится нештатное завершение тестируемого ПО. После этого фаззер переходит к новой итерации и продолжает искать новые трассы в ПО. Наглядно действие описанного метода представлено на рисунке 3.2.
Рисунок 3.2 - Схема работы интеллектуального метода мутации входных данных
Теоретическая значимость метода заключается в расширении известных методов и стратегий мутации входных корпусов новым интеллектуальным методом на основе ИНС. Полученные результаты могут лечь в основу средств фаззинг-тестирования нового поколения, отличающихся универсальностью и возможностью создания подтверждения концепта выявленной уязвимости без участия эксперта.
Практическая значимость метода заключается в сокращении трудоёмкости поиска уязвимостей в ПО, эксплуатации которых способна привести к исполнению вредоносного кода. Оптимизация скорости поиска и повышение степени автоматизации положительно скажутся не только в контексте обеспечения безопасности информационных систем, но и локализации уязвимости при её устранении.
3.2.4 Примеры работы метода
Метод предполагает наличие некоторого набора исходных корпусов входных данных, над которыми, в зависимости от реакции исследуемой программы, будут выполнены преобразования с использованием разработанного интеллектуального метода. Поэтому первый запуск программы в рамках тестирования всегда будет осуществляться с исходными корпусами для оценки их корректности как с синтаксической, так и семантической стороны. Полученная реакция программы сохраняется для определения вектора мутации.
После первого запуска производится модификация исходного входного корпуса и повторный запуск с оценкой покрытия и сохранением полученных результатов, которые передаются в ИНС вместе с мутированным входным корпусом. Тип и масштаб последующих мутаций определяется исходя из полученного на первом запуске показателя покрытия. На данном этапе основной целью является вызов нештатного завершения программы.
В случае обнаружения нештатного завершения информация о месте нарушения целостности программного стека или выхода за пределы динамически выделенной памяти передается в ИНС, что инициирует начало второго этапа.
На втором этапе осуществляется модификация входного корпуса с использованием заранее заданных начальных шаблонов шелл-кода. Здесь
объектом мутации является сам шелл-код, которые модифицируется в соответствии с правилами, заданными в ИНС. Запуск шелл-кода в среде запущенной программы не приведет к нештатному завершению работы до завершения работы шелл-кода. Таким образом, критерием успеха на данном этапе будет являться отсутствие такого завершения работы. При успешном запуске фиксируется состояние тестируемой программы, сохраняются необходимые для дальнейшего анализа сведения и осуществляется проверка достижения целей фаззинг-тестирования.
Алгоритм завершается при достижении целей фаззинг-тестирования, которые определяются оператором. К таким целям относится достижение определённого покрытия по функциональным блокам (для тестирования «черного» или «серого ящика») или строкам кода (для тестирования «белого ящика») или прошествие определённого времени фаззинг-тестирования без прироста покрытия. По умолчанию алгоритм завершится при фиксировании одного и того же состояния тестируемой программы на протяжении 300 итераций. Такое поведение будет означать, что вариативность возможных мутаций, которые привели бы к нештатному завершению или исполнению шелл-кода, исчерпана.
Ключевой особенностью метода является возможность его применения вне зависимости от типа ПО. Универсальность применения обеспечивается механизмами, на базе которых данный метод реализован. В основе движка мутации реализована ИНС с долгой краткосрочной памятью, которая фиксирует контекст и позволяет адаптировать мутированные ранее корпуса в зависимости от реакции программы на запуск с их подачей. Кроме того, использование ИНС позволяет абстрагироваться от характера входных корпусов, взаимодействуя с ними как с набором данных без привязки к их типу - сетевые пакеты, бинарные данные, строка аргументов и т.д.
Для оценки эффективности метода реализована среда для проведения фаззинг-тестирования с использованием одного из наиболее популярных средств - АБЬ++. В контексте проводимого эксперимента, описанного также
в работе автора [65], эффективность выражается как время до обнаружения уязвимости. Для сравнения эффективности предложенного метода с реальными мутаторами использованы мутаторы Огаттаг-МШ:а1:ог, Бирепоп и НЬрго1:оЬи£ В качестве объекта фаззинг-тестирования определён веб-сервер п§тх. На этапе подготовки в логику работы веб-сервера внесена уязвимость переполнения буфера на стеке при подаче конфигурационного файла, размер которого превышает 2 Мбайт. Результаты проведенного эксперимента приведены в таблице 3.1.
Таблица 3.1 - Результаты оценки эффективности предлагаемого метода
Интеллектуальный метод мутации GrammarMutator Superion libprotobuf
Время до
обнаружения 02:17:43 08:53:21 07:11:59 11:14:36
уязвимости
Покрытие 8,34% 7,22% 7,56% 4,49%
Количество итераций 181 776 352 011 286 101 422 563
Кроме того, запуск шелл-кода посредством предлагаемого метода мутации осуществлен спустя 11 часов с момента начала фаззинг-тестирования. Полученный в результате мутации шелл-код представлял собой бесконечный цикл с выводом времени собственного запуска. Логика вывода времени была заложена на этапе обучения ИНС. В дальнейшем набор шаблонов может быть расширен посредством её дообучения.
Метод также был применён для фаззинг-тестирования почтовых сервисов; данный эксперимент детально описан в работе автора [95]. Современные почтовые сервисы представляют собой комплексную программную систему, состоящую из служб, обрабатывающих различные почтовые протоколы. К наиболее распространенным почтовым протоколам относятся POP, IMAP
и SMTP. Каждый из приведенных протоколов имеет расширения, допускаемые соответствующим стандартом, в котором описаны протоколы [95, 96]. Многообразие доступных расширений для протоколов при необходимости их реализации обуславливает серьезные угрозы для безопасности почтовых сервисов. Ошибки, которые могут привести к эксплуатации уязвимостей в реализациях расширения, могут быть внесены как на этапе разработки конкретных модулей, так и на этапе проектирования архитектуры. Уязвимости в пограничных узлах, особенно если они имеют доступ к сети Интернет, могут привести не только к компрометации пользователя, но и к компрометации всей системы в целом.
Оценка эффективности разработанного метода производилась по числу вызванных нарушений работы почтового клиента или сервера в процессе фаззинг-тестирования. Работа фаззера, использующего разработанный метод, сравнивалась с работой штатного мутатора инструмента AFL. В качестве почтовых клиентов, подверженных фаззинг-тестированию, были выбраны клиенты Mutt, Alpine и Sup, поддерживающие расширения протоколов и интерфейс, выполненный в командной строке. Почтовыми серверами для обслуживания выбранных клиентов были назначены sendmail и postfix, наиболее распространенные как в открытом сообществе, так и в корпоративной среде.
Для каждой комбинации «клиент - сервер» проводись эксперименты продолжительностью 24 часа с использованием описанных в настоящей работе протоколов и расширений. Параллельно в рамках одной сессии тестировалась только одна пара «клиент - сервер». Засчитывались уникальные ошибки, подтвержденные экспертным анализом.
Результаты фаззинг-тестирования с использованием штатного фаззера AFL и фаззера AFL, модифицированного в соответствии с рассмотренным методом, приведены в таблице 3.2.
Таблица 3.2 - Результаты фаззинг-тестирования с применением штатного и модифицированного фаззеров AFL
Почтовый клиент Штатный фаззер AFL Модифицированный фаззер AFL
Postfix sendmail Postfix sendmail
Mutt 0 1 отказ сервера 1 отказ клиента и сервера 1 отказ сервера
Alpine 0 0 0 1 отказ сервера
Sup 0 1 отказ сервера 2 отказа клиента 1 отказ сервера
Из данных, приведенных в таблице 3.2, следует, что штатный фаззер AFL выявил по одному нарушению работы в парах «Mutt - sendmail» и «Sup -sendmail».
В ходе анализа полученных результатов было установлено, что эти нарушения связаны с превышением максимально допустимого размера вложения в электронное письмо. При попытке отправить вложение с размером более чем 4294967295 байт (что соответствует максимальному размеру переменной типа «long unsigned int» в языке программирования C) по протоколу SMTP произошла ошибка сегментации из-за переполнения целочисленного значения при отправке команды «DATA» протокола SMTP c расширением MIME версии 1.0 от соответствующих клиентов.
Отсутствие отказов со стороны почтового сервера Postfix обусловлено ограничениями, которые реализованы в логике работы сервера: вложения более чем 4 Гб по умолчанию не поддерживаются, а почтовому клиенту отправляется соответствующее уведомление. Аналогично для почтового клиента Alpine: пользователь получается уведомление о том, что вложение превышает допустимый размер, поддерживаемый сервером.
Из таблицы 3.2 следует, что доработанный фаззер AFL определил семь отказов работы во всех исследуемых парах «клиент - сервер», за исключением «Alpine - Postfix». Выявленные отказы для комбинаций «Mutt - sendmail»
и «Sup - sendmail» такие же, как и в случае применения штатного фаззера AFL (в таблице 3.2 они выделены полужирным начертанием).
Кроме того, при попытке инкапсуляции запроса в SMTP установлен один новый отказ сервера в паре «Alpine - sendmail», связанный с расширением XTND XMIT. Сгенерированные с помощью модуля мутации входные данные позволили заполнить поля пакета POP так, что в ходе его десериализации на сервере происходило зависание в бесконечном цикле из-за некорректной ссылки на начало инкапсулированного пакета. Это, в конечном счёте, привело к тому, что ОС завершила процесс, посчитав его «зомби-процессом».
Обнаруженные нарушения работы пары «sup - Postfix» связаны со спецификой работы расширения ACL при попытке получения списка электронных писем для определения доступа. Одно нарушение работы было при попытке загрузить письма для пользователей из списка доступа, в котором находилось 0 пользователей. В результате ответа от сервера происходило разыменование нулевого указателя, что привело к окончанию работы клиента из-за сигнала ОС SIGINT. Ещё одно нарушение работы комбинации «sup - Postfix» вызвано расширением MIME. При указании в поле Content-Transfer-Encoding кодировки «7bit» и использовании кодировки base64 выполняется некорректная обработка вложения, в результате чего буфер на стеке переполняется, и клиент завершается с ошибкой сегментации.
Отказ, вызванный в паре «Mutt - Postfix», выявлен в ходе одной итерации. При создании очереди отправлений на клиенте Mutt уникальный идентификатор не является структурой. В случае если его размер превышает 128 байтов во время отправки сообщений с клиента, происходит ошибка в логике распаковки идентификатора, так как при таком значении этот идентификатор считается структурой. В результате при сохранении истории исходящих сообщений клиент прекращает работу с ошибкой сегментации памяти. Аналогично почтовый сервер Postfix при попытке сохранения писем с некорректным идентификатором очереди завершает работу с ошибкой сегментации памяти
из-за попытки десериализации и распаковки идентификатора, представляющего собой ложную структуру.
3.3 Метод генерации некорректных данных для проведения фаззинг-тестирования приложений с помощью NFC
Отдельным направлением исследований в части генерации данных для фаззинг-тестирования является подготовка данных именно для мобильных приложений, работающих по технологии NFC (Near Field Communication), обеспечивающей беспроводную передачу данных на короткие расстояния (до 10 сантиметров). Такие приложения также являются бинарными файлами, однако ориентированы в первую очередь на мобильные устройства. Для выполнения передачи данных с помощью NFC используются специальные чипы, работа которых основана на электромагнитной индукции. Данная технология передачи может применяться, к примеру для эмуляции банковских карт (оплата с помощью смартфона), для осуществления пропускного контроля через системы контроля и управления доступом (СКУД), для считывания данных с внешней аппаратной метки (NFC-метки), для передачи данных между мобильными приложениями.
Использование технологии NFC также может приводить к нарушению безопасности устройств и приложений из-за эксплуатации уязвимостей, которые основаны на ошибках в реализации обработчиков пакетов NFC. К примеру, уязвимость CVE-2023-35671 позволяет злоумышленнику получить данные о сохраненных в «GoogleWallet» банковских картах с помощью внешнего считывателя NFC [98].
Обнаруживать дефекты в таких приложениях также удобно с использованием фаззинг-тестирования, в том числе точечного, составляющего часть методологии автоматизированного обнаружения ошибок и НДВ в ПО.
Однако актуальным остается вопрос о формировании эффективного набора входных данных для проведения фаззинг-тестирования. На решение данной проблемы направлены работы [99, 100]. Авторы работы [99] разработали алгоритм генерации тестовых сообщений «NFC Data Exchange Format» (NDEF), используемых для передачи данных с помощью NFC. Алгоритм использует четыре стратегии для построения тестовых примеров - вручную, генерация, мутация и «обратный анализ». На основе алгоритма также разработан инструмент «GNFCVulFinder», предназначенный для поиска уязвимостей в приложениях Android и Windows. Авторы работы [100] подробно исследуют стек протоколов NFC, форматы передаваемых данных. Описываются способы проведения фаззинг-тестирования различных уровней стека протоколов.
Однако предложенные авторами подходы к генерации некорректных данных обладают существенным недостатком, а именно, отсутствием возможности автоматической генерации тестовых данных с помощью внесения конфликтов в заголовки пакетов NDEF. Для устранения данного недостатка автором диссертационной работы создан метод [66] генерации некорректных данных, опирающийся на особенности структуры NDEF-сообщений. Непосредственно перед описанием работы метода следует рассмотреть процесс передачи данных с использованием NFC.
3.3.1 Передача данных с помощью NFC
При работе с NFC приложения, как правило, используют сообщения NDEF для обмена данными в двоичном формате. Основной контейнер данных, определённый форматом NDEF, называется NDEF сообщением, оно состоит из одной или нескольких записей NDEF разных типов. Тип характеризует вид данных, которые содержат запись, а последовательность типов записей
в сообщении определяет вид сообщения. Например, сообщение URI содержит одну запись, которая кодирует строку URL.
При работе с NDEF сообщениями разработчики мобильных приложений могут использовать и собственные, и сторонние программные библиотеки. Так, например, распространён набор инструментов разработки nRFConnect SDK [101]. Также известны библиотеки, ориентированные на работу с конкретными типами сообщений и записей, и универсальный генератор, который может быть использован для простой реализации других стандартизированных записей и сообщений или даже для создания собственных записей.
Каждое сообщение NDEF содержит одну или несколько записей, каждая из которых состоит из заголовка и полезной нагрузки [102]. Заголовок записи содержит метаданные о типе и длине полезной нагрузки. Полезная нагрузка записи представляет собой её фактическое содержимое. Структура сообщения и записи NDEF представлена на рисунке 3.3.
7 6 5 4 3 2 10 1 I
MB ME CF SR IL 1 1 TNF I |
T YPE .ENGT H
1 PAYLOAD | 1 1 1 LENGTH 3 1 1 1
Обратите внимание, представленные выше научные тексты размещены для ознакомления и получены посредством распознавания оригинальных текстов диссертаций (OCR). В связи с чем, в них могут содержаться ошибки, связанные с несовершенством алгоритмов распознавания. В PDF файлах диссертаций и авторефератов, которые мы доставляем, подобных ошибок нет.