← Back to SOC feed Coverage →

Rare User Agent strings

kql LOW Azure-Sentinel
T1190
W3CIISLog
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-06-04T23:00:00Z · Confidence: medium

Hunt Hypothesis

Unusual User Agent strings detected in recent traffic may indicate reconnaissance activities targeting IIS servers. SOC teams should proactively hunt for these patterns to identify potential adversary probing before exploitation occurs.

KQL Query


W3CIISLog
//Exclude local addresses, using ipv4_is_private operator
|where ipv4_is_private(cIP) == false and  cIP !startswith "fe80" and cIP !startswith "::" and cIP !startswith "127."  
| where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC")
| extend csUserAgent_size = string_size(csUserAgent)
| project TimeGenerated, sSiteName, sPort, csUserAgent, csUserAgent_size, csUserName , csMethod, csUriStem, sIP, cIP, scStatus, 
scSubStatus, scWin32Status, csHost 
| join (
    W3CIISLog
	  // The below line can be used to exclude local IPs if these create noise
    |where ipv4_is_private(cIP) == false and  cIP !startswith "fe80" and cIP !startswith "::" and cIP !startswith "127."  
    | where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC") 
    | extend csUserAgent_size = string_size(csUserAgent)
    | summarize csUserAgent_count = count() by bin(csUserAgent_size, 1)
    | top 20 by csUserAgent_count asc nulls last 
) on csUserAgent_size
| project TimeGenerated, sSiteName, sPort, sIP, cIP, csUserAgent, csUserAgent_size, csUserAgent_count, csUserName , csMethod, csUriStem, 
scStatus, scSubStatus, scWin32Status, csHost
| extend timestamp = TimeGenerated, IPCustomEntity = cIP, HostCustomEntity = csHost, AccountCustomEntity = csUserName 

Analytic Rule Definition

id: 3de523b5-9608-43d5-801e-732c741dd82e
name: Rare User Agent strings
description: |
  'This will check for Rare User Agent strings over the last 3 days.  This can indicate potential probing of your IIS servers.'
severity: Low
requiredDataConnectors:
  - connectorId: AzureMonitor(IIS)
    dataTypes:
      - W3CIISLog
tactics:
  - InitialAccess
relevantTechniques:
  - T1190
query: |

  W3CIISLog
  //Exclude local addresses, using ipv4_is_private operator
  |where ipv4_is_private(cIP) == false and  cIP !startswith "fe80" and cIP !startswith "::" and cIP !startswith "127."  
  | where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC")
  | extend csUserAgent_size = string_size(csUserAgent)
  | project TimeGenerated, sSiteName, sPort, csUserAgent, csUserAgent_size, csUserName , csMethod, csUriStem, sIP, cIP, scStatus, 
  scSubStatus, scWin32Status, csHost 
  | join (
      W3CIISLog
  	  // The below line can be used to exclude local IPs if these create noise
      |where ipv4_is_private(cIP) == false and  cIP !startswith "fe80" and cIP !startswith "::" and cIP !startswith "127."  
      | where isnotempty(csUserAgent) and csUserAgent !in~ ("-", "MSRPC") 
      | extend csUserAgent_size = string_size(csUserAgent)
      | summarize csUserAgent_count = count() by bin(csUserAgent_size, 1)
      | top 20 by csUserAgent_count asc nulls last 
  ) on csUserAgent_size
  | project TimeGenerated, sSiteName, sPort, sIP, cIP, csUserAgent, csUserAgent_size, csUserAgent_count, csUserName , csMethod, csUriStem, 
  scStatus, scSubStatus, scWin32Status, csHost
  | extend timestamp = TimeGenerated, IPCustomEntity = cIP, HostCustomEntity = csHost, AccountCustomEntity = csUserName 
version: 1.0.0
metadata:
    source:
        kind: Community
    author:
        name: Shain
    support:
        tier: Community
    categories:
        domains: [ "Security - Other" ]

Required Data Sources

Sentinel TableNotes
W3CIISLogEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/W3CIISLog/RareUserAgentStrings.yaml