Merge pull request #1318 from vaniMSTIC/vaasawa-mstic

Create MaliciousWAFSessions.yaml
This commit is contained in:
Shain 2020-11-23 07:48:17 -08:00 коммит произвёл GitHub
Родитель 48912a334b d47acc4e96
Коммит 30d61e126d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 63 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,63 @@
id: 46ac55ae-47b8-414a-8f94-89ccd1962178
name: A potentially malicious web request was executed against a web server
description: |
'Detects unobstructed Web Applicatio Firewall (WAF) activity in sessions where the WAF blocked incoming requests by computing the
ratio between blocked requests and unobstructed WAF requests in these sessions (BlockvsSuccessRatio metric). A high ratio value for
a given client IP and hostname calls for further investigation of the WAF data in that session, due to the significantly high number
of blocked requests and a few unobstructed logs which may be malicious but have passed undetected through the WAF. The successCode
variable defines what the detection thinks is a successful status code, and should be altered to fit the environment.'
severity: Medium
requiredDataConnectors:
- connectorId: WAF
dataTypes:
- AzureDiagnostics
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1190
query: |
let mode = 'Blocked';
let successCode = dynamic(['200', '101','204', '400','504','304','401','500']);
let minTime = ago(1d);
let maxSessionWindow = 1h;
let sessionBin = maxSessionWindow/2.0;
AzureDiagnostics
| where TimeGenerated > minTime
| where Category == 'ApplicationGatewayFirewallLog'
| where action_s == mode
| sort by hostname_s asc, clientIp_s asc, TimeGenerated asc
| extend SessionStarted = row_window_session(TimeGenerated, maxSessionWindow, 10m, ((clientIp_s != prev(clientIp_s)) or (hostname_s != prev(hostname_s))))
| summarize minTime = min(TimeGenerated), maxTime = max(TimeGenerated), SessionBlockedCount=count() by hostname_s, clientIp_s, SessionStarted
| extend duration = maxTime - minTime
| extend TimeKey = bin(SessionStarted, sessionBin)
| join kind = inner(
AzureDiagnostics
| where TimeGenerated > minTime
| where Category == 'ApplicationGatewayAccessLog'
| where httpStatus_d in (successCode) or isempty(httpStatus_d)
| extend TimeKey = range(bin(TimeGenerated-maxSessionWindow, sessionBin), bin(TimeGenerated, sessionBin), sessionBin)
| mv-expand TimeKey to typeof(datetime)
) on $left.hostname_s == $right.host_s, $left.clientIp_s == $right.clientIP_s, TimeKey
| where (TimeGenerated - SessionStarted) between (0m .. duration)
| extend originalRequestUriWithArgs_s = column_ifexists("originalRequestUriWithArgs_s", "")
| extend serverStatus_s = column_ifexists("serverStatus_s", "")
| extend timestamp = SessionStarted, IPCustomEntity = clientIP_s
| summarize SuccessfulAccessLogCount = count(), UserAgents = make_set(userAgent_s), RequestURIs = make_set(requestUri_s) , OriginalRequestURIs = make_set(originalRequestUriWithArgs_s),
SuccessCodes = make_set(httpStatus_d), SuccessCodes_BackendServer = make_set(serverStatus_s) by timestamp, hostname_s, IPCustomEntity, SessionBlockedCount
| extend BlockvsSuccessRatio = SessionBlockedCount/SuccessfulAccessLogCount
| sort by BlockvsSuccessRatio desc, timestamp asc
| where SessionBlockedCount > SuccessfulAccessLogCount
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
- entityType: DNS
fieldMappings:
- identifier: HostIpAddress
columnName: hostname_s