Примеры DQL для данных безопасности

Материал из Документация Ключ-АСТРОМ

Примеры DQL для данных безопасности

Примеры ниже показывают, как анализировать данные безопасности и создавать мощные и гибкие отчёты по безопасности с помощью Ключ-АСТРОМ Query Language (DQL).

Запрос событий Ключ-АСТРОМ

Общее количество открытых уязвимостей

Получите общее количество открытых, неотключённых уязвимостей в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status=="OPEN"
     AND vulnerability.mute.status!="MUTED"
// count unique vulnerabilities
| summarize {`Open vulnerabilities`=countDistinctExact(vulnerability.display_id)}

Общее количество критических открытых уязвимостей

Получите общее количество критических открытых, неотключённых уязвимостей в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for critical open non-muted vulnerabilities
| filter vulnerability.resolution.status=="OPEN"
     AND vulnerability.mute.status!="MUTED"
     AND vulnerability.risk.level=="CRITICAL"
// count unique vulnerabilities
| summarize {`Critical open vulnerabilities`=countDistinctExact(vulnerability.display_id)}

Общее количество открытых уязвимостей в зоне управления

Получите общее количество открытых, неотключённых уязвимостей в конкретной зоне управления (в этом примере — AppSec: UNGUARD).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities in a specific management zone
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     AND in("AppSec: Unguard", affected_entity.management_zones.names)
// count unique vulnerabilities
| summarize {`Open vulnerabilities (unguard)`=countDistinctExact(vulnerability.display_id)}

Общее количество открытых уязвимостей с доступом из интернета

Получите общее количество открытых, неотключённых уязвимостей с публичным доступом из интернета в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities with public internet exposure
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     AND vulnerability.davis_assessment.exposure_status=="PUBLIC_NETWORK"
// count unique vulnerabilities
| summarize {`With internet exposure`=countDistinctExact(vulnerability.display_id)}

Общее количество затронутых сущностей

Получите общее количество затронутых сущностей в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
// count unique entities
| summarize {`Affected entities`=countDistinctExact(affected_entity.id)}

Общее количество затронутых групп процессов

Получите общее количество затронутых групп процессов в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities detected in running processes
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     AND affected_entity.type=="PROCESS_GROUP"
// count unique entities
| summarize {`Affected process groups`=countDistinctExact(affected_entity.id)}

Общее количество затронутых сущностей за период времени

Получите общее количество затронутых, неотключённых сущностей за период времени (с шагом в три часа).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
     // filter for open non-muted vulnerabilities
     AND vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
// count unique entities for each timestamp bucket of 3h
| sort timestamp desc
| summarize {entities=countDistinctExact(affected_entity.id)}, by: {timestamp=bin(timestamp, 3h)}

Общее количество хостов, связанных с уязвимостями

Получите общее количество хостов, косвенно затронутых открытыми уязвимостями в вашей среде.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
|filter  vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
// count hosts
| summarize {`Related hosts`=arraySize(collectDistinct(related_entities.hosts.ids, expand:true))}

Открытые уязвимости по уровню риска

Получите количество открытых уязвимостей с разбивкой по уровням риска.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
// summarize score per vulnerability
| summarize {vulnerability.risk.score=takeMax(vulnerability.risk.score)}, by: {vulnerability.display_id}
// map the risk level
| fieldsAdd vulnerability.risk.level=if(vulnerability.risk.score>=9,"CRITICAL",
                                     else:if(vulnerability.risk.score>=7,"HIGH",
                                     else:if(vulnerability.risk.score>=4,"MEDIUM",
                                     else:if(vulnerability.risk.score>=0.1,"LOW",
                                     else:"NONE"))))
// count vulnerabilities per risk level
| summarize { Vulnerabilities=count(), maxScore=takeMax(vulnerability.risk.score) }, by:{vulnerability.risk.level}
| sort maxScore, direction:"descending"

Открытые уязвимости по типу

Получите количество открытых уязвимостей с разбивкой по типу.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
// count vulnerabilities per type
| summarize { Vulnerabilities=countDistinctExact(vulnerability.display_id) }, by:{vulnerability.type}
| sort Vulnerabilities, direction:"descending"
| limit 10

Открытые уязвимости за период времени

Получите количество открытых уязвимостей за период времени с шагом в три часа.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
     // filter for open non-muted vulnerabilities
     AND vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
| sort timestamp desc
| summarize {Open=countDistinctExact(vulnerability.display_id)}, by: {timestamp=bin(timestamp,3h)}

Уязвимости в библиотеке

Получите открытые уязвимости в конкретной библиотеке (в этом примере — log4j).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     // filter by the vulnerable library/component name
     AND contains(affected_entity.vulnerable_component.name,"log4j",caseSensitive:false)
// now summarize on the vulnerability level
| summarize{
    vulnerability.risk.score=round(takeMax(vulnerability.risk.score),decimals:1),
    vulnerability.title=takeFirst(vulnerability.title),
    vulnerability.references.cve=takeFirst(vulnerability.references.cve),
    last_detected=coalesce(takeMax(vulnerability.resolution.change_date),takeMax(vulnerability.parent.first_seen)),
    affected_entities=countDistinctExact(affected_entity.id),
    vulnerable_function_in_use=if(in("IN_USE",collectArray(vulnerability.davis_assessment.vulnerable_function_status)),true, else:false),
    public_internet_exposure=if(in("PUBLIC_NETWORK",collectArray(vulnerability.davis_assessment.exposure_status)),true,else:false),
    public_exploit_available=if(in("AVAILABLE",collectArray(vulnerability.davis_assessment.exploit_status)),true,else:false),
    data_assets_within_reach=if(in("REACHABLE",collectArray(vulnerability.davis_assessment.data_assets_status)),true,else:false)
}, by: {vulnerability.display_id}
// map the risk level
| fieldsAdd vulnerability.risk.level=if(vulnerability.risk.score>=9,"CRITICAL",
                                     else:if(vulnerability.risk.score>=7,"HIGH",
                                     else:if(vulnerability.risk.score>=4,"MEDIUM",
                                     else:if(vulnerability.risk.score>=0.1,"LOW",
                                     else:"NONE"))))
| sort   {vulnerability.risk.score, direction:"descending"}, {affected_entities, direction:"descending"}

Уязвимости на хосте

Получите открытые уязвимости, прямо или косвенно затрагивающие конкретный хост (в этом примере — i-05f1305a50721e04d).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     // filter by the host name of the related/affected host
     AND in("easytravel-demo2",related_entities.hosts.names) OR affected_entity.name=="easytravel-demo2"
// now summarize on the vulnerability level
| summarize{
    vulnerability.risk.score=round(takeMax(vulnerability.risk.score),decimals:1),
    vulnerability.title=takeFirst(vulnerability.title),
    vulnerability.references.cve=takeFirst(vulnerability.references.cve),
    last_detected=coalesce(takeMax(vulnerability.resolution.change_date),takeMax(vulnerability.parent.first_seen)),
    affected_entities=countDistinctExact(affected_entity.id),
    vulnerable_function_in_use=if(in("IN_USE",collectArray(vulnerability.davis_assessment.vulnerable_function_status)),true, else:false),
    public_internet_exposure=if(in("PUBLIC_NETWORK",collectArray(vulnerability.davis_assessment.exposure_status)),true,else:false),
    public_exploit_available=if(in("AVAILABLE",collectArray(vulnerability.davis_assessment.exploit_status)),true,else:false),
    data_assets_within_reach=if(in("REACHABLE",collectArray(vulnerability.davis_assessment.data_assets_status)),true,else:false)
}, by: {vulnerability.display_id}
// map the risk level
| fieldsAdd vulnerability.risk.level=if(vulnerability.risk.score>=9,"CRITICAL",
                                     else:if(vulnerability.risk.score>=7,"HIGH",
                                     else:if(vulnerability.risk.score>=4,"MEDIUM",
                                     else:if(vulnerability.risk.score>=0.1,"LOW",
                                     else:"NONE"))))
| sort {vulnerability.risk.score, direction:"descending"}, {affected_entities, direction:"descending"}

Уязвимости в приложении

Получите открытые уязвимости, затрагивающие конкретное приложение (в этом примере — www.easytravel.com).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     // filter by name of the related applications
     AND in("www.easytravel.com",related_entities.applications.names)
// now summarize on the vulnerability level
| summarize{
    vulnerability.risk.score=round(takeMax(vulnerability.risk.score),decimals:1),
    vulnerability.title=takeFirst(vulnerability.title),
    vulnerability.references.cve=takeFirst(vulnerability.references.cve),
    last_detected=coalesce(takeMax(vulnerability.resolution.change_date),takeMax(vulnerability.parent.first_seen)),
    affected_entities=countDistinctExact(affected_entity.id),
    vulnerable_function_in_use=if(in("IN_USE",collectArray(vulnerability.davis_assessment.vulnerable_function_status)),true, else:false),
    public_internet_exposure=if(in("PUBLIC_NETWORK",collectArray(vulnerability.davis_assessment.exposure_status)),true,else:false),
    public_exploit_available=if(in("AVAILABLE",collectArray(vulnerability.davis_assessment.exploit_status)),true,else:false),
    data_assets_within_reach=if(in("REACHABLE",collectArray(vulnerability.davis_assessment.data_assets_status)),true,else:false)
}, by: {vulnerability.display_id}
// map the risk level
| fieldsAdd vulnerability.risk.level=if(vulnerability.risk.score>=9,"CRITICAL",
                                     else:if(vulnerability.risk.score>=7,"HIGH",
                                     else:if(vulnerability.risk.score>=4,"MEDIUM",
                                     else:if(vulnerability.risk.score>=0.1,"LOW",
                                     else:"NONE"))))
| sort   {vulnerability.risk.score, direction:"descending"}, {affected_entities, direction:"descending"}

Топ-10 затронутых сущностей по количеству уязвимостей

Получите топ-10 затронутых сущностей по количеству открытых уязвимостей.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
| summarize {
    `Affected entity name` = takeFirst(affected_entity.name),
    Type = takeFirst(affected_entity.type),
    Vulnerabilities = countDistinctExact(vulnerability.display_id)
}, by: {dt.source_entity=affected_entity.id}
| sort {Vulnerabilities, direction:"descending"}
| limit 10

Топ-10 групп процессов с владельцами

Получите топ-5 групп процессов по количеству открытых уязвимостей с указанием их владельцев.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     AND affected_entity.type=="PROCESS_GROUP"
// summarize per process group
| summarize {
    `Affected entity name` = takeFirst(affected_entity.name),
    Type = takeFirst(affected_entity.type),
    Vulnerabilities = countDistinctExact(vulnerability.display_id)
}, by: {dt.source_entity=affected_entity.id}
| sort {Vulnerabilities, direction:"descending"}
| limit 10
// add ownership information
| lookup [
    fetch dt.entity.process_group
    | parse toString(tags), "LD ('owner:'|'owner\\\\:') (SPACE)? LD:Team ('\"')"
    | fields id, Team=coalesce(Team, "-")
], sourceField:dt.source_entity, lookupField:id, fields:{Team}
| sort Vulnerabilities, direction:"descending"

Хосты, связанные с уязвимостями в библиотеке, с владельцами

Получите хосты, косвенно связанные с открытыми уязвимостями в конкретной библиотеке (в этом примере — tomcat), с указанием их владельцев.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     AND related_entities.hosts.count > 0
     // filter by the vulnerable component name
     AND contains(affected_entity.vulnerable_component.name,"tomcat")
| expand entity_id=related_entities.hosts.ids
| summarize Vulnerabilities=countDistinctExact(vulnerability.display_id), by: {entity_id}
//add ownership information
| lookup [
    fetch dt.entity.host
    | parse toString(tags), "LD ('owner:'|'owner\\\\:') (SPACE)? LD:Team ('\"')"
    | fields id, Host=entity.name, Team=coalesce(Team, "-")
], sourceField:entity_id, lookupField:id, fields: {Host,Team}
| sort Vulnerabilities, direction:"descending"

Уязвимые программные компоненты хоста с владельцами

Получите уязвимые компоненты конкретного хоста (в этом примере — HOST-4CF0F659B8823D74) с владельцами.

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     // filter by ID of the related or affected host
     AND in("HOST-DBF63A01C27E4B50",related_entities.hosts.ids) or affected_entity.id=="HOST-DBF63A01C27E4B50"
| summarize{
    entities=countDistinctExact(affected_entity.id),
    vulnerable_functions=arraySize(collectDistinct(affected_entity.vulnerable_functions, expand:true)),
    vulnerable_component.name=takeAny(affected_entity.vulnerable_component.name)
}, by: {dt.entity.software_component=affected_entity.vulnerable_component.id}
| filterOut isNull(dt.entity.software_component)
// add component information
| lookup [
    fetch dt.entity.software_component
    | fieldsAdd softwareComponentFileName
], sourceField:dt.entity.software_component, lookupField:id, fields:{softwareComponentFileName}
| fields dt.entity.software_component, vulnerable_component.name, softwareComponentFileName, entities, vulnerable_functions
| sort {entities, direction:"descending"}, {vulnerable_functions, direction:"descending"}

Уязвимые функции программного компонента

Получите уязвимые функции конкретного программного компонента (в этом примере — SOFTWARE_COMPONENT-1D466FB7ADEBF92E).

Пример запроса:

fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
     AND event.provider=="astromkey"
     AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
     AND event.level=="ENTITY"
// filter for the latest snapshot per entity
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
// filter for open non-muted vulnerabilities
| filter vulnerability.resolution.status == "OPEN"
     AND vulnerability.mute.status != "MUTED"
     // filter for the software component ID
     AND affected_entity.vulnerable_component.id=="SOFTWARE_COMPONENT-1D466FB7ADEBF92E"
| expand vulnerable_function=affected_entity.vulnerable_functions
| filter isNotNull(vulnerable_function)
| summarize{Usages=countIf(in(vulnerable_function,affected_entity.vulnerable_functions))}, by: {vulnerable_function}
| sort {Usages, direction:"descending"}

Запрос принятых событий

Общее количество критических обнаружений уязвимостей

Получите общее количество критических обнаружений уязвимостей, загруженных в Ключ-АСТРОМ.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents"
     AND event.type == "VULNERABILITY_FINDING"
     AND isNotNull(component.name)
// latest findings per affected object, vulnerability and component
| dedup {object.id, vulnerability.id, component.name, component.version}, sort: {timestamp desc}
// aggregation and custom filtering
| filter dt.security.risk.level=="CRITICAL"
| summarize {Vulnerabilities=countDistinctExact(vulnerability.id)}

Общее количество уязвимых образов контейнеров

Получите общее количество образов контейнеров, содержащих обнаружения уязвимостей, загруженных в Ключ-АСТРОМ.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents"
     AND event.type == "VULNERABILITY_FINDING"
     AND isNotNull(component.name)
// latest findings per affected object, vulnerability and component
| dedup {object.id, vulnerability.id, component.name, component.version,
         container_image.registry, container_image.repository, container_image.tags}, sort: {timestamp desc}
// aggregation and custom filtering
| summarize {containerImages=countDistinctExact(container_image.digest)}

Общее количество уязвимых компонентов

Получите общее количество уязвимых компонентов в образах контейнеров, содержащих обнаружения уязвимостей, загруженных в Ключ-АСТРОМ.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents"
     AND event.type == "VULNERABILITY_FINDING"
     AND isNotNull(component.name)
// latest findings per affected object, vulnerability and component
| dedup {object.id, vulnerability.id, component.name, component.version}, sort: {timestamp desc}
// aggregation and custom filtering
| summarize {components=countDistinctExact(component.name)}

Последние обнаружения уязвимостей

Получите последние обнаружения уязвимостей, загруженные в Ключ-АСТРОМ.

Пример запроса:

fetch security.events
// data access
| filter dt.system.bucket == "default_securityevents"
     AND event.type == "VULNERABILITY_FINDING"
     AND isNotNull(component.name)
// latest findings per affected object, vulnerability and component
| dedup {object.id, vulnerability.id, component.name, component.version}, sort: {timestamp desc}
| sort timestamp desc

Количество просканированных образов контейнеров

Получите общее количество загруженных образов контейнеров, которые были просканированы.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents"
| filter object.type == "CONTAINER_IMAGE" // includes both SCAN_EVENTS and VULNERABILITY_FINDINGS without scan events
| dedup {container_image.digest}, sort: {timestamp desc}
| summarize {containerImages=count()}

Количество событий сканирования образов контейнеров

Получите общее количество событий сканирования из загруженных образов контейнеров.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents"
| filter event.type == "VULNERABILITY_SCAN"
  AND object.type == "CONTAINER_IMAGE"
| summarize {scanEvents=count()}

Запрос событий соответствия

Последние результаты для всех охваченных систем

Получите последние результаты соответствия поддерживаемых стандартов для всех систем, охваченных Security Posture Management.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents_builtin"
  AND event.type == "COMPLIANCE_SCAN_COMPLETED"
// filter for the latest assessment
| dedup {object.name}, sort:{timestamp desc}
// parse the compliance percentage from json
| parse `scan.result.summary_json`, """JSON{JSON_ARRAY{JSON{ STRING:standardCode, INT:compliancePercentage }}:standardResultSummaries}(flat=true)"""
| expand standardResultSummaries
| fieldsFlatten standardResultSummaries
| fields timestamp, object.name, standard = standardResultSummaries.standardCode, compliance = standardResultSummaries.compliancePercentage

Исторические результаты соответствия по стандарту для всех охваченных систем

Получите исторические результаты соответствия по стандарту (в данном случае — DORA) для всех систем, охваченных Security Posture Management.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents_builtin"
  AND event.type == "COMPLIANCE_SCAN_COMPLETED"
// parse the compliance percentage from json
| parse `scan.result.summary_json`, """JSON{JSON_ARRAY{JSON{ STRING:standardCode, INT:compliancePercentage }}:standardResultSummaries}(flat=true)"""
| expand standardResultSummaries
| fieldsFlatten standardResultSummaries
// filter for the specific standard
| filter standardResultSummaries.standardCode == "DORA"
| fields timestamp, object.name, standardResultSummaries.compliancePercentage

Последние результаты анализа для системы за выбранный период

Получите последние результаты анализа для данной системы за выбранный период.

Это даёт представление, аналогичное отображаемому в xSPM Security Posture Management на странице результатов оценки.

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents_builtin"
  AND event.type == "COMPLIANCE_FINDING"
// filter for the latest rule assessment results in the timeframe
| join [
  fetch security.events
    | filter dt.system.bucket == "default_securityevents_builtin"
      AND event.type == "COMPLIANCE_SCAN_COMPLETED"
    // filter for desired system
      AND object.name == "demo-kspm"
    | dedup object.name, sort: { timestamp desc }
    | fields scan.id
  ], on: {scan.id}
// summarize findings on rule level
| summarize {
        compliance.rule.severity.level = takeFirst(compliance.rule.severity.level),
        compliance.standard.short_name = takeFirst(compliance.standard.short_name),
        compliance.rule.title = takeFirst(compliance.rule.title),
        compliance.standard.url = takeFirst(compliance.standard.url),
        finding.time.created = takeFirst(finding.time.created),
        compliance.result.count.passed = countIf(compliance.result.status.level == "PASSED"),
        compliance.result.count.failed = countIf(compliance.result.status.level == "FAILED"),
        compliance.result.count.manual = countIf(compliance.result.status.level == "MANUAL"),
        compliance.result.count.not_relevant = countIf(compliance.result.status.level == "NOT_RELEVANT"),
        compliance.rule.metadata_json = takeFirst(compliance.rule.metadata_json)
      },
      by: { compliance.rule.id }
 // add rule level status
 | fieldsAdd compliance.result.status.level =
      if(compliance.result.count.failed > 0, "FAILED",
      else: if(compliance.result.count.manual > 0, "MANUAL",
      else: if(compliance.result.count.passed > 0, "PASSED",
      else: "NOT_RELEVANT"
   )))
 | filterout compliance.result.status.level == "NOT_RELEVANT"

Исторические результаты оценки для выбранного правила и системы

Получите количество для каждой оценки, выполненной за выбранный период для выбранного правила и системы (в данном случае — dt-cluster-01).

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents_builtin"
  AND event.type == "COMPLIANCE_FINDING"
  AND k8s.cluster.name == "dt-cluster-01"
  // filter for the specific rule
  AND compliance.rule.id == "DORA-67950"
// summarize findings on rule level
| summarize {
  timestamp = takeFirst(timestamp),
  Passed=countIf(compliance.result.status.level == "PASSED"),
  Failed=countIf(compliance.result.status.level == "FAILED"),
  Manual=countIf(compliance.result.status.level == "MANUAL")
}, by: {scan.id}
| makeTimeseries avg(Passed), avg(Failed), avg(Manual)

Последние ошибки конфигурации объекта согласно определённому стандарту

Получите количество последних ошибок конфигурации объекта (в данном случае — ip-10-45-243-57) для конкретного стандарта (в данном случае — CIS).

Пример запроса:

fetch security.events
| filter dt.system.bucket == "default_securityevents_builtin"
  AND event.type == "COMPLIANCE_FINDING"
  // filter for desired object
  AND object.name == "ip-10-45-243-57"
  // filter for compliance findings reporting misconfigurations
  AND compliance.result.status.level == "FAILED"
  // filter for the specific standard
  AND compliance.standard.short_name == "CIS"
// filter for the latest rule assessment results in the timeframe
| join [
  fetch security.events
    | filter dt.system.bucket == "default_securityevents_builtin"
      AND event.type == "COMPLIANCE_SCAN_COMPLETED"
    // filter for desired system
      AND object.name == "demo-kspm"
    | dedup object.name, sort: { timestamp desc }
    | fields scan.id
  ], on: {scan.id}