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]),"")
severity: Medium
relevantTechniques:
- T1133
- T1203
- T1566
customDetails:
EventStartTime: EventStartTime
DstIpAddr: DstIpAddr
EventCount: EventCount
EventEndTime: EventEndTime
queryFrequency: 5m
kind: Scheduled
version: 1.0.0
name: Detect web requests to potentially harmful files (ASIM Web Session)
triggerOperator: gt
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.'
queryPeriod: 5m
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]),"")
alertDetailsOverride:
alertDisplayNameFormat: User '{{SrcUsername}}' with IP address '{{SrcIpAddr}}' accessed a potentially harmful URL
alertDescriptionFormat: User accessed URL - '{{Url}}' that contains a file - '{{requestedFileName}}' with risky extension. Downloading this file could pose a potential risk
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
tactics:
- InitialAccess
- Persistence
- Execution
status: Available
triggerThreshold: 0
tags:
- Schema: WebSession
SchemaVersion: 0.2.6
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Session Essentials/Analytic Rules/RequestToPotentiallyHarmfulFileTypes.yaml
eventGroupingSettings:
aggregationKind: AlertPerResult
id: c6608467-3678-45fe-b038-b590ce6d00fb
requiredDataConnectors: []
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2023-02-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",
"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"
}
]
}