Skip to content

Instantly share code, notes, and snippets.

View TheCloudScout's full-sized avatar

Koos Goossens TheCloudScout

View GitHub Profile
@TheCloudScout
TheCloudScout / azure-firewall-log4j-kql
Last active December 13, 2021 14:15
Azure Firewall | Check log4j IoCs
let timeWindow = datetime("2021-12-09");
let intel = ((externaldata (URL:string,values: dynamic) [@"https://gist.githubusercontent.com/superducktoes/9b742f7b44c71b4a0d19790228ce85d8/raw/f1751cc072bd33256c0005021f33348c22aa76fc/Callback%2520Domains%2520log4j"]));
let IPList = externaldata(IPAddress:string)[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/Log4j_IOC_List.csv"] with (format="csv", ignoreFirstRecord=True);
let domains = intel | extend domains=extract(@"([0-9a-z]+\.[0-9a-z]+\.[a-z]+)",0,URL)| distinct domains| where domains != "" | project domains;
let ips = intel | extend ips=extract(@"([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})",0,URL) | distinct ips | where ips != "" | project ips;
let ports = intel | extend ports=extract(@":([0-9]{2,5})\/",1,URL) | distinct ports | where ports != "" | project ports;
// to parse Azure Firewall logs with "AzureFirewallApplicationRule" category, we need several different parsing methods based on the type of entries
let appl
"Country: United States City: Chicago Local dish: Deep dish pizza",
"City: New York City Attraction: Statue of Liberty Local dish: Cheesecake",
"Country: United States State: NV Population: 641903 Attraction: Fremont Street",
"State: CA City:San Francisco Population: 873965 Attraction: Golden Gate Bridge Local dish: Clam Chowder"
let unparsedData = datatable( string_:string )
[
"Country: United States City: Chicago Local dish: Deep dish pizza",
"City: New York City Attraction: Statue of Liberty Local dish: Cheesecake",
"Country: United States State: NV Population: 641903 Attraction: Fremont Street",
"State: CA City:San Francisco Population: 873965 Attraction: Golden Gate Bridge Local dish: Clam Chowder"
];
let parser1 = unparsedData
| parse-where string_ with *
"Country: " country:string
let unparsedData = datatable( string_:string )
[
"Country: United States City: Chicago Local dish: Deep dish pizza",
"City: New York City Attraction: Statue of Liberty Local dish: Cheesecake",
"Country: United States State: NV Population: 641903 Attraction: Fremont Street",
"State: CA City:San Francisco Population: 873965 Attraction: Golden Gate Bridge Local dish: Clam Chowder"
];
let parser1 = unparsedData
| where string_ has_all("Country:", "City:", "dish:")
| parse-where string_ with *
let AzureFirewallApplicationRulesLogsSample = datatable( msg_s:string )
[
"HTTP request from 10.0.0.1:50776 to ocsp.msocsp.com:80. Url: ocsp.msocsp.com/MFQ=. Action: Allow. Policy: azfwpolicy-nbfw-prd-weeu-01. Rule Collection Group: DefaultApplicationRuleCollectionGroup. Rule Collection: generic-allow-500. Rule: Azure-to-AllowedServices, HTTP",
"HTTPS request from 10.0.0.1:49553 to guestconfiguration.azure.com:443. Action: Allow. Policy: azfwpolicy-nbfw-prd-weeu-01. Rule Collection Group: DefaultApplicationRuleCollectionGroup. Rule Collection: enablement-genericwebcategory-prd-allow-200. Rule: Allowed Business-Use Webcategories. Web Category: ComputersAndTechnology",
"HTTP request from 10.0.0.1:53717 to ocsp.usertrust.com:80. Url: ocsp.usertrust.com/MFEk=. Action: Deny. No rule matched. Proceeding with default action",
"HTTPS request from 10.0.0.1:62773 to settings-win.data.microsoft.com:443. Action: Deny. No rule matched. Proceeding with default action",
"HTTPS request from 10.0.0.1:590
let AzureFirewallNetworkRulesLogsSample = datatable( msg_s:string )
[
"ICMP Type=8 request from 10.0.0.1 to 10.0.0.2. Action: Allow.",
"TCP request from 10.0.0.1:56088 to 10.0.0.2:443. Action: Allow.",
"HTTP request from 10.0.0.1:62504 to ocsp.sca1b.amazontrust.com:80. Url: ocsp.sca1b.amazontrust.com/MFE=. Action: Deny. ThreatIntel: Bot Networks",
"HTTPS request from 10.0.0.1:53415 to tags.bluekai.com:443. Action: Deny. ThreatIntel: Phishing Url",
"ICMP request from 10.0.0.1: to 10.0.0.2:. Action: alert. Signature: 2100366. IDS: ICMP_INFO PING *NIX. Priority: 3. Classification: Misc activity"
];
//
// This parser with pars string messages in the "msg_s" colomn provided by Azure Firewall diagnostics logs.
// Due to the native of these logs it's impossible to parse all data with a single "parse" statement
// Because there are six different parsers needed all data is deviced into their respective parser type by
// using parse-where sometime in conjuction with an addition "where" statement to prevent duplicates
//
// Created by Koos Goossens @ Wortell Last updated: January 10th 2022
//
let AzureFirewallApplicationRuleLogs = AzureDiagnostics
| where OperationName == "AzureFirewallApplicationRuleLog";
//
// This parser with pars string messages in the "msg_s" colomn provided by Azure Firewall diagnostics logs.
// Due to the native of these logs it's impossible to parse all data with a single "parse" statement
// Because there are six different parsers needed all data is deviced into their respective parser type by
// using parse-where sometime in conjuction with an addition "where" statement to prevent duplicates
//
// Create by Koos Goossens @ Wortell Last updated: January 10th 2022
//
let AzureFirewallNetworkRuleLogs = AzureDiagnostics
| where Category == "AzureFirewallNetworkRule"
"resources": [
{
"type": "microsoft.operationalinsights/workspaces",
"apiVersion": "2021-06-01",
"name": "[parameters('logAnalyticsName')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"name": "capacityreservation",
"capacityReservationLevel": 100
"resources": [
{
"type": "microsoft.operationalinsights/workspaces",
"apiVersion": "2021-06-01",
"name": "[parameters('logAnalyticsName')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"name": "pergb2018"
},