Баландин Алексей, Security Vision
В предыдущих статьях (1, 2, 3
цикла, посвященному сбору событий в ОС Windows и Linux) мы рассмотрели, какие типы источников событий важны для мониторинга с точки зрения обеспечения информационной безопасности, а также каким образом осуществляется сбор и отправка соответствующих событий в системы мониторинга, в т.ч. был рассмотрен сбор событий с помощью агентов.
Мы планируем расширять функционал наших агентов сбора событий и внедрять подходы, используемые для реализации углубленного мониторинга событий ОС Windows, обнаружения сложных нетиповых атак, а также реагирования на них. Упомянутые подходы лежат в основе функционирования такого класса продукта, как EDR для Windows. Их описанию будет посвящена данная статья. Обзор класса продукта EDR для Linux рассмотрен не будет, т.к. заслуживает отдельной статьи ввиду своей объемности.
Мы рассмотрим существующие проблемы обнаружения атак, предоставим теоретический концепт и подходы к разработке собственной системы EDR для Windows.
Ни для кого не секрет, что классический антивирус сам по себе уже давно не является надежным средством противодействия компьютерным атакам. Тут достаточно вспомнить про бесфайловые вирусы, которые активны последние 10 лет и против которых классический антивирус бессилен. Другая очень распространенная разновидность атак — living off the land, от которой также не может защитить классический антивирус. “Antivirus is dead” — фраза, которую произнес Brian Dye, вице-президент Symantec еще в далеком 2017 году. Это означает, что мы ни в коем случае больше не можем полагаться на один лишь антивирус при построении системы информационной безопасности и теперь мы вынуждены исходить из гипотезы, что наша инфраструктура потенциально скомпрометирована и нам необходимо в непрерывном режиме проактивно искать угрозы. Если речь идет о Windows системах, то здесь мы можем полагаться на подсистему аудита и журнал Security, в который Windows записывает важнейшие события информационной безопасности.
К типовым проблемам подсистемы аудита Windows можно отнести следующие:
1. Логирование только базовых событий информационной безопасности (аутентификация/авторизация учетных записей, запуск процессов, запись в реестр, файловая активность, сетевая активность, создание/удаление учетных записей).
2. Многие важные события (DNS, RPC, LDAP, WMI активность и т.д.) логируются только в режиме углубленного анализа (например, посредством настройки ETW либо средствами собственного драйвера-минифильтра), что позволяет многим атакам оставаться ниже радара средств мониторинга.
3. Отсутствие фильтрации потока событий, что приводит их к лавинообразному росту и большому количеству ложных срабатываний.
4. Отсутствие возможностей мониторинга низкоуровневых системных вызовов (манипуляции с памятью процессов, потоков, структурами файловой системы и т.д.), что создает риски проведения атак класса code injection, process tampering и т.д.
5. Отсутствие средств самозащиты и контроля целостности и работоспособности компонентов системы аудита ОС.
6. Отсутствие возможностей превентивных блокировок событий ИБ, а также проактивного обнаружения атак.
Частично данных недостатков лишен Sysmon, но он не обнаруживает большую часть атак класса code injection, process tampering, полностью лишен функционала самозащиты, противодействия техникам обхода и не поддерживает каких-либо превентивных блокировок атак, поэтому его ни в коем случае нельзя воспринимать как полноценный EDR, скорее, как сборщик расширенной телеметрии ОС. Несмотря на это, Sysmon давно стал стандартом де-факто в области аудита событий ИБ Windows. И не будет преувеличением сказать, что ни один SOC не обходится без Sysmon.
Перечисленных выше недостатков лишено решение класса EDR, которое, помимо выполнения роли агента, осуществляющего функции сбора и отправки событий ИБ на централизованный сервер, проактивно обнаруживает, блокирует атаки и прочую нежелательную активность.
Все современные EDR для защиты конечных точек устанавливают в системе т.н. хуки посредством драйвера ядра, осуществляющие перехваты и фильтрацию системных вызовов, которые могут быть задействованы в процессе проведения атаки. Задачей хука, установленного на системный вызов, является убедиться в его легитимности и заблокировать в случае обнаружения признаков проведения атаки.
Схематично работа хука показана далее на рисунке. Смысл его работы заключается в перезаписи первых нескольких байт в начале перехватываемой функции с установкой инструкций перехода на функцию-перехватчик, которая выполняет заложенные в нее действия и в зависимости от текущего окружения либо блокирует выполнение исходной функции, либо передает выполнение исходной функции без изменения, либо меняет что-либо в переданных параметрах. Таким образом, установка хука позволяет держать выполнение исходной функции под полным контролем и в т.ч. не допустить НСД либо прочие злонамеренные действия. Например, попытки изменения системных настроек (адрес DNS-сервера, прокси-сервера, шлюза) через правку соответствующих ключей реестра, либо попытка выполнения зловредной powershell команды, либо попытка снятия дампа памяти системного процесса lsass с последующей копрометацией учетных данных и т.д.
Здесь стоит упомянуть, что пространство системных вызовов Windows включает в себя верхнеуровневую часть (usermode) функции Win32 API (реализованы в системных библиотеках kenel32.dll, user32.dll, advapi32.dll), Native API (ntdll.dll), которая представляет из себя прослойку между usermode и kernelmode и ядро, которое непосредственно отвечает за выполнение системного вызова.
Функции ядра (NTOSKRNL.DLL) выглядят наиболее привлекательными с точки зрения установки хука, так как такие перехватчики будут наиболее низкоуровневыми и их будет сложнее всего обнаружить и деактивировать. И, действительно, до появления технологии Patch Guard, которая защищает ядро от перезаписи, вмешиваться в работу ядра было стандартной практикой как среди СЗИ, так и среди вирусописателей. Последние годы хуки ставятся в Win32 пространстве и внутри библиотеки ntdll.dll. Другими словами, если нам необходимо перехватить событие записи в память процесса, мы будем делать это посредством установки хука на системный вызов writeprocessmemory (из kernel32.dll) либо, что предпочтительнее, на ntwritewirtualmemory (из ntdll.dll). Таким образом, установка хуков — это мощнейший механизм перехвата и анализа событий ОС, которым активно пользуются все EDR-системы. В тоже же время не стоит забывать, что этим механизмом злоупотребляет и malware, например, кейлогеры для перехвата введенных пользователем учетных данных и переписки, а также руткиты для сокрытия своего присутствия в системе.
Механизм установки хуков в системе происходит по следующей схеме:
1. Посредством вызова функции PsSetCreateProcessNotifyRoutineEx происходит регистрация т.н. callback функции драйвера, которая получает доступ к контексту создаваемого процесса: имя, путь, pid, командная строка, имя родителя.
2. Драйвер передает pid запущенного процесса пользовательскому приложению, например, через именованный пайп либо каким-либо другим способом.
3. Пользовательское приложение (инжектор) методом классического DLL Inject (либо каким-либо другим способом) внедряет библиотеку в адресное пространство создаваемого процесса.
4. Внедренная библиотека получает управление, в большинстве случаев происходит вызов функции DLLMain, после чего происходит установка хуков на интересуемые функции. Как уже было сказано выше, достигается это посредством перезаписи первых нескольких байт функции инструкциями перехода на функцию-перехватчик.
5. Теперь вызовы всех интересуемых функций внутри процесса будут замыкаться на функции-перехватчики, осуществляющие контроль исходных функций.
6. Пункты 1-5 повторяются для каждого нового создаваемого в системе процесса, что дает возможность EDR выявлять вызовы потенциально опасных функций и разграничивать доступ ко всем ресурсам системы (файловая система, реестр, память, сеть и т.д.)
EDR также может быть оснащен компонентом контроля запуска приложений, который на основе ряда критериев принимает решение о разрешении/запрете запуска приложений. К таким критериям для запускаемого приложения можно отнести следующие: наличие ЭЦП, издатель, имя файла, версия файла, путь файла, md5/sha256 хэши. На основании связки данных критериев могут быть сформированы следующие уровни доверия приложения:
-
высокодовереннный,
-
среденедоверенный,
-
низкодоверенный,
-
недоверенный,
-
запрещенный.
Можно привести следующие примеры для определения уровня доверия процессов:
-
Высокодоверенный процесс: файл подписан известным издателем и лежит в одном из каталогов C:\\Windows\\*', 'C:\\Program Files(x86)\\*', 'C:\\Program Files;
-
Среднедоверенный процесс: файл подписан неизвестным издателем и лежит в одном из каталогов C:\\Windows\\*', 'C:\\Program Files(x86)\\*', 'C:\\Program Files;
-
Низкодоверенный процесс: файл подписан неизвестным издателем и не лежит в одном из известных каталогах или не подписан и лежит в одном из каталогах C:\\Windows\\*', Program Files(x86)\\*', 'C:\\Program Files;
-
Недоверенный процесс: файл не подписан и не лежит ни в одном из каталогах C:\\Windows\\*', 'C:\\Program Files(x86)\\*', 'C:\\Program Files;
-
Запрещенный процесс: 84858CA42DC54947EEA910E8FAB5F668 md5 файла PsExec64.exe.
На основании уровня доверия процесса формируется матрица доступа к защищаемым ресурсам, которая анализируется по факту сработки хука на системный вызов при попытке обращения к защищаемому ресурсу.
Пример матрицы доступа к Run ключам реестра для процессов разного уровня доверия:
"registry": {
"autostart_run": [
{
"type": "highly_trusted",
"crud_rights": "++++"
},
{
"type": "medium_trusted",
"crud_rights": "++++"
},
{
"type": "low_trusted",
"crud_rights": "?+?-"
},
{
"type": "untrusted",
"crud_rights": "----"
}
]
}, где
"+" - разрешение доступа
"-" - запрет доступа
"?" - спросить у пользователя и запомнить выбор
Если просуммировать всю телеметрию, которую целесообразно собирать EDR, получим следующую таблицу:
Как видно, много позиций, которые покрываются Sysmon, но не покрываются стандартным аудитом Windows, что является аргументов в пользу использования Sysmon как один из источников аудита в проектируемой EDR системе (в случае, если нет возможности для разработки собственных драйверов мини-фильтров).
Одной из особенностью EDR является проактивное обнаружение и реагирование на атаки, о чем говорилось выше и чего не в состоянии выполнить классические СЗИ: антивирус, межсетевой экран, прокси-сервер и т.д.
Среди классических действий по реагированию EDR должна уметь выполнять (как в ручном, так и в автоматическом режимах):
-
завершение процесса/цепочки процессов,
-
удаление файла/ключа реестра, блокировка УЗ,
-
отмена изменения ключа реестра,
-
завершение сессии пользователя,
-
изоляция узла,
-
блокировка IP.
Хорошей практикой является построение моделей эталонного поведения хоста (baseline) как на локальном, так и сетевом уровнях, что позволит обнаруживать ранее неизвестные атаки и аномалии, например, запуск редкого процесса или обращение к редкому сетевому ресурсу, либо, наоборот, сетевой всплеск, свидетельствующий об утечке данных.
Практически все современные EDR оснащены сканерами памяти (в т.ч. основанными на YARA), способные обнаруживать бесфайловое ВПО. Взять за основу собственного сканера памяти можно уже имеющиеся бесплатные тулзы (Moneta, pe-sieve, Loki, hollows_hunter и т.д)
EDR также может обнаруживать сетевые атаки, как сигантурным, так и эвристическим способом, в т.ч. на основе сетевых моделей машинного обучения. Отличным кейсом для EDR является обнаружение C&C активности на основе алгоритмов JA3/JA4 либо собственных реализаций особенно для известных C&C фреймворков (Cobalt Strike, Sliver, Brute Ratel, Havoc и т.д.).
Многие EDR оснащены собственными корреляционными движками. В то же время корреляция —это все же прерогатива SIEM, и здесь в какой-то степени мы сталкиваемся с дублированием функционала, что приводит к избыточности. На наш взгляд, грамотно настроенные компоненты контроля запуска и активности (выставленные хуки) приложений (HIPS) вкупе с обученными моделями машинного обучения вполне способны нивелировать отсутствие корреляционного движка в EDR. С другой стороны, если в линейке продуктов компании отсутствует SIEM, наличие корреляционного движка в EDR вполне оправдано.
В результате всего сказанного получаем концептуальную схему EDR, которая покрывает основные требования, предъявляемые к EDR. Разными цветами выделены компоненты EDR в порядке их значимости:
Белый — базовые компоненты, обязательны для реализации EDR.
Желтый — крайне желательные компоненты EDR.
Фиолетовый — компоненты, который существенно расширил бы функционал EDR.
Вывод
В данной статье описаны проблематика и подходы, на основе которых предложен концептуальный прототип EDR, удовлетворяющий требованиям, предъявляемым к данному классу решений.