Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions .script/tests/KqlvalidationsTests/CustomTables/AWSWAF.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"Name": "AWSWAF",
"Properties": [
{
"name": "TenantId",
"type": "String"
},
{
"name": "Action",
"type": "String"
},
{
"name": "Args",
"type": "String"
},
{
"name": "CaptchaResponse",
"type": "Object"
},
{
"name": "ChallengeResponse",
"type": "Object"
},
{
"name": "ClientIp",
"type": "String"
},
{
"name": "Country",
"type": "String"
},
{
"name": "ExcludedRules",
"type": "Object"
},
{
"name": "FormatVersion",
"type": "String"
},
{
"name": "Headers",
"type": "Object"
},
{
"name": "HttpMethod",
"type": "String"
},
{
"name": "HttpRequest",
"type": "Object"
},
{
"name": "HttpSourceId",
"type": "String"
},
{
"name": "HttpSourceName",
"type": "String"
},
{
"name": "HttpVersion",
"type": "String"
},
{
"name": "Ja3Fingerprint",
"type": "String"
},
{
"name": "Labels",
"type": "Object"
},
{
"name": "NonTerminatingMatchingRules",
"type": "Object"
},
{
"name": "OversizeFields",
"type": "Object"
},
{
"name": "RateBasedRuleList",
"type": "Object"
},
{
"name": "RequestHeadersInserted",
"type": "Object"
},
{
"name": "RequestId",
"type": "String"
},
{
"name": "ResponseCodeSent",
"type": "Int32"
},
{
"name": "RuleGroupId",
"type": "String"
},
{
"name": "RuleGroupList",
"type": "Object"
},
{
"name": "TerminatingRule",
"type": "Object"
},
{
"name": "TerminatingRuleId",
"type": "String"
},
{
"name": "TerminatingRuleMatchDetails",
"type": "Object"
},
{
"name": "TerminatingRuleType",
"type": "String"
},
{
"name": "TimeGenerated",
"type": "DateTime"
},
{
"name": "Uri",
"type": "String"
},
{
"name": "WebAclId",
"type": "String"
},
{
"name": "SourceSystem",
"type": "String"
},
{
"name": "Type",
"type": "String"
},
{
"name": "_ItemId",
"type": "String"
}
Comment thread
manuelhauch marked this conversation as resolved.
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"displayName": "Web Session ASIM parser",
"category": "ASIM",
"FunctionAlias": "ASimWebSession",
"query": "let DisabledParsers=materialize(_GetWatchlist('ASimDisabledParsers') | where SearchKey in ('Any', 'ExcludeASimWebSession') | extend SourceSpecificParser=column_ifexists('SourceSpecificParser','') | distinct SourceSpecificParser| where isnotempty(SourceSpecificParser));\nlet ASimBuiltInDisabled=toscalar('ExcludeASimWebSession' in (DisabledParsers) or 'Any' in (DisabledParsers)); \nlet parser=(pack:bool=false){\nunion isfuzzy=true\n vimWebSessionEmpty,\n ASimWebSessionSquidProxy (ASimBuiltInDisabled or ('ExcludeASimWebSessionSquidProxy' in (DisabledParsers))),\n ASimWebSessionZscalerZIA (ASimBuiltInDisabled or ('ExcludeASimWebSessionZscalerZIA' in (DisabledParsers))),\n ASimWebSessionNative (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionNative' in (DisabledParsers)))),\n ASimWebSessionVectraAI (pack=pack, disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionVectraAI' in (DisabledParsers)))),\n ASimWebSessionIIS (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionIIS' in (DisabledParsers)))),\n ASimWebSessionPaloAltoCEF (ASimBuiltInDisabled or ('ExcludeASimWebSessionPaloAltoCEF' in (DisabledParsers))),\n ASimWebSessionApacheHTTPServer (ASimBuiltInDisabled or ('ExcludeASimWebSessionApacheHTTPServer' in (DisabledParsers))),\n ASimWebSessionFortinetFortiGate (ASimBuiltInDisabled or ('ExcludeASimWebSessionFortinetFortiGate' in (DisabledParsers))),\n ASimWebSessionCiscoMeraki (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoMeraki' in (DisabledParsers))),\n ASimWebSessionBarracudaWAF (ASimBuiltInDisabled or ('ExcludeASimWebSessionBarracudaWAF' in (DisabledParsers))),\n ASimWebSessionBarracudaCEF (ASimBuiltInDisabled or ('ExcludeASimWebSessionBarracudaCEF' in (DisabledParsers))),\n ASimWebSessionCitrixNetScaler (ASimBuiltInDisabled or ('ExcludeASimWebSessionCitrixNetScaler' in (DisabledParsers))),\n ASimWebSessionCiscoFirepower (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoFirepower' in (DisabledParsers))),\n ASimWebSessionF5ASM (ASimBuiltInDisabled or ('ExcludeASimWebSessionF5ASM' in (DisabledParsers))),\n ASimWebSessionPaloAltoCortexDataLake (ASimBuiltInDisabled or ('ExcludeASimWebSessionPaloAltoCortexDataLake' in (DisabledParsers))),\n ASimWebSessionSonicWallFirewall (ASimBuiltInDisabled or ('ExcludeASimWebSessionSonicWallFirewall' in (DisabledParsers))),\n ASimWebSessionAzureFirewall (ASimBuiltInDisabled or ('ExcludeASimWebSessionAzureFirewall' in (DisabledParsers))),\n ASimWebSessionCiscoUmbrella (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoUmbrella' in (DisabledParsers)),pack=pack),\n ASimWebSessionSalesforceServiceCloudV2 (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionSalesforceServiceCloudV2' in (DisabledParsers))), pack=pack)\n}; \nparser(pack=pack)\n",
"query": "let DisabledParsers=materialize(_GetWatchlist('ASimDisabledParsers') | where SearchKey in ('Any', 'ExcludeASimWebSession') | extend SourceSpecificParser=column_ifexists('SourceSpecificParser','') | distinct SourceSpecificParser| where isnotempty(SourceSpecificParser));\nlet ASimBuiltInDisabled=toscalar('ExcludeASimWebSession' in (DisabledParsers) or 'Any' in (DisabledParsers));\nlet parser=(pack:bool=false){\nunion isfuzzy=true\n vimWebSessionEmpty,\n ASimWebSessionSquidProxy (ASimBuiltInDisabled or ('ExcludeASimWebSessionSquidProxy' in (DisabledParsers))),\n ASimWebSessionZscalerZIA (ASimBuiltInDisabled or ('ExcludeASimWebSessionZscalerZIA' in (DisabledParsers))),\n ASimWebSessionNative (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionNative' in (DisabledParsers)))),\n ASimWebSessionVectraAI (pack=pack, disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionVectraAI' in (DisabledParsers)))),\n ASimWebSessionIIS (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionIIS' in (DisabledParsers)))),\n ASimWebSessionPaloAltoCEF (ASimBuiltInDisabled or ('ExcludeASimWebSessionPaloAltoCEF' in (DisabledParsers))),\n ASimWebSessionApacheHTTPServer (ASimBuiltInDisabled or ('ExcludeASimWebSessionApacheHTTPServer' in (DisabledParsers))),\n ASimWebSessionFortinetFortiGate (ASimBuiltInDisabled or ('ExcludeASimWebSessionFortinetFortiGate' in (DisabledParsers))),\n ASimWebSessionCiscoMeraki (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoMeraki' in (DisabledParsers))),\n ASimWebSessionBarracudaWAF (ASimBuiltInDisabled or ('ExcludeASimWebSessionBarracudaWAF' in (DisabledParsers))),\n ASimWebSessionBarracudaCEF (ASimBuiltInDisabled or ('ExcludeASimWebSessionBarracudaCEF' in (DisabledParsers))),\n ASimWebSessionCitrixNetScaler (ASimBuiltInDisabled or ('ExcludeASimWebSessionCitrixNetScaler' in (DisabledParsers))),\n ASimWebSessionCiscoFirepower (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoFirepower' in (DisabledParsers))),\n ASimWebSessionF5ASM (ASimBuiltInDisabled or ('ExcludeASimWebSessionF5ASM' in (DisabledParsers))),\n ASimWebSessionPaloAltoCortexDataLake (ASimBuiltInDisabled or ('ExcludeASimWebSessionPaloAltoCortexDataLake' in (DisabledParsers))),\n ASimWebSessionSonicWallFirewall (ASimBuiltInDisabled or ('ExcludeASimWebSessionSonicWallFirewall' in (DisabledParsers))),\n ASimWebSessionAzureFirewall (ASimBuiltInDisabled or ('ExcludeASimWebSessionAzureFirewall' in (DisabledParsers))),\n ASimWebSessionCiscoUmbrella (ASimBuiltInDisabled or ('ExcludeASimWebSessionCiscoUmbrella' in (DisabledParsers)),pack=pack),\n ASimWebSessionSalesforceServiceCloudV2 (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionSalesforceServiceCloudV2' in (DisabledParsers))), pack=pack),\n ASimWebSessionAWSWAF (disabled=(ASimBuiltInDisabled or ('ExcludeASimWebSessionAWSWAF' in (DisabledParsers))), pack=pack)\n};\nparser(pack=pack)\n",
"version": 1,
"functionParameters": "pack:bool=False"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"Workspace": {
"type": "string",
"metadata": {
"description": "The Microsoft Sentinel workspace into which the function will be deployed. Has to be in the selected Resource Group."
}
},
"WorkspaceRegion": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The region of the selected workspace. The default value will use the Region selection above."
}
}
},
"resources": [
{
"type": "Microsoft.OperationalInsights/workspaces/savedSearches",
"apiVersion": "2020-08-01",
"name": "[concat(parameters('Workspace'), '/ASimWebSessionAWSWAF')]",
"location": "[parameters('WorkspaceRegion')]",
"properties": {
"etag": "*",
"displayName": "Web Session ASIM parser for AWS Web Application Firewall",
"category": "ASIM",
"FunctionAlias": "ASimWebSessionAWSWAF",
"query": "let parser = (\n disabled:bool=false,\n pack:bool=false\n)\n{\n //According to AWS documentation: https://docs.aws.amazon.com/waf/latest/developerguide/logging-fields.html\n let ActionLookup = datatable(Action:string, DvcAction:string, EventResult:string, EventSeverity:string)\n [\n 'ALLOW', 'Allow', 'Success', 'Informational',\n 'BLOCK', 'Deny', 'Failure', 'Low',\n 'CAPTCHA', 'Deny', 'Failure', 'Low',\n 'CHALLENGE', 'Deny', 'Failure', 'Low',\n '', '', 'NA', 'Informational'\n ];\n AWSWAF\n | where not(disabled)\n //Mandatory common fields\n | extend\n EventCount = int(1),\n EventStartTime = TimeGenerated,\n EventEndTime = TimeGenerated,\n EventType = 'HTTPsession',\n EventVendor = 'AWS',\n EventProduct = 'WAF',\n EventSchema = 'WebSession',\n EventSchemaVersion = '0.2.7'\n | extend Dvc = coalesce(WebAclId, strcat(EventVendor, '/', EventProduct))\n | lookup ActionLookup on Action\n //Recommended common fields\n | extend DvcId = Dvc,\n DvcIdType = 'Other',\n EventUid = _ItemId\n | project-rename DvcOriginalAction = Action\n // AWS WAF populates ResponseCodeSent only when a custom block response is configured; the field is empty for allowed requests and default-response blocks.\n | extend EventResultDetails = tostring(ResponseCodeSent)\n | extend HttpStatusCode = EventResultDetails\n //HTTP session fields\n | extend parsedRequest = parse_json(HttpRequest)\n //Network Source fields\n | extend SrcIpAddr = tostring(parsedRequest.clientIp),\n Src = tostring(parsedRequest.clientIp),\n SrcGeoCountry = tostring(parsedRequest.country)\n | extend headers = iff(array_length(parsedRequest.headers) > 0, parsedRequest.headers, dynamic([{}]))\n | mv-apply header = headers on (\n summarize\n HttpHost = take_anyif(tostring(header.value), tostring(header.name) =~ 'host'),\n HttpUserAgent = take_anyif(tostring(header.value), tostring(header.name) =~ 'user-agent'),\n HttpReferrer = take_anyif(tostring(header.value), tostring(header.name) =~ 'referer'),\n HttpCookie = take_anyif(tostring(header.value), tostring(header.name) =~ 'Cookie'),\n HttpRequestXff = take_anyif(tostring(header.value), tostring(header.name) =~ 'X-Forwarded-For')\n )\n | extend\n scheme = tostring(parsedRequest.scheme),\n host = coalesce(tostring(parsedRequest.host), HttpHost),\n uri = tostring(parsedRequest.uri),\n args = tostring(parsedRequest.args)\n | extend Url = case(\n isnotempty(scheme) and isnotempty(host),\n strcat(scheme, '://', host, uri, iff(isnotempty(args), strcat('?', args), '')),\n isnotempty(host),\n strcat(host, uri, iff(isnotempty(args), strcat('?', args), '')),\n uri\n ),\n HttpVersion = tostring(parsedRequest.httpVersion),\n HttpRequestMethod = tostring(parsedRequest.httpMethod),\n HttpRequestHeaderCount = toint(array_length(parsedRequest.headers)),\n UserAgent = HttpUserAgent\n //Network session fields\n | extend NetworkApplicationProtocol = toupper(scheme),\n NetworkSessionId = tostring(parsedRequest.requestId)\n //Network destination fields\n | project-rename DstDvcId = HttpSourceId\n | extend DstDvcIdType = 'Other',\n DstPortNumber = case(\n scheme =~ 'https', toint(443),\n scheme =~ 'http', toint(80),\n int(null)\n )\n // Normalize: unwrap bracketed IPv6 [::1]:443 -> ::1 ; strip :port from host:port (but not from bare IPv6)\n | extend _hostNoPort = case(\n host startswith '[', extract(@'^\\[(.+?)\\]', 1, host), // [IPv6] or [IPv6]:port\n host matches regex @'^[^:]+:\\d+$', tostring(split(host, ':')[0]), // host:port (single colon + digits)\n host // bare host or bare IPv6\n )\n | extend _hostIsIp =\n isnotnull(parse_ipv4(_hostNoPort))\n or (_hostNoPort contains ':' and isnotnull(parse_ipv6(_hostNoPort)))\n | extend _hostIsIpShaped =\n _hostIsIp\n or _hostNoPort matches regex @'^\\d{1,3}(\\.\\d{1,3}){3}$' // padded/oversized dotted-quads e.g. 083.130.061.x\n | extend _hostIsClean = _hostNoPort matches regex @'^[A-Za-z0-9\\.\\-\\_]+$' or _hostIsIp\n | extend _hostHasDomain = _hostIsClean and not(_hostIsIpShaped) and array_length(split(_hostNoPort, '.')) > 1\n | extend\n DstIpAddr = iff(_hostIsIp, _hostNoPort, ''), // strict: only real IPs\n DstHostname = case(\n _hostIsIp, _hostNoPort, // valid IP; keep\n _hostIsIpShaped, '', // IP-shaped junk is blank, not a fake hostname\n _hostIsClean, tostring(split(_hostNoPort, '.')[0]),\n ''\n ),\n DstFQDN = iff(_hostHasDomain, _hostNoPort, ''),\n DstDomain = iff(_hostHasDomain, strcat_array(array_slice(split(_hostNoPort, '.'), 1, -1), '.'), '')\n | extend DstDomainType = iff(isnotempty(DstDomain), 'FQDN', '')\n //Network Inspection fields\n | project-rename RuleName = TerminatingRuleId\n //Additional, non-normalized fields\n | extend AdditionalFields = iff(\n pack,\n bag_pack(\n 'HttpSourceName', HttpSourceName,\n 'TerminatingRuleType', TerminatingRuleType,\n 'TerminatingRuleMatchDetails', TerminatingRuleMatchDetails,\n 'RuleGroupList', RuleGroupList,\n 'RateBasedRuleList', RateBasedRuleList,\n 'Labels', Labels,\n 'JA3', Ja3Fingerprint\n ),\n dynamic({})\n )\n //Aliases\n | extend\n IpAddr = SrcIpAddr,\n Hostname = DstHostname,\n Dst = DstDvcId,\n EventOriginalUid = NetworkSessionId,\n SessionId = NetworkSessionId,\n Rule = RuleName\n //Select fields\n | project\n // -- Mandatory\n TimeGenerated,\n EventCount,\n EventStartTime,\n EventEndTime,\n EventType,\n EventResult,\n EventProduct,\n EventVendor,\n EventSchema,\n EventSchemaVersion,\n Dvc,\n Url,\n Dst,\n // -- Recommended\n EventResultDetails,\n EventSeverity,\n EventUid,\n DvcAction,\n DvcOriginalAction,\n DvcId,\n DvcIdType,\n HttpRequestMethod,\n HttpStatusCode,\n DstHostname,\n SrcIpAddr,\n // -- Event optional\n EventOriginalUid,\n // -- HTTP optional\n HttpVersion,\n HttpRequestHeaderCount,\n HttpHost,\n HttpUserAgent,\n HttpReferrer,\n HttpCookie,\n HttpRequestXff,\n // -- Destination optional\n DstDvcId,\n DstDvcIdType,\n DstIpAddr,\n DstPortNumber,\n DstFQDN,\n DstDomain,\n DstDomainType,\n // -- Source optional\n SrcGeoCountry,\n // -- Network fields\n NetworkApplicationProtocol,\n NetworkSessionId,\n // -- Inspection fields\n RuleName,\n Rule,\n // -- Additional\n AdditionalFields,\n // -- Aliases\n IpAddr,\n UserAgent,\n Hostname,\n SessionId,\n Src,\n // -- Source table\n Type\n};\nparser(\n disabled=disabled,\n pack=pack\n)\n",
"version": 1,
"functionParameters": "disabled:bool=False,pack:bool=False"
}
}
]
}
21 changes: 21 additions & 0 deletions Parsers/ASimWebSession/ARM/ASimWebSessionAWSWAF/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# AWS WAF ASIM WebSession Normalization Parser

ARM template for ASIM WebSession schema parser for AWS WAF.

This ASIM parser supports normalizing AWS Web Application Firewall (WAF) web session logs from the AWSWAF table to the ASIM Web Session normalized schema.


The Advanced Security Information Model (ASIM) enables you to use and create source-agnostic content, simplifying your analysis of the data in your Microsoft Sentinel workspace.

For more information, see:

- [Normalization and the Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM)
- [Deploy all of ASIM](https://aka.ms/DeployASIM)
- [ASIM WebSession normalization schema reference](https://aka.ms/ASimWebSessionDoc)

For the changelog, see:
- [CHANGELOG](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/ASimWebSession/CHANGELOG/ASimWebSessionAWSWAF.md)

<br>

[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FParsers%2FASimWebSession%2FARM%2FASimWebSessionAWSWAF%2FASimWebSessionAWSWAF.json) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FParsers%2FASimWebSession%2FARM%2FASimWebSessionAWSWAF%2FASimWebSessionAWSWAF.json)
Loading
Loading