Skip to content

Instantly share code, notes, and snippets.

View x3nc0n's full-sized avatar

John Spaid x3nc0n

View GitHub Profile
@x3nc0n
x3nc0n / aadsigning-legacy.gallery
Created March 7, 2022 19:30
Gallery Template for Legacy Auth Workbook
@x3nc0n
x3nc0n / NewServicePrincipalLoginAttemptFromPreviouslyUnseenIp.kql
Last active November 18, 2021 15:31
This KQL query returns logins from IP addresses for Service Principals where the IP has not been previously seen used by the SP.
// If this is too noisy, create and use the watchlist below, then uncomment the first line and last line of this query
// let watchlist = (_GetWatchlist('NoisyIpApps') | project AppName);
let lookback = 30d;
let detectionTime = 1d;
let ipNew =
imAuthentication
| where EventProduct == 'AAD Service Principal'
| where TimeGenerated > ago(detectionTime)
| summarize by ServicePrincipalName, SrcDvcIpAddr;
let ipHistory =
@x3nc0n
x3nc0n / AzSentinelMdeNewFileExtensions
Created November 3, 2021 19:47
KQL query to build a table of historically seen file extensions and find new ones in the DeviceFileEvents table from MDE
// This query builds a table of historically seen file extensions and then compares it to extensions seen in the last day, listing new ones.
let FileExtensionHistory = (
DeviceFileEvents
| where TimeGenerated between (ago(14d)..ago(1d)) and FileName != '' // get two weeks of events
| extend FileExtension = extract("\\.([0-9A-Za-z]+)(?:[\\?#]|$)", 1, FileName) // extract the file extension
| where FileExtension != '' // get rid of the empty extensions
| summarize by FileExtension); // project only what we need, a big list of file extensions
DeviceFileEvents
| where TimeGenerated between (ago(1d)..now()) and FileName != '' // get data from the last day
| extend FileExtension = extract("\\.([0-9A-Za-z]+)(?:[\\?#]|$)", 1, FileName) // extract the file extension
@x3nc0n
x3nc0n / AzSentinelFileEventsAbnormality.kql
Created November 3, 2021 19:44
KQL query to detect file event abnormalities via the normalized Asim functions
// This query gets the specified historic (line 4; can be removed for all file event types) file creation events by each Host and bins them by a time period (line 6), computes the average and standard deviation, and then adds them to get a dynamic threshold for each Host. It then joins the data in the recent time period (line 10) and drops Hosts under their threshold.
let mod_threshold = (
imFileEvent
| where TimeGenerated between (ago(14d)..ago(1d)) // get two weeks of events
| where EventType == "FileCreated" // get file creations; can remove this line for all file events or alter for deleted, modified, etc.
| summarize cnt=count() by DvcHostname, bin(TimeGenerated, 1h) //count the events for each host by hour specified, default 1
| summarize avg(cnt), stdev(cnt) by DvcHostname // compute the average and standard deviation for each Host
| project average = avg_cnt, threshold = avg_cnt + stdev_cnt, DvcHostname); // project only what we need
imFileEvent
| where TimeGenerated between (ago(1h)..now()) // get da
@x3nc0n
x3nc0n / AzSentinelNewFileExtensions.kql
Last active November 4, 2021 20:17
This KQL query builds a list of previously seen file extensions and finds new ones that appears in the last day from the Asim imFileEvents function
// This query builds a table of historically seen file extensions and then compares it to extensions seen in the last day, listing new ones.
let FileExtensionHistory = (
imFileEvent
| where TimeGenerated between (ago(14d)..ago(1d)) // get two weeks of events
| where FilePath !startswith "C:\\Windows\\Temp\\" and FilePath !startswith "/tmp/" //drop temp directories with random file names
| extend FileExtension = extract("\\.([0-9A-Za-z]+)(?:[\\?#]|$)", 1, FilePath) // extract the file extension
| where FileExtension != '' // get rid of the empty extensions
| summarize by FileExtension); // project only what we need, a big list of file extensions
imFileEvent
| where TimeGenerated between (ago(1d)..now()) // get data from the last day
@x3nc0n
x3nc0n / AzFrontDoorAccessAnomalies.txt
Created September 3, 2021 15:00
KQL Query for Front Door Access Anomalies
let request_threshold = toscalar(
AzureDiagnostics
| where Category contains "FrontDoorAccessLog"
| where TimeGenerated >= startofday(ago(90d)) and TimeGenerated < startofday(now())
| summarize cnt=count() by clientIp_s, bin(TimeGenerated, 1d)
| summarize avg(cnt), stdev(cnt)
| project threshold = avg_cnt+stdev_cnt);
AzureDiagnostics
| where Category == "FrontdoorAccessLog"
| summarize count() by userAgent_s,clientIp_s

Start Here

With the execption of infrastructure setup for Syslog/CEF or WEF/WEC, you can connect all this with the following roles and permissions:

  • Azure AD Directory Role - Security Admin
  • Azure Subscription RBAC Role - Security Reader (for logs)
  • Contributor on the Log Analytics Workspace used for Sentinel (for least privledge, you can use Log Analytics Contributor and Sentinel Contributor)

Connect

  • AAD Logs, audit and sign-in
  • Azure subscription Activity logs (ad-hoc or via Policy)
@x3nc0n
x3nc0n / keybase.md
Created September 5, 2019 23:22
Public

Keybase proof

I hereby claim:

  • I am x3nc0n on github.
  • I am x3nc0n (https://keybase.io/x3nc0n) on keybase.
  • I have a public key ASBa8svUbM_n4CDAcgyg5D_yoQntpy7acgConWK_K7ti8Qo

To claim this, I am signing this object: