Привет, Хабр! В прошлой статье мы делали обзор на opensource NTA – Arkime, здесь мы продолжим развивать NTA для безопасника и поговорим об анализе файлов в сетевом трафике.  Текущая статья будет своего рода обзором - инструкцией по развитию системы. “Из коробки” Arkime может в YARA, но в таком случае анализ файлов будет на мощностях нод захвата со всеми вытекающими последствиями (увеличение потока трафика потребует СУЩЕСТВЕННОГО увеличения мощности ноды). Чтобы переложить нагрузку с “больной головы” на “здоровую” мы решили прикрутить Strelka. Итак, что же такое Strelka? Как заявляет комьюнити - это энтерпрайз решение для статического анализа и поиска файлов по YARA правилами (и не только) в режиме реального времени. Архитектурно представляет клиент-серверное приложение (понятное дело, требует установки агентов). Агенты написаны на Go Lang, что предоставляет возможность кроссплатформенной установки. Наглядный usecase - поиск вредоносного файла, который обошел антивирусы, но при этом был обнаружен командой кибербеза. На файл написали YARA сигнатуру и запустили поиск по всем агентам в инфраструктуре. Подобный кейс рассмотрим чуть дальше в статье.  К сожалению, о Strelka мало кто знает и использует в СНГ. Разумеется, в этом нет ничего удивительного - как правило, такие функции возлагают на вышеупомянутые коммерческие решения (антивирусы, EDR и пр.), используют самописное, либо вовсе не задумываются о таких задачах. Изначально Strelka задумывалась как решение для поиска и анализа файлов по запросу, в том числе и анализ файлов на сетевом потоке IDS/IPS сенсорах, полученных из трафика. Именно такой функционал нам и нужен в рамках развития нашего NTA – Arkime. Из однозначно приятных дополнительных возможностей - отправка файлов в песок для  динамического анализа (из коробки реализована только интеграция с Cuckoo sandbox, но есть возможность прикрутить любой другой, если вы умеете в Python). Используя такую интеграцию можно получить песок для всех передаваемых по сети файлов. Архитектура Strelka достаточно гибкая и позволяет развернуть как маленькую инсталяцию для тестов, так и распределенную инсталяцию для кровавого энтерпрайза (реализация любого взаимодействия серверов и агентов). Возникает вполне логичный вопрос - зачем вовсе анализировать файлы на сетевом потоке, когда есть EDR/антивирус и прочие СЗИ с аналогичным функционалом (даже если 146% покрытие инфраструктуры указанными тулами)? Отвечу списком, который раскрою подробнее: Любой вредонос может бесследно исчезнуть на эндпоинтах до его обнаружения, но не из трафика, который захвачен NTA; Точное понимание откуда, куда и когда передавался файл; Модифицировался ли файл при передаче от одного узла к другому; Обнаружение Lateral Movement (в дальнейшем просто latmov); Передача файла с машины, которая вошла в 0,00001% без покрытия СЗИ (или вовсе не доменной); Автоматизация и упрощение рутинных задач Detection Engineering’а (удобно скармливать файл стрелке и большинство полезной информации удобно (почти) раскладывается в JSON’e, отправляется в песочницы и куда только захотите). Как известно, антивирусы не являются серебряной пулей от всех болезней, да и способов обхода их обнаружения известно не мало. Хороший специалист красной команды (этичный хакер) сможет легко обойти антивирус даже для избитого и отлично известного mimikatz’a. А серьезные ребята из АРТ группировок вовсе стараются не оставлять своих следов. При передаче нешифрованным каналом своего инструментария (например smb или любимым psexec’ом) и последующим его запуском с моментальным удалением, вряд ли удастся получить образец файла на целевой системе, однако он осядет на NTA и будет проанализирован strelka. Из этого можно будет написать детект и отслеживать дальнейшее перемещение файла по сети не только с помощью агентов/антивируса и пр, но и на сети. Хочу отметить, что речь идет не о первичном обнаружении, а именно о насыщении инцидента важными подробностями, о последующем респонзе и анализе, что в будущем приведет к своевременному первичному обнаружению. Агенты на устройствах наверняка расскажут о наличии того или иного файла, максимум - подсветят происхождение файла (вспоминаем о Transfer Zone), но едва ли расскажут, откуда появился файл (если только косвенными признаками при анализе логов с хоста, что требует самого ценного ресурса - времени). В случае же анализа Strelk’ой - у вас будет неоспоримое доказательство о дате, источнике передачи точного файла (ведь Strelka считает хэши). Такой подход существенно сокращает время разбора инцидента, а как мы знаем,  при активном реагировании, скорость анализа является очень критичным показателем - иногда секунды определят, появится ли новый доменный админ или нет.  Некоторые вирусы могут изменять свою структуру с течением времени или иными факторами (разумеется, для избежания обнаружения), но Strelka анализирует все возможные заголовки файлов, в том числе вычисляет imphash и пишет его в лог (imphash - это хэш подключаемых библиотек для исполняемого файла). Кроме imphash для исполняемых файлов записываются: архитектура, для который был написан бинарь, все метаданные исполняемого файла (например версия, цифровая подпись и пр.), ОС, характеристики подключаемых библиотек (их функции) и многие другие заголовки. По таким признакам возможно написать YARA правило (или правило корреляции - ведь логи Strelka отправляются в SIEM), которое будет отслеживать файл, даже если он постоянно изменяется (вы можете справедливо заметить, что в случае продвинутой малвари для избежания обнаружения могут подключаться дополнительные библиотеки для изменения imphash, однако не всегда будут использоваться дополнительные функции новых библиотек).  Вполне вероятно, что latmov может отслеживаться на логах и самой сети, однако как быть, когда злоумышленники используют легитимные для инфраструктуры инструменты (конечно же, что бы усложнить свое обнаружение защитниками)? Профилирование активности админов может не спасти - ведь с точки зрения логов и сети, активность ничем не отличается от действий администратора. Однако именно тут на помощь приходит Strelka - в случае передачи своих инструментов по сети (а как иначе?), они будут проанализированы. Согласитесь, что администраторы не используют хактулы и малварь при осуществлении ежедневных обязанностей? Идеальных инфраструктур не существует. Наверняка даже в крупнейших банках мира найдется 1 машина, на которой нет СЗИ или вне домена, или вовсе является нелегитимно подключенным устройством в сеть (например raspberry pi, включенная в RJ-45 розетку сети ip-телефонии).  В таком случае СЗИ смогут обнаружить (ЕСЛИ смогут) только факт появления вредоноса на атакуемой машине, но Strelka точно расскажет, откуда прилетел такой файл. В более зрелых, с точки зрения ИБ, инфраструктурах может быть обнаружен факт подключения в сеть неизвестного устройства, что послужит хорошим поводом для начала расследования - при таком раскладе развития событий, Strelka упростит анализ активности нелегитимного устройства.  Резюмируя, все эти пункты можно свести к следующему профиту: Сокращение времени расследования инцидентов; Увеличение видимости инфраструктуры для безопасника; Насыщение контекста инцидентов; Дополнительные возможности детекта вредоносной активности в сети. Плюсов не мало, однако есть очень важный нюанс, в случае анализа файлов на трафике, они должны быть переданы НЕшифрованным каналом (например, если файл передавался по RDP или по кастомному шифрованному протоколу - разумеется, он не будет проанализирован). В копилку минусов можно так же отнести отсутствие в логах Strelka айпишников, откуда файл был выдернут, НО! с помощью logstash обогатить такие данные. Мы не претендуем (хотя стремимся к ней) на идеальную конфигурацию Suricata, Zeek, Strelka и тд, а так же на полноту покрытия всех потребностей безопасника. Мы точно знаем, что у нас есть недостатки в конфигах, но мы только начали свой путь и, со временем, мы станем лучше, в том числе, благодаря вашим советам и рекомендациям. “Совет начинающим: начните” (с) Великие цитаты Великих людей =) Для того, чтобы анализировать файлы, их сначала надо откуда-то получить. В прошлой статье мы упоминали, что Arkime сам по себе не выдергивает файлы из трафика (но индексирует их имена).  Кроме самого Arkime, на ноде захвата установлена Suricata. Именно с ее помощью мы хотели получать файлы. Однако, столкнулись с тем, что Suricata не особо адекватно выдирает файлы из трафика из-за особенностей пересбора сессии. Более эффективным вариантом будет Zeek (ранее Bro) с настройки на экстракт файлов.  Для этого стоит начать с установки самого Zeek, но мы надеемся, что с эти проблем у вас не будет =). После стандартной настройки (выбор портов для прослушки и т.д.), необходимо написать скрипт на языке самого Zeek (смесь Lua). Такой скрипт есть "из коробки", но он будет собирать все файлы подряд и изначально выключен. Сам Zeek устроен достаточно хитро и подразумевает внутри себя целую программируемую  платформу, которая может делать все что вы захотите, при наличии прямых рук. Для включения скрипта нам нужно “загрузить” его в основной скрипт запуска Zeek. В случае использования standalone инсталяции, достаточно внести директиву “@load <имя модуля>”  в файл “префикс_корня_zeek/share/zeek/site/local.zeek”. С точки зрения загрузчика - пути к модулями начинаются из папки share и share/policy, и идеологически - каждый модуль находится в своей папке. Дефолтный крипт выгрузки всех файлов является частью стандартного модуля FileAnalysis,  и находится по пути “frameworks/files/extract-all-files”. Как уже было сказано выше, скрипт будет выдирать все подряд, чего мы хотим избежать. Для этого мы своровали вдохновились более точечной вариацией от Security Onion Solutions, где предварительно создан словарь с mime типами файлов и их расширениями. Так как данный скрипт генерируется при установке самого SOS, мы переопределим свои типы и используем их. Для того чтобы скрипт стал “модулем”, который мы будем использовать, переместим его в папку (для сохранения истоков - share/policy/securityonion/file-extract/) и создадим файл “__load__.zeek” (по аналогии __init__.py в Python модулях), в которой добавим директиву  “@load ./extract”. Соответственно, сам скрипт будет называть extract.zeek и в него мы добавим следующее:   Статья не про Zeek, но в вариации SOS также есть проверка на корректность выгрузки в обработке file_state_remove, где файл будет удален, если во время сбора не были выполнены некоторые требования. Настройка suricata.yaml:  Чтобы научить сурка сохранять файлы, необходимо добавить следующие строки (из документации самого сурка 1 и 2)  в suricata.yaml (оформить код-блоком) : - eve-log:       enabled: yes       filetype: regular        filename: eve.json …      types: … - files:             force-magic: yes … - file-store:       version: 2       enabled: yes        dir: /ваша/директория/       stream-depth: 0 … Правила захвата файлов мы честно решили взять с проекта Security Onion Solutions,  вот ссылка на сами правила После изменения конфигов, рестартуем сурикату и проверяем запись файлов по указанной директории в конфиге выше. Должно получиться что-то подобное: Все эти директории - первые 2 символа в sha-256 хэше, того файла, который был сохранен. (например, если SHA-256 хэш файла начинается с ”00”, то он будет сохранен в директории 00) Готово, теперь файлы будут выдергиваться в эту директорию.  Перейдем к деплою и настройке Strelka. В рамках этой статьи мы выбрали самый простой варинат деплоя - инсталяция всех компонентов в одном экземпляре с помощью docker compose (1 сервер - 1 агент). В большой инсталяции количество сервисов увеличивается по необходимости, а для роутинга и балансировки gRPC запросов используется Envoy. Проще говоря - больше нагрузка, больше сервисов. Разберем, что в космической собаке зарыто: Strelka-frontend принимает входящие запросы от клиентов по gRPC. Strelka-backend  обрабатывает входящие файлы. Strelka-manager  смотрит в Redis. Coordinator – Redis сервер, координирующий задачи на анализ и данные между frontend и backend. Gatekeeper – Redis сервер, реализующий временный кэш из событий. Mmrpc - опциональный сервис на базе проекта MaliciousMacroBot, и включающий сканер ScanMmbot Перейдем к самой установке (далее мы просто копируем из официального гита Strelka):  Копируем репозиторий и заходим в негоgit clone https://github.com/target/strelka.git && \ cd strelka Удаляем тестовый файл с yara правилами и качаем правила из Yara-Rules. Стоит отметить, что в Yara-Rules идет в комплекте файл index.yar, который включает в себя все остальные. Его же мы инклюдим в файл configs/python/backend/yara/rules.yara. Вы можете использовать другие правила или использовать свои собственные rm configs/python/backend/yara/rules.yara && \ git clone https://github.com/Yara-Rules/rules.git configs/python/backend/yara/rules/ && \ echo 'include "./rules/index.yar"' > configs/python/backend/yara/rules.yara  Билдим образа докера и поднимаем их, а также собираем один из клиентов - strelka-oneshot. docker-compose -f build/docker-compose.yaml build && \ docker-compose -f build/docker-compose.yaml up -d && \ go build github.com/target/strelka/src/go/cmd/strelka-oneshot Берем любой пример вредоносного ПО (в примере от самой Strelka решили выбрать Emotet, находящийся в запароленном архиве) и скармливаем его нашей собаке: ./strelka-oneshot -f samples/Win32.Emotet.zip -l - | jq Вывод будет представлять собой 2 JSON документа, которые с помощью jq будут адекватно отображены. Так как мы скармливаем архив, Strelka автоматом обрабатывает и вложенные файлы. Как же именно strelka понимает, что за файл перед ней? С помощью пачки yara правил из файлика taste.yara, а с помощью файла конфигурации backend.yaml, будут выбраны сканеры, которые и проанализируют файлы. Все файлы конфигурации всех сервисов нашей собаки лежат в папке configs/<язык сервиса(go или python)>, как и примеры конфигураций для клиентов. Итак, вернемся к нашему кейсу - обработка файлов на потоке. Нам нужен клиент strelka-filestream, который будет смотреть указанные шаблоны наименований файлов и отправлять их как задачи на анализ.  Давайте также соберем filestream: go build github.com/target/strelka/src/go/cmd/strelka-filestream Обработанные файлы он будет перекладывать в другую папку, чтобы необработанные и обработанные не пересекались: Это настройки, которые мы решили выбрать для себя, но вы всегда можете обратиться к документации, и настроить все под себя. Описание всех конфигураций для всех сервисов - здесь, но документация достаточно скромная (ну, а что мы хотели от opensource). Также напишем простенький systemd юнит для “правильного” (по мнению бОльшего представительства линуксойдов) запуска strelka-filestream: Вы можете более тонко настроить деплой клиента - сделать отдельного пользователя, настроить права на все используемые нами папки, или даже написать SeLinux политику (почему бы и да?). Самое НЕинтересное - доставка логов в ELK, именно на этом этапе мы потратили больше всего времени. Схема JSON документов по результатам анализа файлов нам показалась невероятно монструозной, поэтому выделили самое интересное и основное ниже (документация на схему JSON отсутствует на момент выхода статьи): И выглядит все оно конечно просто и понятно, но как только вы сами закинете тестовый Emotet на анализ, вы увидите “немного” больше, чем показывают в примере. Тут по плану должен был быть пример лога, но в нем более 9к строк, поэтому прикладываем только отрывок под скрытый текст. "pe": { "address_of_entry_point": 1075979, "base_of_code": 4096, "base_of_data": 1671168, "checksum": 8268887, "compile_time": "2023-01-20T18:07:04", "debug": { "age": 1, "guid": "2d00683a-1f90-0e48-8dc7b915b650eec3", "pdb": "D:\a\1\s\exe\Win32\Public_Release\Sysmon.pdb", "type": "rsds" }, "dll_characteristics": [ "DYNAMIC_BASE", "NX_COMPAT", "TERMINAL_SERVER_AWARE" ], "elapsed": 1.431875, "file_alignment": 512, "file_info": { "company_name": "Sysinternals - www.sysinternals.com", "file_description": "System activity monitor", "file_version": "14.14", "fixed": { "operating_systems": [ "WINDOWS32" ], "type": { "primary": "UNKNOWN" } }, "internal_name": "System Monitor", "legal_copyright": "By Mark Russinovich and Thomas Garnier\nCopyright (C) 2014-2023 Microsoft Corporation\nUsing libxml2. libxml2 is Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.", "product_name": "Sysinternals Sysmon", "product_version": "14.14", "var": { "character_set": "Unicode", "language": "U.S. English" } }, "flags": [ "no_certs_found" ], "header": { "machine": { "id": 332, "type": "I386" }, "magic": { "dos": "DOS", "image": "32_BIT" }, "subsystem": "WINDOWS_CUI" }, "image_base": 4194304, "image_characteristics": [ "EXECUTABLE_IMAGE", "32BIT_MACHINE" ], "image_version": 0, "imphash": "22c706ca771a1849826506040b11d50f", "linker_version": 14.34, "major_image_version": 0, "major_linker_version": 14, "major_operating_system_version": 6, "major_subsystem_version": 6, "minor_image_version": 0, "minor_linker_version": 34, "minor_operating_system_version": 0, "minor_subsystem_version": 0, "operating_system_version": 6, "resources": [ { "id": 1001, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "3e725ceddba1b9460f6304986e6248da", "sha1": "8710b02483beac27184dd236209f7d1df864ffe6", "sha256": "d92b848707513894733fe2da0faf7ba7dcfbbb98380d06e07c87521e7fab6bf0" }, { "id": 1002, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "01124a558ec6d65f6471456da07ab4ea", "sha1": "743e1c0d0495d334c77132640352208f806aeb54", "sha256": "9681d860e84375b95b3d59006dae41b007bca3824bfe10e0c313b72f68ac178a" }, { "id": 1, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "12a95179b2738a3f37060eacad6bd6a3", "sha1": "1197df76d0a31be7a369b13499f1e73c6b6791d0", "sha256": "3d63feefaf94dc719aa83afc9b25dc8ca317a686cdb617e39f4c1548b060a8ed" }, { "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "932524ab57ae83176d5596fff967aa52", "name": "SYSMONSCHEMA", "sha1": "691dd0236bc963b1b7528accdba56fee26fce10d", "sha256": "0387426eeb7ea7705c7524e2d6425a7c6fda9923c25650309ae3a6440a0e9971" }, { "id": 1, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "bfc1566bfd06c8135ab5c3a2e321ebe7", "sha1": "66bd09bd18c6953d6fcea960431dfb6ddd7f9416", "sha256": "db58c2c74246fa1e1c6c504373332303a511be9072ee5b31796c2a837a922f17", "type": "MESSAGETABLE" }, { "id": 1, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "d901d37a441a56585e2878f8f31fd958", "sha1": "0c60e3a7cc4a9c5726767611fd774c5826690438", "sha256": "695d4d08304fd3377908fb02cb58063052223e391b9ed70da067a9bb3725c53e", "type": "VERSION" }, { "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "97563aa40292469b3e117adfc66dfcbe", "name": "SYSMONMAN", "sha1": "8c4b4d8d95edc34e21b1723f3badcfaf51ea6dd5", "sha256": "71318e89313c58d15da819be6f89fdc975228cbf82626bfa2c78aa2f28d04ad8", "type": "HTML" }, { "id": 1, "language": { "primary": "ENGLISH", "sub": "ENGLISH_US" }, "md5": "d41d8cd98f00b204e9800998ecf8427e", "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "type": "MANIFEST" } ], "rich": { "clear_data": { "data": "RGFuUwAAAAAAAAAAAAAAAEt4AwETAAAAS3gFAcUAAABPfP0ABAAAAE98BQFWAAAAT3wEARMAAABPfAMBGQAAAEt4BAEZAAAAuHUDAQEAAAC7dQQBCgAAAEt4AQEjAAAAAAABAFIBAADBfAkBPQAAAMF8/wABAAAAAACXAAIAAADBfAIBAQAAAA==", "md5": "fa160a389ccba4f1f5e7ea61c15d319a" }, "info": [ { "count": 19, "toolid": 259, "version": 30795 }, { "count": 197, "toolid": 261, "version": 30795 }, { "count": 4, "toolid": 253, "version": 31823 }, { "count": 86, "toolid": 261, "version": 31823 }, { "count": 19, "toolid": 260, "version": 31823 }, { "count": 25, "toolid": 259, "version": 31823 }, { "count": 25, "toolid": 260, "version": 30795 }, { "count": 1, "toolid": 259, "version": 30136 }, { "count": 10, "toolid": 260, "version": 30139 }, { "count": 35, "toolid": 257, "version": 30795 }, { "count": 338, "toolid": 1, "version": 0 }, { "count": 61, "toolid": 265, "version": 31937 }, { "count": 1, "toolid": 255, "version": 31937 }, { "count": 2, "toolid": 151, "version": 0 }, { "count": 1, "toolid": 258, "version": 31937 } ], "key": "6220d5e7", "raw_data": { "data": "JkG7tGIg1ediINXnYiDV5ylY1uZxINXnKVjQ5qcg1ectXCjnZiDV5y1c0OY0INXnLVzR5nEg1ectXNbmeyDV5ylY0eZ7INXn2lXW5mMg1efZVdHmaCDV5ylY1OZBINXnYiDU5zAh1eejXNzmXyDV56NcKudjINXnYiBC52Ag1eejXNfmYyDV5w==", "md5": "99df8167e636a4e5d03f3a305f56b445" } }, "section_alignment": 4096, "sections": [ { "address": { "physical": 1666038, "virtual": 4096 }, "characteristics": [ "CNT_CODE", "MEM_EXECUTE", "MEM_READ" ], "entropy": 6.636632502553922, "md5": "55eac3bed86e853dd7b97ecae392a49c", "name": ".text", "sha1": "d86802270020bf19260c1a0f4c4e46551a9f01d6", "sha256": "7b80a0764abba960a81e444dcc6f5cb3ec8c38c0c4aeb89e518ef40ee0d129d1", "size": 1666048 }, { "address": { "physical": 786576, "virtual": 1671168 }, "characteristics": [ "CNT_INITIALIZED_DATA", "MEM_READ" ], "entropy": 4.3805809880051365, "md5": "ba57f1bdd64e68192ac99511c004430d", "name": ".rdata", "sha1": "ae67fd775a29fe2e812c04d7fae00fed6cd3f10f", "sha256": "95d49c9c84ddb5bd3fb746000e2be173d51af0a4971d0d2f82a728d769a74778", "size": 786944 }, { "address": { "physical": 29224, "virtual": 2461696 }, "characteristics": [ "CNT_INITIALIZED_DATA", "MEM_READ", "MEM_WRITE" ], "entropy": 4.474025218651877, "md5": "31a647892600452887f8681d5007a2e4", "name": ".data", "sha1": "7b84cf7ccb58aca03a780b60ee731ef458f311d7", "sha256": "6331c1d1e5d08db286a879035ffa9f08f999bf87358938ef184ccaf25fe0b626", "size": 14848 }, { "address": { "physical": 5686360, "virtual": 2494464 }, "characteristics": [ "CNT_INITIALIZED_DATA", "MEM_READ" ], "entropy": 1.699918955277781, "md5": "bf1b231fd7cebcaf9ce86b18fdcba822", "name": ".rsrc", "sha1": "1e941fdd57610dd433314447b1076f84bad98594", "sha256": "fe21359b2a4ce3fde264344efee4f475b752d192ea1039aad72edf19e764f073", "size": 5686784 }, { "address": { "physical": 60920, "virtual": 8183808 }, "characteristics": [ "CNT_INITIALIZED_DATA", "MEM_DISCARDABLE", "MEM_READ" ], "entropy": 0, "md5": "d41d8cd98f00b204e9800998ecf8427e", "name": ".reloc", "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "size": 60928 } ], "size_of_code": 1666048, "size_of_headers": 1024, "size_of_heap_commit": 4096, "size_of_heap_reserve": 1048576, "size_of_image": 8245248, "size_of_initialized_data": 6564352, "size_of_stack_commit": 4096, "size_of_stack_reserve": 1048576, "size_of_uninitialized_data": 0, "subsystem_version": 6, "summary": { "resource_md5": [ "01124a558ec6d65f6471456da07ab4ea", "97563aa40292469b3e117adfc66dfcbe", "12a95179b2738a3f37060eacad6bd6a3", "3e725ceddba1b9460f6304986e6248da", "d41d8cd98f00b204e9800998ecf8427e", "932524ab57ae83176d5596fff967aa52", "d901d37a441a56585e2878f8f31fd958", "bfc1566bfd06c8135ab5c3a2e321ebe7" ], "resource_sha1": [ "1197df76d0a31be7a369b13499f1e73c6b6791d0", "0c60e3a7cc4a9c5726767611fd774c5826690438", "691dd0236bc963b1b7528accdba56fee26fce10d", "8c4b4d8d95edc34e21b1723f3badcfaf51ea6dd5", "743e1c0d0495d334c77132640352208f806aeb54", "66bd09bd18c6953d6fcea960431dfb6ddd7f9416", "da39a3ee5e6b4b0d3255bfef95601890afd80709", "8710b02483beac27184dd236209f7d1df864ffe6" ], "resource_sha256": [ "71318e89313c58d15da819be6f89fdc975228cbf82626bfa2c78aa2f28d04ad8", "d92b848707513894733fe2da0faf7ba7dcfbbb98380d06e07c87521e7fab6bf0", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "3d63feefaf94dc719aa83afc9b25dc8ca317a686cdb617e39f4c1548b060a8ed", "db58c2c74246fa1e1c6c504373332303a511be9072ee5b31796c2a837a922f17", "0387426eeb7ea7705c7524e2d6425a7c6fda9923c25650309ae3a6440a0e9971", "695d4d08304fd3377908fb02cb58063052223e391b9ed70da067a9bb3725c53e", "9681d860e84375b95b3d59006dae41b007bca3824bfe10e0c313b72f68ac178a" ], "section_md5": [ "55eac3bed86e853dd7b97ecae392a49c", "d41d8cd98f00b204e9800998ecf8427e", "31a647892600452887f8681d5007a2e4", "bf1b231fd7cebcaf9ce86b18fdcba822", "ba57f1bdd64e68192ac99511c004430d" ], "section_sha1": [ "d86802270020bf19260c1a0f4c4e46551a9f01d6", "da39a3ee5e6b4b0d3255bfef95601890afd80709", "1e941fdd57610dd433314447b1076f84bad98594", "ae67fd775a29fe2e812c04d7fae00fed6cd3f10f", "7b84cf7ccb58aca03a780b60ee731ef458f311d7" ], "section_sha256": [ "6331c1d1e5d08db286a879035ffa9f08f999bf87358938ef184ccaf25fe0b626", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "fe21359b2a4ce3fde264344efee4f475b752d192ea1039aad72edf19e764f073", "95d49c9c84ddb5bd3fb746000e2be173d51af0a4971d0d2f82a728d769a74778", "7b80a0764abba960a81e444dcc6f5cb3ec8c38c0c4aeb89e518ef40ee0d129d1" ] } Самое страшное здесь - секции с импортируемыми функциями из PE заголовков, полная meta информация по yara правилам и массив из информации об энтропии каждой секции исполняемого файла (не пугайтесь, если вы ничего не поняли - мы тоже ничего не поняли). Нам очень хотелось слать всю информацию о сработках yara правил в Elasticsearch и в дальнейшем использовать в визуализациях, или даже написать правила в Elastic Security. Но к нашему сожалению - meta данные по yara правилам - массив из несвязанных объектов, поэтому пришлось воспользоваться Vector и написать парсер на VRL, так как писать все это на Painless Script - полное безумие (попробуйте сами). Результатом обработки файлов является лог-файл на ноде захвата и для его последующего анализа требуется его куда-то забирать и визуализировать. Для этого мы решили использовать filebeat + ELK stack (теоретически, можно складывать в ELK Arkime, к которому прикручена Kibana/opensearch, но мы складываем в отдельную инсталяцию). Пример лога в ELK для тестового EICAR файла (мы используем yara правила от Elastic - можно глянуть тут):  Как можно заметить, самые интересные, с точки зрения безопасности, поля - это сработка YARA, хэши, название файла. Внутри тестового файла отсутствуют какие-либо еще интересные данные. Пару скринов ниже покажут пример анализа internal monologue: Однако Strelka вытаскивает еще полезную информацию: Тип файла (из заголовка) URL’ы в файлах Импортируемые функции из библиотек  Strelka не единственная в своем роде - коллеги по цеху из Канады разрабатывают AssemblyLine - концептуально похожий проект со Strelka. Авторы текста:Тыщенко Иван, tg:@nerebros Дьячков Иван, tg: @Roosevelt_Rus