[KL] "Playbook for isolating a device where an infected file is detected"

19 октября 2026

ID 324934

Предустановленный плейбук [KL] "Playbook for isolating a device where an infected file is detected" изолирует устройство после обнаружения зараженного файла.

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

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

  1. Получение файла из выбранного актива.
  2. Отправка полученного файла на проверку.
    • Если во время проверки возникает ошибка, выполнение плейбука прерывается.
    • Если проверка завершена и угрозы не обнаружены, выполнение плейбука прерывается.
    • Если проверка завершена и угроза обнаружена:
      • На всех выбранных устройствах включается сетевая изоляция.
      • Правило запрета на основе хеша добавляется ко всем устройствам в тенанте.

Дополнительная информация о плейбуке.

  • Если на шагах по добавлению правил запрета для включения сетевой изоляции возникает ошибка, выполнение плейбука прерывается, во всех других случаях оно будет продолжаться.
  • Действия "Включить сетевую изоляцию" и "Добавить правило запрета" необходимо вручную подтвердить во время выполнения плейбука.

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"

}

}

}

]

}

]

}

}

]

}

]

}

}

]

}

Вам помогла эта статья?
Что нам нужно улучшить?
Спасибо за ваш отзыв, вы помогаете нам становиться лучше!
Спасибо за ваш отзыв, вы помогаете нам становиться лучше!