Наш главный научный сотрудник ShiftLeft, Фабиан Ямагути, ранее обсуждал независимый от языка анализ с использованием графов свойств кода (CPG) и то, как эта инновационная технология используется в платформе ShiftLeft. В ShiftLeft наука статического анализа кода трансформируется в искусство понимания поведения вашего кода и создания профиля безопасности - средства описания ДНК безопасности заявление.

В этом посте я хочу изучить динамический анализ программ. Анализ программ во время выполнения с точки зрения безопасности - нетривиальная задача. Тот факт, что безопасность и надежность кода в производственной среде имеет первостепенное значение, накладывает ограничения на то, что можно делать во время выполнения кода. В основе любого динамического анализа - будь то анализ безопасности или производительности - является концепция инструментария кода.

Есть ли лучший способ узнать о состоянии приложения и понять его поведение, чем заставить приложение сообщать вам само?

Концепция зондов в приложении использовалась во многих поддоменах вычислений, давала причудливые имена, упаковывала, переупаковывала и перепродавала. Одним из таких инструментальных средств, на котором было построено множество инструментов, является трассировка программного обеспечения. Трассировка позволяет нам создавать инструменты, которые предоставляют такие показатели, как потоки программ, потоки данных и задержка функций. Хотя в самом чистом смысле методы трассировки использовались для повышения производительности и отладки, из-за характера исходных данных (стеки вызовов функций, аргументы, временные метки) мы также можем использовать их для реализации функций безопасности, таких как целостность потока управления (CFI) и динамическое отслеживание заражений путем сохранения состояний во время выполнения. Такой расширенный анализ традиционно является частью исследовательских групп по безопасности, и инструменты в основном сосредоточены на функциях, ориентированных на разработчиков, которые будут использоваться на этапах разработки или внутреннего тестирования. Однако современный сценарий DevOps требует такого уровня повышенной безопасности в производственных системах. Таким образом, гарантия надежности зависит от конкретных методов используемых контрольно-измерительных приборов.

Итак, это ведение журнала, а? Нейн. Ожидания разные. В то время как регистрация событий может быть полезна для просмотра важных, обычно менее частых событий (таких как передача сообщений об ошибках), трассировка может осуществляться на уровне детализации функций или инструкций - следовательно, для получения более подробной информации о высокочастотных событиях с целью незначительных накладных расходов.

Инструментарий кода

Процесс инструментирования включает вставку дополнительного фрагмента кода в блок кода либо во время компиляции (например, -finstrument-functions в GCC или Clang), либо во время выполнения (Cantrill et al.). Такое зондирование обычно выполняется при входе и выходе из наблюдаемой функции (показано полосой на графике) и позволяет нам собирать определенную информацию о них по мере их выполнения.

Эта информация может быть метками времени (полезными для профилирования) или аргументами функции и возвращаемыми значениями (полезными для определения того, какие данные проходят через функцию). Сбор информации происходит внутри обработчика зонда, который вызывается при обнаружении точки инструментария. Обработчик выполняет фильтрацию и сбор данных, а также генерирует то, что мы можем назвать событием. Набор событий может быть проанализирован на предмет значимых данных, проходящих через приложение, и может генерировать полезную информацию о его возможном отклонении от нормы.

Собственный код. В случае машинного кода, написанного на C / C ++, методы инструментария могут быть статическими или динамическими. В статической инструментарии код зонда и обработчика может быть частью самой цели, поскольку он встроен во время компиляции. В некоторых случаях компилятор может разрешить вставку специальных ловушек при входе и выходе функций, которые можно использовать для динамического включения или отключения зондов (например, GCC mcount). Для чисто динамического инструментария могут быть полезны бинарные инструментальные фреймворки, такие как Dyninst, поскольку они позволяют модифицировать бинарные файлы на уровне инструкций. Фактически, такие методы динамического инструментария для анализа безопасности изучались и раньше (Roundy et al.). Несмотря на элегантный подход, бинарная модификация всегда сложна и может не работать хорошо во всех сценариях (например, в запутанном коде, где необходимо угадывать границы функций).

Управляемый или динамический код. Инструментирование управляемого или динамического кода, такого как Java, Python или Ruby, несколько проще из-за стандартизации и встроенных инструментов в соответствующие виртуальные машины и интерпретаторы. Например, JVM предоставляет богатый набор инструментальных API, которые можно использовать для создания инструментов для обнаружения уязвимостей или применения политики безопасности (Hao et al.). Такие инструменты полагаются на инструментарий байт-кода на основе Java-агента, который позволяет коду наблюдения вставлять себя с почти нулевыми накладными расходами и собирать интересные данные из целевых функций. Btrace - хороший пример инструмента динамической трассировки для Java, который позволяет безопасно вставлять код анализа с помощью инструментария байт-кода Java. Точно так же интерпретаторы Python и Ruby поддерживают перехватчики статической трассировки, известные как зонды USDT (статически определяемая трассировка на уровне пользователя), которые могут быть полезны для понимания потока приложения.

Вставка безопасности во время выполнения

Как я уже говорил, существуют различные механизмы, позволяющие инструментировать код и получать потоки программ и данных из приложений. Это привело к разработке таких методов, как динамическое отслеживание зараженных данных, которые позволяют отслеживать испорченные данные через приложение с помощью методов мониторинга с отслеживанием состояния и стеков вызовов по мере выполнения программы. Это может быть хорошо для тестирования, и действительно, люди экспериментировали с Valgrind и показали многообещающие результаты (Newsome et al., Enck et al.). Но, как и ожидалось, в некоторых реализациях накладные расходы времени выполнения в таких сценариях могут быть недопустимыми для производственных систем (Bell et al.). Следовательно, имеет смысл иметь сокращенный набор наблюдений. В ShiftLeft мы расширяем границы и используем этот уровень анализа во время выполнения и делаем его готовым к работе.

Для производственных систем одной из целей является устранение любых внешних накладных расходов, которые вызывает сам вставленный код анализа.

Мониторинг и применение

С точки зрения безопасности, помимо детального анализа и мониторинга предупреждений, не менее важно и грубое наблюдение. Необходимо отслеживать общесистемные события, такие как повышение привилегий, доступ к ограниченным ресурсам и небезопасные сетевые операции. Эта постоянная осведомленность о безопасности укрепляет уверенность и помогает сформировать периферийное представление о приложении: как приложение взаимодействует с базовой системой и оборудованием; сопоставление точек входа и выхода для обмена сообщениями и сетевых операций. Наряду с мелкозернистым анализом, крупнозернистый анализ позволяет нам предвидеть события и формировать визуальную модель того, где приложение соответствует своей ДНК безопасности, и определять, происходит ли что-то мутации.

Поддержка ядра. Современные операционные системы предоставляют несколько механизмов для проверки систем времени выполнения и обеспечения мониторинга событий и обеспечения соблюдения политик безопасности. Ядро Linux предоставляет механизмы Linux Security Module (LSM), такие как SElinux и AppArmor, которые разрешают политики управления доступом на уровне процессов и ресурсов. Новые функции ядра, такие как eBPF, обеспечивают программируемость во время анализа событий трассировки и безопасности, что позволяет осуществлять дальнейший контроль и принудительное применение. Например, Google Chrome использует механизм безопасных вычислений (seccomp) для реализации песочницы с фильтрацией системных вызовов, чтобы защитить пользователей от выполняемых системных вызовов, занесенных в черный список. Пространства имен Linux также вводят разделение ресурсов в контейнерах и вместе с seccomp-bpf обеспечивают начальный уровень защиты.

Во время выполнения ShiftLeft использует современные конструкции безопасности и инструменты, предоставляемые самим приложением, а также динамический анализ кода, чтобы обеспечить детальный контроль над безопасностью приложения.

Обеспечение безопасности

Одна из самых важных ошибок во время выполнения - это предположение, что код, обеспечивающий безопасность, вероятно безопасен. Как видно из многочисленных инцидентов, подобных этим, антивирусные системы сами могут стать поверхностью атаки. Это требует нескольких указателей для разработки кода анализа времени выполнения. Важно использовать уроки, извлеченные за последние 25 с лишним лет разработки программного обеспечения, и использовать современные языки программирования, такие как Go и Rust, которые обеспечивают неотъемлемые конструкции безопасности. Сбор и агрегация событий должны соответствовать лучшим практикам безопасного обмена данными, а любой инструментальный код должен быть проверен и проверен. Например, Dyninst проверяет наличие рекурсивных трамплинов при построении кода анализа для вставки, а eBPF содержит собственный верификатор в ядре для проверки циклов и незаконных обращений к памяти. Другой подход заключается в создании систем, которые существуют долгое время и прошли испытания в боевых условиях, таких как ядро ​​Linux и JVM. Это, конечно, не освобождает разработчика от аудита приложения и его внутреннего тестирования.

Чтобы узнать больше о ShiftLeft и начать пользоваться бесплатной пробной версией, посетите наш веб-сайт по адресу https://www.shiftleft.io/.

использованная литература

[Cantrill et al. 2004] Динамическое контрольно-измерительное оборудование производственных систем, Труды ежегодной конференции USENIX Annual Technical Conference (ATEC ’04), 2004 г.

[Roundy et al. 2010] Гибридный анализ и контроль вредоносного ПО, Труды 13-й международной конференции о последних достижениях в обнаружении вторжений (RAID ‘10), 2010 г.

[Hao et al. 2013] Об эффективности управления доступом на уровне API с помощью перезаписи байт-кода в Android, Материалы 8-го симпозиума ACM SIGSAC по информационной, компьютерной и коммуникационной безопасности, 2013 г.

[Newsome et al. 2005] Динамический анализ заражения для автоматического обнаружения, анализа и генерации сигнатур эксплойтов в товарном программном обеспечении

[Enck et al. 2014] TaintDroid: система отслеживания потока информации для мониторинга конфиденциальности в реальном времени на смартфонах, транзакции ACM в компьютерных системах

[Bell et al. 2014] Phosphor: освещение динамического потока данных в товарных JVM, 29-я ежегодная конференция ACM по объектно-ориентированному программированию, системам, языкам и приложениям (OOPSLA ’14)