[KL] "Playbook for isolating a device where an infected file is detected"
Предустановленный плейбук [KL] "Playbook for isolating a device where an infected file is detected" изолирует устройство после обнаружения зараженного файла.
Плейбук не содержит триггер. Плейбук должен быть запущен вручную, и для этого нужно, чтобы пользователь выбрал контекст. Чтобы выполнить этот плейбук, вам нужно установить флажок Выберите целевые объекты перед запуском плейбуков и выбрать активы инцидентов и наблюдаемые объекты, для которых он будет выполняться.
Для каждого выбранного типа хеша наблюдаемого объекта выполняются следующие действия:
- Получение файла из выбранного актива.
- Отправка полученного файла на проверку.
- Если во время проверки возникает ошибка, выполнение плейбука прерывается.
- Если проверка завершена и угрозы не обнаружены, выполнение плейбука прерывается.
- Если проверка завершена и угроза обнаружена:
- На всех выбранных устройствах включается сетевая изоляция.
- Правило запрета на основе хеша добавляется ко всем устройствам в тенанте.
Дополнительная информация о плейбуке.
- Если на шагах по добавлению правил запрета для включения сетевой изоляции возникает ошибка, выполнение плейбука прерывается, во всех других случаях оно будет продолжаться.
- Действия "Включить сетевую изоляцию" и "Добавить правило запрета" необходимо вручную подтвердить во время выполнения плейбука.
ResponseFunction используется плейбуком: getFile, serverScan, addCommentToIncident, addFilePreventionRules, netIsolateOn.
Алгоритм плейбука содержит следующую последовательность действий по реагированию:
{
"version": "1",
"dslSpecVersion": "1.1.0",
"actionsSpecVersion": "1",
"playbookRunTimeout": "24h",
"executionFlow": [
{
"decision": {
"conditions": [
{
"condition": "${((.input.assets // []) | length) > 0 and ([.input.observables[] | select(.type == \"md5\" or .type == \"sha256\" and .value != null and .value != \"\")] | length) > 0}",
"name": "has input data",
"steps": [
{
"loop": {
"input": "${[(.input.observables | map(select(.type == \"md5\" or .type == \"sha256\") | select(.value != null and .value != \"\") | .value))[] as $hash | [incident.Alerts[] | .Observables[]? | select((.Type == \"md5\" or .Type == \"sha256\") and .Value == $hash and .Details != \"\")][0] | {\"path\": .Details,\"hash\":.Value}]}",
"steps": [
{
"decision": {
"conditions": [
{
"condition": "${.[0].path? | length > 0}",
"name": "hash with path",
"steps": [
{
"updateData": {
"action": "merge",
"filter": "${.[0]}"
}
},
{
"action": {
"function": {
"type": "getFile",
"asset": "${([incident.Alerts[] | .Assets[]? | select(.Type == \"host\")][0].ID // (.assets[0] // \"\"))}",
"params": {
"path": "${.path}"
}
},
"onError": "continue",
"timeout": {
"scheduleToCloseTimeout": "24h"
},
"output": {
"action": "merge",
"filter": "${{\"fileID\": (.details[0].details.file.id // null), \"scanResult\": null}}"
}
}
},
{
"decision": {
"conditions": [
{
"condition": "${.fileID != null and .fileID != \"\"}",
"name": "fileID exists",
"steps": [
{
"action": {
"function": {
"type": "serverScan",
"params": {
"file": {
"id": "${.fileID}"
}
}
},
"onError": "continue",
"timeout": {
"scheduleToCloseTimeout": "24h"
},
"output": {
"action": "merge",
"filter": "${{\"scanResult\": .}}"
}
}
},
{
"decision": {
"conditions": [
{
"condition": "${.scanResult != null and (.scanResult.resultCode == \"error\" or .scanResult.resultCode == null)}",
"name": "scan error",
"steps": [
{
"action": {
"function": {
"type": "addCommentToIncident",
"params": {
"text": "${\"[DEBUG scan ERROR] fileID: \" + (.fileID // \"null\") + \" | resultCode: \" + (.scanResult.resultCode // \"null\") + \" | errorCode: \" + (.scanResult.result.errorCode // \"null\") + \" | internalCode: \" + (.scanResult.result.internalCode // \"null\") + \"\\noriginalError: \" + (.scanResult.result.originalError // \"null\")}"
}
},
"onError": "continue",
"timeout": {
"scheduleToCloseTimeout": "24h"
}
}
}
]
},
{
"condition": "${.scanResult != null and .scanResult.resultCode == \"success\"}",
"name": "scan success",
"steps": [
{
"action": {
"function": {
"type": "addCommentToIncident",
"params": {
"text": "${\"[DEBUG scan] fileID: \" + (.fileID // \"null\") + \" | resultCode: \" + (.scanResult.resultCode // \"null\") + \"\\nresult: \" + ({\"fileID\": .fileID, \"resultCode\": .scanResult.resultCode, \"technologies\": .scanResult.details.scanResult.technologies} | tostring)}"
}
},
"onError": "continue",
"timeout": {
"scheduleToCloseTimeout": "24h"
}
}
},
{
"decision": {
"conditions": [
{
"condition": "${[.scanResult.details.scanResult.technologies[] | .result] | contains([\"Infected\"])}",
"name": "infected",
"steps": [
{
"action": {
"function": {
"type": "addFilePreventionRules",
"assets":[
"selector": "execution-tenant"
},
"params": {
"files": "${[.hash]}"
}
},
"onError": "stop",
"timeout": {
"scheduleToCloseTimeout": "24h"
},
"manualApprove": true
}
},
{
"updateData": {
"action": "overwrite",
"filter": "${{\"isInfected\": true}}"
}
}
]
}
]
}
}
]
}
]
}
}
]
}
]
}
}
]
}
]
}
}
],
"onError": "continue",
"batchSize": 1,
"aggregate": "${.}",
"output": {
"filter": "${{\"scanResult\": .}}"
}
}
},
{
"decision": {
"conditions": [
{
"condition": "${.scanResult | map(.isInfected) | any}",
"name": "isInfected",
"steps": [
{
"action": {
"function": {
"type": "netIsolateOn",
"assets": "${.input.assets | map(select(.Type == \"host\") | .ID)}",
"params": {
"exclusions": [],
"exclusionsConflictBehavior": "replace",
"isolationTimeoutSec": 28800
}
},
"onError": "stop",
"timeout": {
"scheduleToCloseTimeout": "24h"
}
}
}
]
}
]
}
}
]
}
]
}
}
]
}