Detection rules › Kusto

Anomalous User Agent connection attempt

Severity
low
Time window
1d
Group by
Computer, cIP, csMethod, csUriStem, csUserAgent, csUserAgent_size, csUserName, sIP, sPort, sSiteName, scStatus, scSubStatus, scWin32Status
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

'Identifies connection attempts (success or fail) from clients with very short or very long User Agent strings and with less than 100 connection attempts.'

MITRE ATT&CK coverage

TacticTechniques
Initial Access

Rule body

id: f845881e-2500-44dc-8ed7-b372af3e1e25
name: Anomalous User Agent connection attempt
description: |
  'Identifies connection attempts (success or fail) from clients with very short or very long User Agent strings and with less than 100 connection attempts.'
severity: Low
requiredDataConnectors:
  - connectorId: AzureMonitor(IIS)
    dataTypes:
      - W3CIISLog
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1190
query: |
  let short_uaLength = 5;
  let long_uaLength = 1000;
  let c_threshold = 100;
  W3CIISLog
  // Exclude local IPs as these create noise
  | where cIP !startswith "192.168." and cIP != "::1"
  | where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC") and (string_size(csUserAgent) <= short_uaLength or string_size(csUserAgent) >= long_uaLength)
  | extend csUserAgent_size = string_size(csUserAgent)
  | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ConnectionCount = count() by Computer, sSiteName, sPort, csUserAgent, csUserAgent_size, csUserName , csMethod, csUriStem, sIP, cIP, scStatus, scSubStatus, scWin32Status
  | where ConnectionCount < c_threshold
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
  | extend AccountName = tostring(split(csUserName, "@")[0]), AccountUPNSuffix = tostring(split(csUserName, "@")[1])
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: csUserName
      - identifier: Name
        columnName: AccountName
      - identifier: UPNSuffix
        columnName: AccountUPNSuffix
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: NTDomain
        columnName: HostNameDomain
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: cIP
version: 1.0.3
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Threat Protection" ]

Stages and Predicates

Parameters

let short_uaLength = 5;
let long_uaLength = 1000;
let c_threshold = 100;

Stage 1: source

W3CIISLog

Stage 2: where

| where cIP !startswith "192.168." and cIP != "::1"

Stage 3: where

| where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC") and (string_size(csUserAgent) <= short_uaLength or string_size(csUserAgent) >= long_uaLength)

Stage 4: extend

| extend csUserAgent_size = string_size(csUserAgent)

Stage 5: summarize

| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ConnectionCount = count() by Computer, sSiteName, sPort, csUserAgent, csUserAgent_size, csUserName , csMethod, csUriStem, sIP, cIP, scStatus, scSubStatus, scWin32Status

Stage 6: where

| where ConnectionCount < c_threshold

Stage 7: extend (3 consecutive steps)

| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend AccountName = tostring(split(csUserName, "@")[0]), AccountUPNSuffix = tostring(split(csUserName, "@")[1])

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
Computersummarize
ConnectionCountsummarize
EndTimeUtcsummarize
StartTimeUtcsummarize
cIPsummarize
csMethodsummarize
csUriStemsummarize
csUserAgentsummarize
csUserAgent_sizesummarize
csUserNamesummarize
sIPsummarize
sPortsummarize
sSiteNamesummarize
scStatussummarize
scSubStatussummarize
scWin32Statussummarize
DomainIndexextend
HostNameextend
HostNameDomainextend
AccountNameextend
AccountUPNSuffixextend