Введение 3
Постановка задачи 5
1. Обзор предметной области 6
1.1. Taint анализ 6
1.2. Символьное исполнение в KLEE 7
1.2.1 Генерация моков 9
1.3. Taint конфигурации 10
1.4. Существующие решения 11
2. Реализация taint анализа в символьной машине KLEE 13
2.1. Основная идея 13
2.2. Работа с памятью 13
2.2.1 Символьные taint выражения 14
2.2.2 Хранение в памяти символьных taint выражений .... 15
2.2.3 Чтение и запись в память символьных taint выражений . 15
2.3. Вспомогательные функции 16
2.4. Taint конфигурации 17
2.4.1 Taint правила 18
2.4.2 Аннотации функций 19
2.5. Генерация моков внешних функций 19
2.5.1 Загрязнение данных 20
2.5.2 Распространение загрязненных данных 20
2.5.3 Проверка загрязненности данных в стоке 20
2.6. Архитектура итогового решения 22
3. Эксперименты 23
3.1. Тестовый стенд 23
3.2. Результаты экспериментов 23
Заключение 25
Список литературы 26
В современном мире важной характеристикой любого программного продукта является его надежность, поскольку с ростом кодовой базы растёт вероятность появления в коде уязвимостей и ошибок. Поэтому тестирование является важнейшей и неотъемлемой частью разработки любого программного продукта. Но с увеличением объема кода растут затраты на тестирование, поэтому важной задачей является автоматизация тестирования и поиска уязвимостей. Одним из эффективных подходов для автоматизации тестирования является символьное исполнение [1]. Вместо конкретных данных, поданных на вход программы, символьное исполнение оперирует символьными выражениями, которые подразумевают под собой произвольные значения. Из ограничений на символьные выражения составляются предикаты, описывающие условия прохождения исследуемой программы по конкретному пути исполнения. Из модели условия пути можно получить конкретные входные данные, то есть тест, который приведёт к воспроизведению конкретной трассы. Так при помощи символьного исполнения можно получать тесты, воспроизводящие конкретные дефекты в программе. Это эффективный метод, который позволяет обнаружить маловероятные ошибки [1]. Одним из инструментов, реализующих символьное исполнение для компилируемых в LLVM [2] языков, является символьная виртуальная машина KLEE [3], которая используется в современных анализаторах кода, таких как KLOVER [4] и LibKluzzer [5].
Недостатком символьного исполнения является сложность анализа внешних функций, по путям исполнения которых не может пройти символьное исполнение [6]. Одним из решений данной проблемы является генерация моков для вызываемых в программе внешних функций [7]. Этот подход позволяет символьному исполнению продолжать обходить пути исполнения, несмотря на отсутствие доступа к настоящему телу внешней функции. Однако моки- рование не решает эту проблему полностью, поскольку неизвестно реальное поведение внешних функций, такие как их влияние на поступившие на вход данные, а также свойства возвращаемого значения. Вызовы функций, взаимодействующих с внешним окружением: файлами, сетью, библиотеками, — могут оказывать влияние на данные, задействованные в исследуемой программе, и приводить к ошибкам и уязвимостям. Примером подобной уязвимости является SQL-инъекция [8].
Одним из подходов для решения данной проблемы является taint анализ [9][10]. Основная идея этого подхода состоит в отслеживании распространения по программе потенциально опасных данных, полученных из внешнего источника, и нахождении путей их попадания в уязвимые места программы. В рамках данного подхода потенциально опасные данные, полученных из внешнего источника маркируются, а перемещение маркированных данных по программе отслеживается. Если маркированные данные не очищаются, то taint анализ сообщает об ошибке в случае их попадания в уязвимое место программы. Таким образом, задачей данной работы стала реализация taint анализа на базе символьного исполнения.
Основная идея реализации taint анализа при помощи символьного исполнения состоит в том, чтобы хранить символьную информацию о загрязненности объекта вместе с его символьным значением, использовать её при построении условий путей исполнения и таким образом отслеживать, существуют ли входные данные, при исполнении которых загрязненные данные дойдут от источника к стоку.
Подход был реализован в KLEE. Работа выполнена при поддержке российского исследовательского института Huawei. Тестирование реализованного инструмента проведено на тестовом наборе данных Juliet Test Suite for C/C++ 1.3. В результате тестирования на CWE134, на тестах, поддерживаемых текущим конфигурационным файлом аннотаций, было получено правдиво положительное значение на всех 195 тестах.
В данной работе были выполнены следующие задачи.
• Изучены существующие подходы к taint анализу, в том числе реализованные на базе символьного исполнения. В результате анализа информации были приняты решения относительно харнения и передачи загрязненных данных в символьном исполнении KLEE.
• Предложен и реализован способ хранения в символьной памяти и передачи во время исполнения загрязненных данных. Также были реализованы методы для работы с загрязненными данными в символьной памяти.
• Предложены и реализованы конфигурации для taint аннотаций и taint правил. Конфигурации являются полностью расширяемыми и независимыми.
• Реализована генерация LLVM кода для обработки taint аннотаций. Также были реализованы вспомогательные LLVM функции для работы символьной памятью в процессе исполнения.
• Проведено ручное тестирование на простых тестах. Проведено тестирование реализованного инструмента на тестовом наборе данных Juliet Test Suite for C/C++ 1.35.
Таким образом был разработано усовершенствование для символьной машины KLEE, использующее taint анализ с помощью символьного исполнения.
5https://github.com/arichardson/juliet-test-suite-c
[1] King J. C. Symbolic execution and program testing //Communications of the ACM. - 1976. - Т. 19. - №. 7. - С. 385-394.
[2] Lattner C., Adve V. LLVM: A compilation framework for lifelong program analysis & transformation //International symposium on code generation and optimization, 2004. CGO 2004. - IEEE, 2004. - С. 75-86.
[3] Cadar C. et al. Klee: unassisted and automatic generation of high-coverage tests for complex systems programs //OSDI. - 2008. - Т. 8. - С. 209-224.
[4] Li G., Ghosh I., Rajan S. P. KLOVER: A symbolic execution and automatic test generation tool for C++ programs // Computer Aided Verification: 23rd International Conference, CAV 2011, Snowbird, UT, USA, July 14-20, 2011. Proceedings 23. - Springer Berlin Heidelberg, 2011. - С. 609-615.
[5] Le H. M. LLVM-based Hybrid Fuzzing with LibKluzzer (Competition Contribution) // FASE. - 2020. - С. 535-539.
[6] Baldoni R. et al. A survey of symbolic execution techniques //ACM Computing Surveys (CSUR). - 2018. - Т. 51. - №. 3. - С. 1-39.
[7] С. А. Шмидт. Разработка программного средства для автоматической изоляции тестируемого LLVM кода. ВКР бакалавра, СПбГУ, 2023.
[8] Halfond W. G. et al. A classification of SQL-injection attacks and countermeasures //Proceedings of the IEEE international symposium on secure software engineering. - Piscataway, NJ : IEEE, 2006. - Т. 1. - С. 13-15.
[9] Wang L., Li F., Li L., Feng X.-B. Principle and Practice of Taint Analysis // Ruan Jian Xue Bao/Journal of Software. — 2017. — Апр. — Т. 28. — С. 860-882. — DOI: 10.13328/j.cnki.jos.005190.
[10] Kim J., Kim T. G., Im E. G. Survey of dynamic taint analysis //2014 4th IEEE International Conference on Network Infrastructure and Digital Content. - IEEE, 2014. - С. 269-272.
[11] Cooddy, static analysis tool. URL: https://github.com/program- analysis-team/cooddy (дата обр. 26.05.2024)
[12] Clang Static Analyzer. URL: https://clang-analyzer.llvm.org/ (дата обр. 26.05.2024)
[13] Arroyo M., Chiotta F., Bavera F. An user configurable clang static analyzer taint checker //2016 35th International Conference of the Chilean Computer Science Society (SCCC). - IEEE, 2016. - С. 1-12.
[14] Barrett C., Tinelli C. Satisfiability modulo theories //Handbook of model checking. - 2018. - С. 305-343.
[15] De Moura L., Bjprner N. Z3: An efficient SMT solver //International conference on Tools and Algorithms for the Construction and Analysis of Systems. - Berlin, Heidelberg : Springer Berlin Heidelberg, 2008. - С. 337340.
[16] Niemetz A., Preiner M. Bitwuzla //International Conference on Computer Aided Verification. - Cham : Springer Nature Switzerland, 2023. - С. 3-17.
[17] Clang Static Analyzer, 2.2. Taint Analysis Configuration.
URL: https://clang.llvm.org/docs/analyzer/user-docs/
TaintAnalysisConfiguration.html (дата обр. 26.05.2024)
[18] LLVM, YAML I/O. URL: https://llvm.org/docs/
YamlIO.html#introduction-to-yaml (дата обр. 26.05.2024)
[19] Cooddy, static analysis tool, annotation configuration. URL: https://github.com/program-analysis-team/cooddy/blob/master/ config/.annotations. json (дата обр. 26.05.2024)
[20] Cooddy, static analysis tool, taint configuration. URL: https: //github.com/program-analysis-team/cooddy/tree/master/ checkers/cwe/config (дата обр. 26.05.2024)
[21] Christey S. et al. Common weakness enumeration //Mitre Corporation. - 2013.
[22] Pezoa F. et al. Foundations of JSON schema //Proceedings of the 25th international conference on World Wide Web. - 2016. - С. 263-273.
[23] Shimchik N. V., Ignatyev V. N. Vulnerabilities detection via static taint analysis //Труды института системного программирования РАН. - 2019. -Т. 31.-№. 3.-С. 177-190.
[24] Ivannikov V. P. et al. Static analyzer Svace for finding defects in a source program code //Programming and Computer Software. - 2014. - Т. 40. - С. 265-275.