EXPLORE
← Back to Explore
kqlHunting

FOCI Client ID Detection

This query checks sign-in logs for Family of Client IDs (FOCI) applications

Detection Query

//This query checks sign-in logs for Family of Client IDs (FOCI) applications
//FOCI apps can obtain special family refresh tokens for bearer token redemption
let FOCI = externaldata(ClientID: string, Application: string)[@"https://raw.githubusercontent.com/secureworks/family-of-client-ids-research/main/known-foci-clients.csv"] with (format="csv", ignoreFirstRecord=true);
union SigninLogs,AADNonInteractiveUserSignInLogs
| join kind=leftouter FOCI on $left.AppId == $right.ClientID //Everything from left and only matching from right
| extend isFOCI = iff(isnotempty(ClientID), "1", "0") //yield true if a join was possible between records of the two tables
| project-away ClientID

Data Sources

SigninLogs

Platforms

azure-ad

Tags

entra
Raw Content
//This query checks sign-in logs for Family of Client IDs (FOCI) applications
//FOCI apps can obtain special family refresh tokens for bearer token redemption
let FOCI = externaldata(ClientID: string, Application: string)[@"https://raw.githubusercontent.com/secureworks/family-of-client-ids-research/main/known-foci-clients.csv"] with (format="csv", ignoreFirstRecord=true);
union SigninLogs,AADNonInteractiveUserSignInLogs
| join kind=leftouter FOCI on $left.AppId == $right.ClientID //Everything from left and only matching from right
| extend isFOCI = iff(isnotempty(ClientID), "1", "0") //yield true if a join was possible between records of the two tables
| project-away ClientID