Azure Activity with Federated Credentials outside of GitHub Workflow activity
Fed Cred Az Activity Without Sign In Workflow
Query
// Workflow runs and sign-ins from GitHub
let GitHubFederated = _GetWatchlist('GitHubFederatedCredentials');
let GitHubEvents = GitHubFederated
| extend ServicePrincipalId = tostring(ServicePrincipalId)
| extend GitHubOrganization = tostring(split(Repo, "/")[0])
| extend GitHubRepository = tostring(split(Repo, "/")[1])
| extend FedCredSubjectIdentifier = SubjectIdentifier
| join kind=inner (
AADServicePrincipalSignInLogs
| where ServicePrincipalCredentialKeyId == "00000000-0000-0000-0000-000000000000"
)on $left.ServicePrincipalId == $right.ServicePrincipalId
| project AADSignInTime = TimeGenerated, AADCorrelationId = CorrelationId, IPAddress, ServicePrincipalResource = ResourceDisplayName, AADSignInLocation = Location, ServicePrincipalId, ServicePrincipalCredentialKeyId, AADSignInResult = ResultType, AADTokenId = UniqueTokenIdentifier, FedCredSubjectIdentifier = SubjectIdentifier, GitHubRepoName = Repo
| extend GitHubOrganization = tostring(split(GitHubRepoName, "/")[0])
| extend GitHubRepository = tostring(split(GitHubRepoName, "/")[1])
| join kind=inner (
GitHubAuditLogPolling_CL
| where action_s == "workflows.completed_workflow_run"
| project GitHubRepoName = repo_s, WorkflowRunId = workflow_run_id_d, WorkflowName = name_s, WorkflowActor = actor_s, WorkflowStartedTime = started_at_t, WorkflowCompletedTime = completed_at_t, WorkflowConslusion = conclusion_s
) on $left.GitHubRepoName == $right.GitHubRepoName
| where AADSignInTime between (todatetime(WorkflowStartedTime) .. todatetime(WorkflowCompletedTime));
// Azure Activities from Federated Credentials
GitHubFederated
| extend ServicePrincipalId = tostring(ServicePrincipalId)
| join kind=inner (
AzureActivity
| extend AzClaims = parse_json(Claims_d)
| extend AzObjProp = parse_json(Properties_d)
| extend AzResourceId = tostring(AzObjProp.entity)
| extend AzActivityResource = tostring(AzClaims.aud)
| project AzCorrelationId = CorrelationId, AzTimeStamp = TimeGenerated, AzIpAddress = CallerIpAddress, AzSpId = Caller, AzClaims = parse_json(Claims_d), AzObjProp = parse_json(Properties_d), AzResourceId = tostring(AzObjProp.entity), AzActivityResource = tostring(AzClaims.aud)
)on $left.ServicePrincipalId == $right.AzSpId
| join kind=leftouter GitHubEvents on $left.AzSpId == $right.ServicePrincipalId, $left.AzIpAddress == $right.IPAddress
| where isempty(WorkflowStartedTime) or AzTimeStamp !between (WorkflowStartedTime .. WorkflowCompletedTime)
| project AzResourceId, AzSpId, ServicePrincipalId, ServicePrincipalName, AzIpAddress, IPAddress, WorkflowStartedTime, WorkflowCompletedTime, AzTimeStamp
| extend timestamp = AzTimeStamp, AccountCustomEntity = ServicePrincipalName, IPCustomEntity = AzIpAddressExplanation
This query is designed to detect potentially suspicious activity involving Azure Service Principals with Federated Credentials. Here's a simplified breakdown of what it does:
-
Purpose: The query identifies instances where a Service Principal with Federated Credentials is used for Azure management activities, but there is no corresponding GitHub workflow or sign-in event recorded during the same time frame.
-
Data Sources:
- It uses a watchlist named
GitHubFederatedCredentialsto identify relevant Service Principals. - It checks Azure Active Directory (AAD) sign-in logs and GitHub audit logs for workflow activities.
- It uses a watchlist named
-
Process:
- It first gathers data on GitHub workflow runs and sign-ins associated with the Service Principals.
- It then collects Azure activities performed by these Service Principals.
- The query looks for Azure activities that do not have a matching GitHub workflow event or sign-in within the same time window.
-
Alert Trigger:
- An alert is triggered if there are any such unmatched Azure activities, indicating potential unauthorized or unexpected use of the Service Principal.
-
Frequency: The query runs every 4 hours, checking the past 4 hours of activity.
-
Severity: The severity of the alert is set to "Medium," suggesting that while the activity is suspicious, it may not be immediately critical.
-
Tactics and Techniques:
- The query is associated with tactics like Persistence and Impact, and techniques such as T1098 (Account Manipulation) and T1496 (Resource Hijacking).
-
Entity Mappings:
- The query maps detected entities to account, IP, and Azure resource entities for further investigation.
In summary, this query helps in monitoring and identifying potentially unauthorized use of Azure Service Principals with Federated Credentials, especially when such usage is not accompanied by expected GitHub workflow activities.
Details

Thomas Naunheim
Released: February 9, 2024
Tables
Keywords
Operators
Severity
MediumTactics
Frequency: 4h
Period: 4h