Detection rules › Kusto
Creation of expensive computes in Azure
Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure. An adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes. For Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes Azure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry coverage
Rule body
id: 9736e5f1-7b6e-4bfb-a708-e53ff1d182c3
name: Creation of expensive computes in Azure
description: |
'Identifies the creation of large size or expensive VMs (with GPUs or with a large number of virtual CPUs) in Azure.
An adversary may create new or update existing virtual machines to evade defenses or use them for cryptomining purposes.
For Windows/Linux Vm Sizes, see https://docs.microsoft.com/azure/virtual-machines/windows/sizes
Azure VM Naming Conventions, see https://docs.microsoft.com/azure/virtual-machines/vm-naming-conventions'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: AzureActivity
dataTypes:
- AzureActivity
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 1
tactics:
- DefenseEvasion
relevantTechniques:
- T1578
query: |
let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","nc12","nc24","nv24"]);
let operationList = dynamic(["microsoft.compute/virtualmachines/write", "microsoft.resources/deployments/write"]);
AzureActivity
| where OperationNameValue in~ (operationList)
| where ActivityStatusValue startswith "Accept"
| where Properties has 'vmSize'
| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties
| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)
| mv-apply token=tokens to typeof(string) on (where vmSize contains token)
| extend ComputerName = tostring((parsed_property.osProfile).computerName)
| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize
| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Caller
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: ComputerName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CallerIpAddress
version: 2.0.3
kind: Scheduled
Stages and Predicates
Parameters
let tokens = dynamic(["416","208","192","128","120","96","80","72","64","48","44","40","nc12","nc24","nv24"]);
let operationList = dynamic(["microsoft.compute/virtualmachines/write", "microsoft.resources/deployments/write"]);
Stage 1: source
AzureActivity
Stage 2: where
| where OperationNameValue in~ (operationList)
Stage 3: where
| where ActivityStatusValue startswith "Accept"
Stage 4: where
| where Properties has 'vmSize'
Stage 5: extend
| extend parsed_property= parse_json(tostring((parse_json(Properties).responseBody))).properties
Stage 6: extend
| extend vmSize = tostring((parsed_property.hardwareProfile).vmSize)
Stage 7: kusto:mv-apply
| mv-apply token=tokens to typeof(string) on (where vmSize contains token)
Stage 8: extend
| extend ComputerName = tostring((parsed_property.osProfile).computerName)
Stage 9: project
| project TimeGenerated, OperationNameValue, ActivityStatusValue, Caller, CallerIpAddress, ComputerName, vmSize
Stage 10: extend
| extend Name = tostring(split(Caller,'@',0)[0]), UPNSuffix = tostring(split(Caller,'@',1)[0])
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActivityStatusValue | starts_with |
| field:"ActivityStatusValue" kind:starts_with value:"Accept" |
OperationNameValue | in |
| field:"azure_ad::operation_name_value" kind:in |
Properties | match |
| field:"Properties" kind:match value:"vmSize" |
vmSize | cross_field_compare |
| field:"vmSize" kind:cross_field_compare value:"token" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ActivityStatusValue | project |
Caller | project |
CallerIpAddress | project |
ComputerName | project |
OperationNameValue | project |
TimeGenerated | project |
vmSize | project |
Name | extend |
UPNSuffix | extend |