Detection rules › Kusto

Detect Windows Allow Firewall Rule Addition/Modification

Status
available
Severity
medium
Time window
1h
Source
github.com/Azure/Azure-Sentinel

This analytic rule detects any registry value creation or modification of Windows firewall registry keys to allow network traffic. This could be an indication of defense evasion by an adversary to allow network traffic to/from a compromised host.

MITRE ATT&CK coverage

TacticTechniques
StealthT1562 Impair Defenses

Event coverage

Rule body kusto

id: 056593d4-ca3b-47a7-be9d-d1d0884a1d36
name: Detect Windows Allow Firewall Rule Addition/Modification
description: |
  This analytic rule detects any registry value creation or modification of Windows firewall registry keys to allow network traffic. This could be an indication of defense evasion by an adversary to allow network traffic to/from a compromised host.
severity: Medium
status: Available 
tags:
  - Schema: _ASim_RegistryEvent
    SchemaVersion: 0.1.2
requiredDataConnectors:
  - connectorId: CrowdStrikeFalconEndpointProtection
    dataTypes: 
      - CommonSecurityLog
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - SecurityAlert
  - connectorId: SentinelOne
    dataTypes:
      - SentinelOne_CL
  - connectorId: VMwareCarbonBlack
    dataTypes:
      - CarbonBlackEvents_CL
  - connectorId: CiscoSecureEndpoint
    dataTypes:
      - CiscoSecureEndpoint_CL
  - connectorId: TrendMicroApexOne
    dataTypes:
      - TMApexOneEvent
  - connectorId: TrendMicroApexOneAma
    dataTypes:
      - TMApexOneEvent
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - DefenseEvasion
relevantTechniques:
  - T1562
query: |
  // List of Windows Firewall registry keys to monitor
  let firewallRegistryList = dynamic([
        'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Static\\System',
        'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Configurable\\System',
        'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Defaults\\FirewallPolicy\\FirewallRules',
        'HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\WindowsFirewall'
    ]);
  _ASim_RegistryEvent
  | where EventType in ('RegistryValueSet', 'RegistryKeyCreated') 
  | where RegistryKey has_any (firewallRegistryList) and RegistryValueData has_all ('Action=Allow', 'Active=TRUE')
  | project
      TimeGenerated,
      DvcHostname,
      ActorUsername,
      ActorUsernameType,
      ActingProcessId,
      ActingProcessName,
      ActingProcessCommandLine,
      RegistryKey,
      RegistryValue,
      RegistryValueType,
      RegistryValueData
  | extend HostName = tostring(split(DvcHostname, '.')[0])
  | extend DnsDomain = tostring(strcat_array(array_slice(split(DvcHostname, '.'), 1, -1), '.'))
  | extend Username = iff(tostring(ActorUsernameType) == 'Windows', tostring(split(ActorUsername, '\\')[1]), ActorUsername)
  | extend NTDomain = iff(tostring(ActorUsernameType) == 'Windows', tostring(split(ActorUsername, '\\')[0]), ActorUsername)
  | extend Username = iff(tostring(ActorUsernameType) == 'UPN', tostring(split(ActorUsername, '@')[0]), Username)
  | extend UPNSuffix = iff(tostring(ActorUsernameType) == 'UPN', tostring(split(ActorUsername, '@')[1]), '')
  | extend RegHive = tostring(split(RegistryKey, '\\')[0]), RegKey = tostring(strcat_array(array_slice(split(RegistryKey, '\\'), 1, -1), '\\')) 
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: DnsDomain
      - identifier: NTDomain
        columnName: NTDomain
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: Username
      - identifier: UPNSuffix
        columnName: UPNSuffix
      - identifier: NTDomain
        columnName: NTDomain
  - entityType: Process
    fieldMappings:
      - identifier: ProcessId
        columnName: ActingProcessId
      - identifier: CommandLine
        columnName: ActingProcessCommandLine
  - entityType: RegistryKey
    fieldMappings:
      - identifier: Hive
        columnName: RegHive
      - identifier: Key
        columnName: RegKey
  - entityType: RegistryValue
    fieldMappings:
      - identifier: Name
        columnName: RegistryValue
      - identifier: Value
        columnName: RegistryValueData
      - identifier: ValueType
        columnName: RegistryValueType
eventGroupingSettings:
  aggregationKind: singleAlert
alertDetailsOverride:
  alertDisplayNameFormat: "Allow Firewall Rule {{RegistryValueData}} added at registry key {{RegKey}} on {{HostName}}"
  alertDescriptionFormat: "An allow Firewall Rule {{RegistryValueData}} added at registry key {{RegKey}} by {{Username}}."
version: 1.0.0
kind: Scheduled

Stages and Predicates

Let binding: firewallRegistryList

let firewallRegistryList = dynamic([
      'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Static\\System',
      'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Configurable\\System',
      'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Defaults\\FirewallPolicy\\FirewallRules',
      'HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\WindowsFirewall'
  ]);

Stage 1: source

_ASim_RegistryEvent

Stage 2: where

| where EventType in ('RegistryValueSet', 'RegistryKeyCreated')

Stage 3: where

| where RegistryKey has_any (firewallRegistryList) and RegistryValueData has_all ('Action=Allow', 'Active=TRUE')

References firewallRegistryList (defined above).

Stage 4: project

| project
    TimeGenerated,
    DvcHostname,
    ActorUsername,
    ActorUsernameType,
    ActingProcessId,
    ActingProcessName,
    ActingProcessCommandLine,
    RegistryKey,
    RegistryValue,
    RegistryValueType,
    RegistryValueData

Stage 5: extend (7 consecutive steps)

| extend HostName = tostring(split(DvcHostname, '.')[0])
| extend DnsDomain = tostring(strcat_array(array_slice(split(DvcHostname, '.'), 1, -1), '.'))
| extend Username = iff(tostring(ActorUsernameType) == 'Windows', tostring(split(ActorUsername, '\\')[1]), ActorUsername)
| extend NTDomain = iff(tostring(ActorUsernameType) == 'Windows', tostring(split(ActorUsername, '\\')[0]), ActorUsername)
| extend Username = iff(tostring(ActorUsernameType) == 'UPN', tostring(split(ActorUsername, '@')[0]), Username)
| extend UPNSuffix = iff(tostring(ActorUsernameType) == 'UPN', tostring(split(ActorUsername, '@')[1]), '')
| extend RegHive = tostring(split(RegistryKey, '\\')[0]), RegKey = tostring(strcat_array(array_slice(split(RegistryKey, '\\'), 1, -1), '\\'))

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
EventTypein
  • RegistryKeyCreated transforms: cased
  • RegistryValueSet transforms: cased corpus 4 (kusto 4)
RegistryKeymatch
  • HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\WindowsFirewall
  • HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Defaults\\FirewallPolicy\\FirewallRules
  • HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Configurable\\System
  • HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\RestrictedServices\\Static\\System
RegistryValueDatamatch
  • Action=Allow
  • Active=TRUE

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
ActingProcessCommandLineproject
ActingProcessIdproject
ActingProcessNameproject
ActorUsernameproject
ActorUsernameTypeproject
DvcHostnameproject
RegistryKeyproject
RegistryValueproject
RegistryValueDataproject
RegistryValueTypeproject
TimeGeneratedproject
HostNameextend
DnsDomainextend
Usernameextend
NTDomainextend
UPNSuffixextend
RegHiveextend
RegKeyextend