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]),"")
status: Available
triggerOperator: gt
triggerThreshold: 0
name: Detect web requests to potentially harmful files (ASIM Web Session)
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
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Session Essentials/Analytic Rules/RequestToPotentiallyHarmfulFileTypes.yaml
queryPeriod: 5m
severity: Medium
tags:
- SchemaVersion: 0.2.6
Schema: WebSession
eventGroupingSettings:
aggregationKind: AlertPerResult
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
queryFrequency: 5m
relevantTechniques:
- T1133
- T1203
- T1566
requiredDataConnectors: []
kind: Scheduled
customDetails:
EventStartTime: EventStartTime
EventEndTime: EventEndTime
EventCount: EventCount
DstIpAddr: DstIpAddr
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.'
tactics:
- InitialAccess
- Persistence
- Execution
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]),"")
id: c6608467-3678-45fe-b038-b590ce6d00fb
version: 1.0.0
{
"$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"
}
]
}