Microsoft recently made the Microsoft Graph Activity Logs available as part of the Microsoft Entra ID diagnostic settings. This means we can use the MicrosoftGraphActivityLogs Table to enrich custom detections and analytic rules.
Within this post I want to elaborate closer on an attack scenario for workload identities that leverage workload identity federation and don’t have any persistent credentials or long lived secrets. But one type of credential artefacts is still theft-able — the short lived access tokens.
Adversaries can try to exfiltrate the access token from the CI/CD environment such as a GitHub action and replay the token within another system to access Entra ID protected resources.
This tactic could also be used in scenarios with App Registrations that leverage certificates or clients secrets where adversaries don’t have access to the credentials but get possession of the access token due to exposure in cleartext such as in log files or decrypted TLS traffic.
Stealing and replaying workload identity access tokens
To demonstrate a scenario to steal and replay an access token of a workload identity, I prepared a demo scenario with a GitHub action that acquires access tokens for the Microsoft Graph API and the Azure Resource Manager API. The pipeline leverages federated credentials (also referred to as workload identity federation).
An attacker with access to the CI environment can modify the CI pipeline to exfiltrate the Entra ID access token, e.g. via outgoing webhook or DNS and the replay the access token to call protected resources such as the Microsoft Graph API.
Full example of the GitHub Action workflow: ITDR/.github/workflows/token-theft-demo.yml at main · nicolonsky/ITDR
If the token was issued for Microsoft Graph resources, it is fairly simple to estimate the applicable permissions as they hide within the scopes of the JWT:
In my example I automated the token replay with a simple pipedream workflow that extracts the incoming access token from the webhook and performs a Microsoft Graph API request.
This automated replay has the advantage, that we do not need to worry about the expiration and can directly replay the token after exfiltration. In an advanced scenario we could even check the included permissions that are described as scopes within the token to find a potential target or writeable scope of the acquired token.
This activity can be detected based on the AADServicePrincipalSignInLogs which contains information about the sign-in of the workload identity.
The Microsoft Graph API call from the replayed access token is visible within the MicrosoftGraphActivityLogs table.
The useful thing is, that we can lookup the corresponding sign-in for each Microsoft Graph activity based on the UniqueTokenIdentifier / SignInActivityId.
When the IPAddress between the token issuance and activity doesn’t match, we have a strong indicator, that the token was replayed by a malicious actor. Additionally, we can also include the Azure Activity Logs within our detection, to also detect abuse based on Azure Activity and not only Microsoft Graph calls.
You can find the full detection within my new ITDR GitHub Repository: ITDR/Detections/T1528.Entra.ServicePrincipalAccessTokenReplay.md at main · nicolonsky/ITDR (github.com).
The query can also be used directly for a Sentinel analytics rule - simply adjust the detection frequency 🕵️♂️.
You can find an export of the rule on GitHub as well: ITDR/AnalyticRules/T1528.Entra.ServicePrincipalAccessTokenReplay.json at main · nicolonsky/ITDR (github.com)
As workload identities and some Microsoft backend services also support continuous access evaluation (CAE) we can trigger a CAE aware action as response to limit further abuse. The following actions are honoured for CAE¹:
- Service principal disable
- Service principal delete
- High service principal risk as detected by Microsoft Entra ID Protection
Thanks to Microsoft Sentinel we can trigger the appropriate response action (disabling the service principal) directly from an automation based on a logic app. To keep track of the affected workload identity we store the ObjectId of the service principal within the alert enhancement:
With that we have everything to create a playbook to disable the affected workload identity:
You can find the playbook code here: ITDR/Playbooks/Entra-DisableServicePrincipal/LA-DisableServicePrincipal.json at main · nicolonsky/ITDR (github.com)
Make sure, that the managed identity of the logic app has assigned Application.ReadWrite.All permissions to disable the service principal. With that we can now run our response action in form of a playbook against the service principal for which the token was replayed:
After running the playbook, the service principal gets disabled in Entra ID:
What about managed identities?!
When checking the AADManagedIdentitySignInLogs we will recognize that the sign-ins will not expose any IP or location information. Otherwise we could leverage the same detection capabilities as for ‘regular’ service principals or app registrations.
I assume that we do not have this information as managed identities are not calling the Entra ID authentication endpoints ‘from the outside’ of Entra ID for access tokens, as managed identities expose an access token directly by calling an internal metadata endpoint such as:
Unfortunately, the same approach for token replay works with managed identities and we cannot determine or identify replay activities. An even bigger drawback was the fact, that in my case the access tokens for managed identities used by an automation account had a validity period of almost 24 hours.
The Microsoft Graph Activity Logs provide valuable detection capabilities for Entra ID tenants. As Microsoft Graph is the de-facto standard it is a welcome addition, although we have other API’s still in place/use where we currently do not have visibility.
The Azure Activity logs do not contain read or list actions and are therefore not able to detect access token replay activities that solely enumerate or discover resources. That’s a clear advantage for the new Microsoft Graph Activity logs.
Personally I’d hoped that Microsoft leverages those signals I used for the detection as part of the Entra workload identities risk score but none of the activities did trigger service principal risk detections:
So 🤞(finger’s crossed) that these blind spots, especially around managed identities will be improved in the future.
During testing and simulation of the access token replay I had sometimes very high delays when it came to the ingestion time after the replay took place, this is also noticeable by calculating the standard deviation:
As I’m very interested in topics around Identity Threat Detection and Response (ITDR) I started a little GitHub project where I will add further resources for similar posts and artefacts in the future.
Also make sure to checkout Fabian Bader’s Detect threats using Microsoft Graph Logs — Part 1 — Cloudbrothers post where he uses the activity logs to identity common reconnaissance tools.