Detection rules › Kusto

Creation of expensive computes in Azure

Status
available
Severity
low
Time window
1d
Source
github.com/Azure/Azure-Sentinel

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

TacticTechniques
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.

FieldKindValuesSearch
ActivityStatusValuestarts_with
  • Accept
field:"ActivityStatusValue" kind:starts_with value:"Accept"
OperationNameValuein
  • microsoft.compute/virtualmachines/write
  • microsoft.resources/deployments/write
field:"azure_ad::operation_name_value" kind:in
Propertiesmatch
  • vmSize transforms: term
field:"Properties" kind:match value:"vmSize"
vmSizecross_field_compare
  • token transforms: op:contains
field:"vmSize" kind:cross_field_compare value:"token"

Output fields

These fields are emitted when the rule matches.

FieldSource
ActivityStatusValueproject
Callerproject
CallerIpAddressproject
ComputerNameproject
OperationNameValueproject
TimeGeneratedproject
vmSizeproject
Nameextend
UPNSuffixextend