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
Каждый пайплайн состоит из следующих компонентов:
- FeedStreamGenerator — получает индикаторы из Solar TI Feeds.
- IndicatorsFilter - фильтрует поток индикаторов выбирая индикаторы с контекстом.
- IndicatorsTextMap — преобразует данные в текстовый формат, пригодный для загрузки.
- IndicatorsTextSink — сохраняет данные в CSV-файл и загружает их в MISP.
Конфигурация автоматически создает отдельный пайплайн для каждого фида из списка allFeedsList. При необходимости вы можете изменить этот список, указав только нужные фиды.
Пример настройки списка фидов:
local feedsWithCustomTags = List(
new FeedTags{
feedName = "APT"
customTags = List()
},
new FeedTags{
feedName = "C2"
customTags = List()
}
)
Справочник параметров для MISP
Ключевые параметры конфигурации для MISP приведены в таблице:
| Параметр | Тип данных | Значение по умолчанию | Обязательность | Описание | Пример |
|---|---|---|---|---|---|
| credentials | Credentials | Да | Данные для аутентификации | credentials = new agent.Basic {username = misp_User password = misp_Password} | |
| address | Address | Да | Данные подключения | address {host = misp_Host port = misp_Port insecureSkipVerify = true scheme = "https"} | |
| timeout | Duration | 30.s | Нет | Таймаут запросов | 60.s |
| listName | String | Да | Имя списка для загрузки данных | “4rays_feeds” |
Дополнительные параметры конфигурации для расширения ServiceConfig – MispCfg:
| Параметр | Тип данных | Обязательность | Описание |
|---|---|---|---|
| threatActorsTagPrefix | String | Да | Префикс, с которым добаляеются теги Threat Actors к Event |
| malwareTagPrefix | String | Да | Префикс, с которым добаляеются теги Malware к Event |
| feedTagPrefix | String | Да | Префикс, с которым добаляеются теги фидов к 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_ и что они содержат актуальные данные.