Detect web requests to potentially harmful files ASIM Web Session
Id | c6608467-3678-45fe-b038-b590ce6d00fb |
Rulename | Detect web requests to potentially harmful files (ASIM Web Session) |
Description | This rule detects web requests made to URLs containing file types such as .ps1, .bat, .vbs,.scr etc. which have the potential to be harmful if downloaded. This rule uses the Advanced Security Information Model (ASIM) and supports any web session source that complies with ASIM. |
Severity | Medium |
Tactics | InitialAccess Persistence Execution |
Techniques | T1133 T1203 T1566 |
Kind | Scheduled |
Query frequency | 5m |
Query period | 5m |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Session Essentials/Analytic Rules/RequestToPotentiallyHarmfulFileTypes.yaml |
Version | 1.0.0 |
Arm template | c6608467-3678-45fe-b038-b590ce6d00fb.json |
let lookback = 5m;
let RiskyFileExtensions = materialize(externaldata(Extensions: string)
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/RiskyFileExtensionsInUrl.csv"]
with(format="csv", ignoreFirstRecord=True));
let CustomRiskyFileExtensions = (_ASIM_GetWatchlistRaw("Web_RiskyFileExtensions") // Create new Watchlist and add your custom indicators(Optional)
| extend
Extensions = tostring(WatchlistItem["Extensions"])
| project Extensions
| where isnotempty(Extensions));
let CombinedRiskyFileExtensions = union RiskyFileExtensions, CustomRiskyFileExtensions;
let knownRiskyFileExtensions=toscalar(CombinedRiskyFileExtensions
| where isnotempty(Extensions)
| summarize make_set(Extensions, 1000));
let Whitelisted_Domains = materialize(externaldata(WhiteListedDomains: string)
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/WhiteListedDomainsForWebSessionUseCases.csv"]
with(format="csv", ignoreFirstRecord=True));
let CustomWhiteListedDomains = (_ASIM_GetWatchlistRaw("Web_WhiteListedDomains") // Create new Watchlist and add your white listed domains(Optional)
| extend
WhiteListedDomains = tostring(WatchlistItem["WhiteListedDomains"])
| project WhiteListedDomains
| where isnotempty(WhiteListedDomains));
let CombinedWhitelisted_Domains = union Whitelisted_Domains, CustomWhiteListedDomains;
let knownWhitelisted_Domains=toscalar(CombinedWhitelisted_Domains
| where isnotempty(WhiteListedDomains)
| summarize make_set(WhiteListedDomains, 1000));
_Im_WebSession (starttime=ago(lookback), url_has_any=knownRiskyFileExtensions, eventresult='Success')
| project
Url,
SrcIpAddr,
TimeGenerated,
SrcUsername,
SrcHostname,
DstIpAddr,
DstPortNumber
| extend requestedFileName=tostring(split(tostring(parse_url(Url)["Path"]), '/')[-1])
| extend requestedFileExt=extract(@'(\.\w+)$', 1, requestedFileName, typeof(string))
| where requestedFileExt in~ (knownRiskyFileExtensions)
| summarize
EventCount=count(),
EventStartTime=min(TimeGenerated),
EventEndTime=max(TimeGenerated)
by
SrcUsername,
SrcIpAddr,
SrcHostname,
DstIpAddr,
DstPortNumber,
Url,
requestedFileName
| extend FQDN = split(parse_url(Url)["Host"], '.')
| extend Domain = iif(array_length(FQDN) > 1, strcat(FQDN[-2], '.', FQDN[-1]), FQDN)
| where Domain !in~ (knownWhitelisted_Domains)
| project-away FQDN
| extend Name = iif(SrcUsername contains "@", tostring(split(SrcUsername,'@',0)[0]),SrcUsername), UPNSuffix = iif(SrcUsername contains "@",tostring(split(SrcUsername,'@',1)[0]),"")
name: Detect web requests to potentially harmful files (ASIM Web Session)
relevantTechniques:
- T1133
- T1203
- T1566
eventGroupingSettings:
aggregationKind: AlertPerResult
requiredDataConnectors: []
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Session Essentials/Analytic Rules/RequestToPotentiallyHarmfulFileTypes.yaml
query: |
let lookback = 5m;
let RiskyFileExtensions = materialize(externaldata(Extensions: string)
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/RiskyFileExtensionsInUrl.csv"]
with(format="csv", ignoreFirstRecord=True));
let CustomRiskyFileExtensions = (_ASIM_GetWatchlistRaw("Web_RiskyFileExtensions") // Create new Watchlist and add your custom indicators(Optional)
| extend
Extensions = tostring(WatchlistItem["Extensions"])
| project Extensions
| where isnotempty(Extensions));
let CombinedRiskyFileExtensions = union RiskyFileExtensions, CustomRiskyFileExtensions;
let knownRiskyFileExtensions=toscalar(CombinedRiskyFileExtensions
| where isnotempty(Extensions)
| summarize make_set(Extensions, 1000));
let Whitelisted_Domains = materialize(externaldata(WhiteListedDomains: string)
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/WhiteListedDomainsForWebSessionUseCases.csv"]
with(format="csv", ignoreFirstRecord=True));
let CustomWhiteListedDomains = (_ASIM_GetWatchlistRaw("Web_WhiteListedDomains") // Create new Watchlist and add your white listed domains(Optional)
| extend
WhiteListedDomains = tostring(WatchlistItem["WhiteListedDomains"])
| project WhiteListedDomains
| where isnotempty(WhiteListedDomains));
let CombinedWhitelisted_Domains = union Whitelisted_Domains, CustomWhiteListedDomains;
let knownWhitelisted_Domains=toscalar(CombinedWhitelisted_Domains
| where isnotempty(WhiteListedDomains)
| summarize make_set(WhiteListedDomains, 1000));
_Im_WebSession (starttime=ago(lookback), url_has_any=knownRiskyFileExtensions, eventresult='Success')
| project
Url,
SrcIpAddr,
TimeGenerated,
SrcUsername,
SrcHostname,
DstIpAddr,
DstPortNumber
| extend requestedFileName=tostring(split(tostring(parse_url(Url)["Path"]), '/')[-1])
| extend requestedFileExt=extract(@'(\.\w+)$', 1, requestedFileName, typeof(string))
| where requestedFileExt in~ (knownRiskyFileExtensions)
| summarize
EventCount=count(),
EventStartTime=min(TimeGenerated),
EventEndTime=max(TimeGenerated)
by
SrcUsername,
SrcIpAddr,
SrcHostname,
DstIpAddr,
DstPortNumber,
Url,
requestedFileName
| extend FQDN = split(parse_url(Url)["Host"], '.')
| extend Domain = iif(array_length(FQDN) > 1, strcat(FQDN[-2], '.', FQDN[-1]), FQDN)
| where Domain !in~ (knownWhitelisted_Domains)
| project-away FQDN
| extend Name = iif(SrcUsername contains "@", tostring(split(SrcUsername,'@',0)[0]),SrcUsername), UPNSuffix = iif(SrcUsername contains "@",tostring(split(SrcUsername,'@',1)[0]),"")
tactics:
- InitialAccess
- Persistence
- Execution
description: |
'This rule detects web requests made to URLs containing file types such as .ps1, .bat, .vbs,.scr etc. which have the potential to be harmful if downloaded. This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.'
entityMappings:
- fieldMappings:
- columnName: SrcIpAddr
identifier: Address
entityType: IP
- fieldMappings:
- columnName: Url
identifier: Url
entityType: URL
- fieldMappings:
- columnName: requestedFileName
identifier: Name
entityType: File
- fieldMappings:
- columnName: SrcHostname
identifier: HostName
entityType: Host
- fieldMappings:
- columnName: Name
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
entityType: Account
queryFrequency: 5m
alertDetailsOverride:
alertDescriptionFormat: User accessed URL - '{{Url}}' that contains a file - '{{requestedFileName}}' with risky extension. Downloading this file could pose a potential risk
alertDisplayNameFormat: User '{{SrcUsername}}' with IP address '{{SrcIpAddr}}' accessed a potentially harmful URL
triggerOperator: gt
version: 1.0.0
customDetails:
EventStartTime: EventStartTime
EventEndTime: EventEndTime
EventCount: EventCount
DstIpAddr: DstIpAddr
queryPeriod: 5m
status: Available
kind: Scheduled
severity: Medium
triggerThreshold: 0
id: c6608467-3678-45fe-b038-b590ce6d00fb
tags:
- Schema: WebSession
SchemaVersion: 0.2.6
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/c6608467-3678-45fe-b038-b590ce6d00fb')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/c6608467-3678-45fe-b038-b590ce6d00fb')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "User accessed URL - '{{Url}}' that contains a file - '{{requestedFileName}}' with risky extension. Downloading this file could pose a potential risk",
"alertDisplayNameFormat": "User '{{SrcUsername}}' with IP address '{{SrcIpAddr}}' accessed a potentially harmful URL"
},
"alertRuleTemplateName": "c6608467-3678-45fe-b038-b590ce6d00fb",
"customDetails": {
"DstIpAddr": "DstIpAddr",
"EventCount": "EventCount",
"EventEndTime": "EventEndTime",
"EventStartTime": "EventStartTime"
},
"description": "'This rule detects web requests made to URLs containing file types such as .ps1, .bat, .vbs,.scr etc. which have the potential to be harmful if downloaded. This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.'\n",
"displayName": "Detect web requests to potentially harmful files (ASIM Web Session)",
"enabled": true,
"entityMappings": [
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "SrcIpAddr",
"identifier": "Address"
}
]
},
{
"entityType": "URL",
"fieldMappings": [
{
"columnName": "Url",
"identifier": "Url"
}
]
},
{
"entityType": "File",
"fieldMappings": [
{
"columnName": "requestedFileName",
"identifier": "Name"
}
]
},
{
"entityType": "Host",
"fieldMappings": [
{
"columnName": "SrcHostname",
"identifier": "HostName"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Session Essentials/Analytic Rules/RequestToPotentiallyHarmfulFileTypes.yaml",
"query": "let lookback = 5m;\nlet RiskyFileExtensions = materialize(externaldata(Extensions: string)\n [@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/RiskyFileExtensionsInUrl.csv\"]\n with(format=\"csv\", ignoreFirstRecord=True));\nlet CustomRiskyFileExtensions = (_ASIM_GetWatchlistRaw(\"Web_RiskyFileExtensions\") // Create new Watchlist and add your custom indicators(Optional)\n | extend\n Extensions = tostring(WatchlistItem[\"Extensions\"])\n | project Extensions\n | where isnotempty(Extensions));\nlet CombinedRiskyFileExtensions = union RiskyFileExtensions, CustomRiskyFileExtensions;\nlet knownRiskyFileExtensions=toscalar(CombinedRiskyFileExtensions\n | where isnotempty(Extensions)\n | summarize make_set(Extensions, 1000));\nlet Whitelisted_Domains = materialize(externaldata(WhiteListedDomains: string)\n [@\"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/WhiteListedDomainsForWebSessionUseCases.csv\"]\n with(format=\"csv\", ignoreFirstRecord=True));\nlet CustomWhiteListedDomains = (_ASIM_GetWatchlistRaw(\"Web_WhiteListedDomains\") // Create new Watchlist and add your white listed domains(Optional)\n | extend\n WhiteListedDomains = tostring(WatchlistItem[\"WhiteListedDomains\"])\n | project WhiteListedDomains\n | where isnotempty(WhiteListedDomains));\nlet CombinedWhitelisted_Domains = union Whitelisted_Domains, CustomWhiteListedDomains;\nlet knownWhitelisted_Domains=toscalar(CombinedWhitelisted_Domains\n | where isnotempty(WhiteListedDomains)\n | summarize make_set(WhiteListedDomains, 1000));\n_Im_WebSession (starttime=ago(lookback), url_has_any=knownRiskyFileExtensions, eventresult='Success')\n| project\n Url,\n SrcIpAddr,\n TimeGenerated,\n SrcUsername,\n SrcHostname,\n DstIpAddr,\n DstPortNumber\n| extend requestedFileName=tostring(split(tostring(parse_url(Url)[\"Path\"]), '/')[-1])\n| extend requestedFileExt=extract(@'(\\.\\w+)$', 1, requestedFileName, typeof(string))\n| where requestedFileExt in~ (knownRiskyFileExtensions)\n| summarize\n EventCount=count(),\n EventStartTime=min(TimeGenerated),\n EventEndTime=max(TimeGenerated)\n by\n SrcUsername,\n SrcIpAddr,\n SrcHostname,\n DstIpAddr,\n DstPortNumber,\n Url,\n requestedFileName\n| extend FQDN = split(parse_url(Url)[\"Host\"], '.')\n| extend Domain = iif(array_length(FQDN) > 1, strcat(FQDN[-2], '.', FQDN[-1]), FQDN)\n| where Domain !in~ (knownWhitelisted_Domains)\n| project-away FQDN\n| extend Name = iif(SrcUsername contains \"@\", tostring(split(SrcUsername,'@',0)[0]),SrcUsername), UPNSuffix = iif(SrcUsername contains \"@\",tostring(split(SrcUsername,'@',1)[0]),\"\")\n",
"queryFrequency": "PT5M",
"queryPeriod": "PT5M",
"severity": "Medium",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Execution",
"InitialAccess",
"Persistence"
],
"tags": [
{
"Schema": "WebSession",
"SchemaVersion": "0.2.6"
}
],
"techniques": [
"T1133",
"T1203",
"T1566"
],
"templateVersion": "1.0.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}