Перейти к основному содержимому
Версия: 1.0

MISP

Данное руководство описывает быструю настройку интеграции (автоматическую загрузку индикаторов компрометации (IoC)) Solar TI Feeds Agent с MISP.

Предварительные требования

  • Установленный и настроенный Solar TI Feeds Agent;
  • Учетные данные для доступа к MISP;
  • Доступ к серверу TI Feeds с действительным JWT-токеном.

Конфигурация интеграции

Данная интеграция автоматизирует выгрузку индикаторов компрометации из Solar TI Feeds в MISP. Для каждого потока данных (фида) угроз создается отдельный пайплайн обработки, обеспечивающий получение, преобразование и загрузку данных с возможностью добавления кастомных тегов.
Для подключения к СЗИ используется аутентификация при помощи токена.

Переменные окружения

Для работы интеграции необходимо определить следующие переменные окружения:

Переменные для интеграции с MISP

  • TIC_AGENT_SERVICE_HOST - Хост или IP-адрес сервера MISP
  • TIC_AGENT_SERVICE_PORT - Порт для подключения к API MISP
  • TIC_AGENT_SERVICE_TOKEN - Токен для аутентификации к API MISP

Структура пайплайнов для MISP

Каждый пайплайн состоит из следующих компонентов:

  1. FeedStreamGenerator — получает индикаторы из Solar TI Feeds.
  2. IndicatorsFilter - фильтрует поток индикаторов выбирая индикаторы с контекстом.
  3. IndicatorsTextMap — преобразует данные в текстовый формат, пригодный для загрузки.
  4. IndicatorsTextSink — сохраняет данные в CSV-файл и загружает их в MISP.

Конфигурация автоматически создает отдельный пайплайн для каждого фида из списка allFeedsList. При необходимости вы можете изменить этот список, указав только нужные фиды.
Пример настройки списка фидов:

local feedsWithCustomTags = List(
new FeedTags{
feedName = "APT"
customTags = List()
},
new FeedTags{
feedName = "C2"
customTags = List()
}
)

Справочник параметров для MISP

Ключевые параметры конфигурации для MISP приведены в таблице:

ПараметрТип данныхЗначение по умолчаниюОбязательностьОписаниеПример
credentialsCredentialsДаДанные для аутентификацииcredentials = new agent.Basic {username = misp_User password = misp_Password}
addressAddressДаДанные подключенияaddress {host = misp_Host port = misp_Port insecureSkipVerify = true scheme = "https"}
timeoutDuration30.sНетТаймаут запросов60.s
listNameStringДаИмя списка для загрузки данных“4rays_feeds”

Дополнительные параметры конфигурации для расширения ServiceConfig – MispCfg:

ПараметрТип данныхОбязательностьОписание
threatActorsTagPrefixStringДаПрефикс, с которым добаляеются теги Threat Actors к Event
malwareTagPrefixStringДаПрефикс, с которым добаляеются теги Malware к Event
feedTagPrefixStringДаПрефикс, с которым добаляеются теги фидов к Event

Полный пример конфигурационного файла для интеграции с MISP

amends "package://pkg.pkl-lang.org/github.com/pipelane/pipelaner/pipelaner@1.3.1#/Pipelaner.pkl"
import "package://pkg.pkl-lang.org/github.com/pipelane/pipelaner/pipelaner@1.3.1#/source/Components.pkl"
import "../agent.pkl"
import "../templates.pkl"

local threatActorsTagPrefixParam = "threat_classification:threat-actors"
local malwareTagPrefixParam = "malware_classification:malware-category"
local feedTagPrefixParam = "ingos-source-context:Solar"
local sourceTagParam = "ingos-source:source=Solar"

local feedsWithCustomTags = List(
new FeedTags{
feedName = "APT"
customTags = List()
},
new FeedTags{
feedName = "C2"
customTags = List()
},
new FeedTags{
feedName = "MALWARE"
customTags = List()
},
new FeedTags{
feedName = "BOTNET"
customTags = List()
},
new FeedTags{
feedName = "CRYPTOMINING"
customTags = List()
},
new FeedTags{
feedName = "STEALER"
customTags = List()
},
new FeedTags{
feedName = "RANSOMWARE"
customTags = List()
},
new FeedTags{
feedName = "MALICIOUS"
customTags = List()
},
new FeedTags{
feedName = "HACKTOOL"
customTags = List()
},
new FeedTags{
feedName = "4RAYS_PULSE"
customTags = List()
},
new FeedTags{
feedName = "GENERIC"
customTags = List()
}
)

local class FeedTags {
feedName: String
customTags: List<String>
}

local function getPipeline(feedName: String, customTags: List<String>): Components.Pipeline = new Components.Pipeline {
local tagsList = List(sourceTagParam) + customTags

name = "misp_" + feedName.toLowerCase() + "_pipeline"
inputs {
new agent.FeedStreamGenerator {
name = feedName.toLowerCase() + "-generator"
server = templates.serverEnvCfg
schedule = templates.scheduleCronMinCfg
filter = new agent.IndicatorRequestParams {
actions = List("create", "update", "delete")
types = List("ipv4-addr", "ipv6-addr", "url", "domain-name", "md5-hash", "sha1-hash", "sha256-hash")
fields = List("indicator_id", "indicator_type", "value", "action", "first_seen", "last_seen", "relations", "feeds", "zone")
feedNames = List(feedName.toLowerCase())
}
sqlite = templates.sqliteEnvCfg
}
}
transforms {
new agent.IndicatorsFilter {
name = feedName.toLowerCase() + "-filter"
inputs {
feedName.toLowerCase() + "-generator"
}
code = """
let filteredRelations = filter(Relations, {#.ObjectType == \"malware\" || #.ObjectType == \"threat-actor\" || #.ObjectType == \"indicator\" || #.ObjectType == \"report\"});
len(filter(filteredRelations, {#.IndicatorType != \"file\"})) > 0
"""
}
new agent.IndicatorsTextMap {
name = feedName.toLowerCase() + "-map"
inputs {
feedName.toLowerCase() + "-filter"
}
fieldsMap {
["indicator_id"] = "IndicatorID"
["indicator_type"] = "IndicatorType"
["value"] = "normalizeValue(IndicatorType, Value)"
["action"] = "Action"
["first_seen"] = "FirstSeen"
["last_seen"] = "LastSeen"
["zone"] = "Zone"
["feed_names"] = """
join(Feeds, ",")
"""
["threat_actors"] = """
let actors = map(Relations, {#.ObjectType == "threat-actor" ? #.ObjectValue : ""});
join(filter(actors, {# != ""}), ",")
"""
["malware"] = """
let malware = map(Relations, {#.ObjectType == "malware" ? #.ObjectValue : ""});
join(filter(malware, {# != ""}), ",")
"""
["indicators"] = """
let filteredRelations = filter(Relations, {#.IndicatorType != "file"});
let indicators = map(filteredRelations, let x = #; x.ObjectType == "indicator" ? x.ObjectID + ":" + x.IndicatorType + ":" + normalizeValue(x.IndicatorType, x.ObjectValue) : "");
join(filter(indicators, {# != ""}), ",")
"""
["info"] = """
let actors = map(Relations, {#.ObjectType == "threat-actor" ? #.ObjectValue : ""});
let malware = map(Relations, {#.ObjectType == "malware" ? #.ObjectValue : ""});
let info = join(filter(concat(actors, malware), {# != ""}), ",");
if len(info) > 0 {Value + " " + info} else {Value}
"""
["comment"] = """
let report = map(Relations, {#.ObjectType == "report" ? #.ObjectValue : ""});
let actors = map(Relations, {#.ObjectType == "threat-actor" ? #.ObjectValue : ""});
let malware = map(Relations, {#.ObjectType == "malware" ? #.ObjectValue : ""});
join(filter(concat(actors, malware, report), {# != ""}), ",")
"""
["custom_tags"] = """
["\(tagsList.join(","))"]
"""
}
}
}
sinks {
new agent.IndicatorsTextSink {
name = feedName.toLowerCase() + "-sink"
inputs {
feedName.toLowerCase() + "-map"
}
writer {
outputDirectory = templates.outputDirEnv
outputFileName = feedName.toLowerCase() + ".csv"
writeMode = "rolling"
fileFormat = "csv"
writeHeaders = false
separator = ";"
allQuotes = true
}
sqlite = templates.sqliteEnvCfg
service = new agent.MispCfg {
address {
host = templates.externalServiceHostEnv
port = templates.externalServicePortEnv
insecureSkipVerify = true
scheme = "https"
}
credentials = new agent.Token {
token = templates.externalServiceTokenEnv
}
timeout = 60.s
threatActorsTagPrefix = threatActorsTagPrefixParam
malwareTagPrefix = malwareTagPrefixParam
feedTagPrefix = feedTagPrefixParam
}
}
}
}

pipelines = feedsWithCustomTags.map((feedTag) -> getPipeline(feedTag.feedName, feedTag.customTags)).toListing()

settings = templates.baseSettings

Мониторинг результатов работы интеграции

После запуска агента убедитесь в корректности работы интеграции:

  • Проверка файлов результатов: Убедитесь, что в рабочей директории (TIC_AGENT_OUTPUT_DIR) создаются CSV-файлы с именами соответствующих фидов.
  • Анализ логов: Проверьте логи агента в директории TIC_AGENT_LOG_DIR на наличие ошибок или предупреждений.
  • Верификация в MISP: В интерфейсе MISP убедитесь, что созданы списки индикаторов с префиксом 4rays_ и что они содержат актуальные данные.