Примеры DQL для данных безопасности
- Latest Dynatrace
- How-to guide
Эта страница была обновлена в соответствии с новой таблицей событий безопасности Grail. Полный список изменений и действий, необходимых для выполнения миграции, см. в руководстве по миграции таблицы безопасности Grail.
Приведённые ниже примеры иллюстрируют, как разрезать данные безопасности и создавать мощные и гибкие отчёты по безопасности с помощью Dynatrace Query Language (DQL).
Запросы к событиям Dynatrace¶
Общее количество открытых уязвимостей¶
Получите общее количество открытых, не отключённых уязвимостей в вашей среде.
Пример запроса:
fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
AND event.provider=="Dynatrace"
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.parent.mute.status!="MUTED"
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=="Dynatrace"
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.parent.mute.status!="MUTED"
AND vulnerability.mute.status!="MUTED"
AND vulnerability.risk.level=="CRITICAL"
// count unique vulnerabilities
| summarize {`Critical open vulnerabilities`=countDistinctExact(vulnerability.display_id)}
Результат запроса:

Общее количество открытых уязвимостей в Management Zone¶
Получите общее количество открытых, не отключённых уязвимостей в определённой Management Zone (в этом примере — AppSec: UNGUARD).
Пример запроса:
fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
AND event.provider=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
AND event.level=="ENTITY"
// filter for open non-muted vulnerabilities
AND vulnerability.resolution.status == "OPEN"
AND vulnerability.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
AND event.type=="VULNERABILITY_STATE_REPORT_EVENT"
AND event.level=="ENTITY"
// filter for open non-muted vulnerabilities
AND vulnerability.resolution.status == "OPEN"
AND vulnerability.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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 групп процессов с владельцами¶
Получите топ-10 групп процессов по количеству открытых уязвимостей с соответствующими владельцами.
Пример запроса:
fetch security.events
| filter dt.system.bucket=="default_securityevents_builtin"
AND event.provider=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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=="Dynatrace"
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.parent.mute.status != "MUTED"
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"}
Результат запроса:

Запросы к загружаемым событиям¶
Общее количество критических результатов анализа уязвимостей¶
Получите общее количество критических результатов анализа уязвимостей, загруженных в Dynatrace.
Пример запроса:
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)}
Результат запроса:

Общее количество уязвимых образов контейнеров¶
Получите общее количество образов контейнеров, содержащих результаты анализа уязвимостей, загруженные в Dynatrace.
Пример запроса:
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)}
Результат запроса:

Общее количество уязвимых компонентов¶
Получите общее количество уязвимых компонентов в образах контейнеров, содержащих результаты анализа уязвимостей, загруженные в Dynatrace.
Пример запроса:
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)}
Результат запроса:

Последние результаты анализа уязвимостей¶
Получите последние результаты анализа уязвимостей, загруженные в Dynatrace.
Пример запроса:
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
Результат запроса:

Последние результаты анализа для системы в выбранном временном интервале¶
Получите последние результаты анализа для конкретной системы в выбранном временном интервале.
Это даёт представление, аналогичное отображаемому в
Security Posture Management на странице Assessment results.
Пример запроса:
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}
Результат запроса:
