A host is potentially using PowerShell to exfiltrate data via HTTP(S) requests by伪装 as a legitimate user agent. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect adversarial activity leveraging PowerShell for command and control or data exfiltration.
KQL Query
let threatCategory="Powershell";
let knownUserAgentsIndicators = materialize(externaldata(UserAgent:string, Category:string)
[ @"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/UnusualUserAgents.csv"]
with(format="csv", ignoreFirstRecord=True));
let knownUserAgents=toscalar(knownUserAgentsIndicators | where Category==threatCategory | where isnotempty(UserAgent) | summarize make_list(UserAgent));
let customUserAgents=toscalar(_GetWatchlist("UnusualUserAgents") | where SearchKey==threatCategory | extend UserAgent=column_ifexists("UserAgent","") | where isnotempty(UserAgent) | summarize make_list(UserAgent));
let fullUAList = array_concat(knownUserAgents,customUserAgents);
_Im_WebSession(httpuseragent_has_any=fullUAList)
| project SrcIpAddr, Url, TimeGenerated, HttpUserAgent, SrcUsername
| extend AccountName = tostring(split(SrcUsername, "@")[0]), AccountUPNSuffix = tostring(split(SrcUsername, "@")[1])
id: 42436753-9944-4d70-801c-daaa4d19ddd2
name: A host is potentially running PowerShell to send HTTP(S) requests (ASIM Web Session schema)
description: |
'This rule identifies a web request with a user agent header known to belong PowerShell. <br>You can add custom Powershell indicating User-Agent headers using a watchlist, for more information refer to the [UnusualUserAgents Watchlist](https://aka.ms/ASimUnusualUserAgentsWatchlist).<br><br>
This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM WebSession schema (ASIM WebSession Schema)'
severity: Medium
tags:
- ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/CiscoUmbrella/CiscoUmbrellaPowershellUserAgentDetected.yaml
version: 1.0.0
- Schema: ASimWebSession
SchemaVersion: 0.2.1
requiredDataConnectors:
- connectorId: SquidProxy
dataTypes:
- SquidProxy_CL
- connectorId: Zscaler
dataTypes:
- CommonSecurityLog
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
- DefenseEvasion
- Execution
relevantTechniques:
- T1132
- T1140
- T1059.001
query: |
let threatCategory="Powershell";
let knownUserAgentsIndicators = materialize(externaldata(UserAgent:string, Category:string)
[ @"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/UnusualUserAgents.csv"]
with(format="csv", ignoreFirstRecord=True));
let knownUserAgents=toscalar(knownUserAgentsIndicators | where Category==threatCategory | where isnotempty(UserAgent) | summarize make_list(UserAgent));
let customUserAgents=toscalar(_GetWatchlist("UnusualUserAgents") | where SearchKey==threatCategory | extend UserAgent=column_ifexists("UserAgent","") | where isnotempty(UserAgent) | summarize make_list(UserAgent));
let fullUAList = array_concat(knownUserAgents,customUserAgents);
_Im_WebSession(httpuseragent_has_any=fullUAList)
| project SrcIpAddr, Url, TimeGenerated, HttpUserAgent, SrcUsername
| extend AccountName = tostring(split(SrcUsername, "@")[0]), AccountUPNSuffix = tostring(split(SrcUsername, "@")[1])
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: Url
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: SrcUsername
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
alertDetailsOverride:
alertDisplayNameFormat: 'Host {{SrcIpAddr}} is potentially running PowerShell'
alertDescriptionFormat: 'The host at address {{SrcIpAddr}} sent an HTTP request to the URL {{Url}} with the HTTP user agent header {{HttpUserAgent}}. This user agent is known to be used by PowerShell and indicates suspicious activity on the host.'
customDe
Scenario: Scheduled PowerShell Task Using Invoke-WebRequest
Description: A legitimate scheduled task runs a PowerShell script that uses Invoke-WebRequest to fetch updates from a known internal server.
Filter/Exclusion: Exclude requests to internal IP ranges (e.g., 10.0.0.0/8) or specific internal domains (e.g., internal-update.example.com).
Scenario: Admin Using PowerShell to Test Connectivity
Description: An admin uses PowerShell to test connectivity to a web service using Test-NetConnection or Invoke-WebRequest for troubleshooting.
Filter/Exclusion: Exclude traffic originating from admin workstations (e.g., user = admin_user) or to known internal diagnostic endpoints.
Scenario: PowerShell Module Installation via HTTP
Description: A system administrator installs a PowerShell module from a private repository using Install-Module or Save-Module.
Filter/Exclusion: Exclude traffic to private module repositories (e.g., modules.example.com) or requests with specific module names (e.g., PSReadLine, PoshRSJob).
Scenario: PowerShell Script Running on a CI/CD Pipeline
Description: A CI/CD pipeline runs a PowerShell script that communicates with a build server or artifact repository to fetch dependencies.
Filter/Exclusion: Exclude traffic from known CI/CD agents (e.g., agent-01.build.example.com) or to specific artifact endpoints (e.g., artifacts.example.com).
Scenario: PowerShell Used for Internal Monitoring or Logging
Description: A monitoring tool or logging system uses PowerShell to send HTTP requests to a central log aggregation service (e.g., ELK, Splunk).
Filter/Exclusion: Exclude traffic to log aggregation services (e.g., logs.example.com)