ENTRA ID AND GCP DETECTION
Defensive detection and incident-response reference for Microsoft Entra ID (Azure AD) and Google Cloud (GCP). Blue-team only: what to log, what to hunt, how to respond. AWS has its own sheet. KQL runs in Microsoft Sentinel / Log Analytics (needs Entra P1/P2 to ingest sign-in logs); gcloud/KQL examples are starting points - tune and allowlist before alerting.
ENTRA: LOGS TO COLLECT (diagnostic settings -> Log Analytics)#
SigninLogs # interactive user sign-ins AADNonInteractiveUserSignInLogs # tokens used without user interaction AADServicePrincipalSignInLogs # app / service principal sign-ins AADManagedIdentitySignInLogs # managed identity sign-ins AuditLogs # directory changes (apps, roles, users) AADProvisioningLogs # SCIM / provisioning AADRiskyUsers / AADUserRiskEvents # ID Protection (P2); SP risk = Workload ID
ENTRA: ID PROTECTION RISK + SIGN-IN ERROR CODES#
# riskEventType values worth alerting on: anonymizedIPAddress # Tor / anonymous VPN unlikelyTravel # atypical travel (impossible travel = mcasImpossibleTravel) unfamiliarFeatures # unfamiliar sign-in properties leakedCredentials # creds found in a dump / public repo (user risk) passwordSpray # fires only on a SUCCESSFUL sprayed password # Sign-in ResultType codes: 50126 # invalid username or password (spray / brute force) 50053 # account locked - smart lockout (too many bad passwords) 50074 # strong auth (MFA) required, not yet satisfied 500121 # MFA not completed / denied / timed out (push-bombing signal) 53003 # blocked by a Conditional Access policy
ENTRA: HUNT QUERIES (KQL)#
# Password spray: one IP, many users, same failure
SigninLogs | where ResultType == "50126"
| summarize users=dcount(UserPrincipalName) by IPAddress, bin(TimeGenerated,1h)
| where users >= 10
# MFA fatigue / push bombing: repeated MFA-required/denied for one user
SigninLogs | where ResultType in ("50074", "500121")
| summarize n=count() by UserPrincipalName, bin(TimeGenerated,15m)
| where n >= 5
# Legacy auth (bypasses MFA) - should be blocked by Conditional Access
SigninLogs | where ClientAppUsed in ("Other clients","IMAP4","POP3","SMTP",
"MAPI","Exchange ActiveSync","Authenticated SMTP")
# Risky sign-ins Identity Protection flagged
SigninLogs | where RiskLevelDuringSignIn in ("high","medium")
or RiskState == "atRisk"
ENTRA: PERSISTENCE TO DETECT (AuditLogs OperationName)#
"Consent to application" # illicit OAuth consent (T1528) "Add delegated permission grant" # delegated scope added to an app "Add app role assignment grant to user" # app role granted "Add service principal credentials" # secret/cert added to SP (T1098.001) "...Certificates and secrets management" # app cred added (en dash in name: match with 'has') "Add owner to application" / "...to service principal" # app takeover "Add member to role" # new privileged role holder # Federation/trust change (Golden SAML risk, T1484.002): watch domain # federation settings and any new/changed trusted token issuer.
ENTRA: INCIDENT RESPONSE (Microsoft Graph PowerShell)#
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All" # Order matters: disable FIRST, then revoke (revoke alone doesn't block sign-in) Update-MgUser -UserId user@corp.com -AccountEnabled:$false Revoke-MgUserSignInSession -UserId user@corp.com # resets refresh tokens # Note: not instant - issued access tokens can stay valid up to ~1 hour. # Then: reset the password; review the user's registered MFA methods; # audit app/SP credentials added recently; disable rogue apps; # block legacy auth + require MFA/compliant device via Conditional Access.
GCP: AUDIT LOGS (Cloud Logging)#
Admin Activity # config/metadata changes; ALWAYS on, free, cannot disable Data Access # reads + data-plane; OFF by default (enable per service) System Event # Google-initiated changes; always on Policy Denied # request blocked by a security policy; on by default # logName suffixes (URL-encode the slash as %2F): # .../logs/cloudaudit.googleapis.com%2Factivity (admin activity) # .../logs/cloudaudit.googleapis.com%2Fdata_access # .../logs/cloudaudit.googleapis.com%2Fsystem_event # .../logs/cloudaudit.googleapis.com%2Fpolicy # Key fields: protoPayload.authenticationInfo.principalEmail (who), # protoPayload.methodName (what), protoPayload.resourceName, .serviceName
GCP: KEY methodName SIGNALS#
SetIamPolicy # IAM binding change (T1098) google.iam.admin.v1.CreateServiceAccountKey # new SA key (persistence) google.iam.admin.v1.CreateServiceAccount # new service account google.iam.admin.v1.CreateRole # new custom role # Impersonation roles added via SetIamPolicy delta ADD: # roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser v1.compute.firewalls.insert / .patch / .delete # firewall opened/changed storage.setIamPermissions # bucket made public/shared
GCP: HUNT (gcloud logging read)#
# New service-account keys in the last day gcloud logging read \ 'protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' \ --freshness=1d --limit=20 --format=json # Any IAM policy change (who granted what to whom) gcloud logging read 'protoPayload.methodName:"SetIamPolicy"' --freshness=1d \ --format='table(protoPayload.authenticationInfo.principalEmail,resource.type)' # Admin Activity for one project gcloud logging read \ 'logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity"' \ --limit=20 # Also: Security Command Center findings + Event Threat Detection module.
GCP: INCIDENT RESPONSE#
gcloud iam service-accounts disable SA@PROJECT.iam.gserviceaccount.com gcloud iam service-accounts keys list --iam-account=SA@PROJECT.iam.gserviceaccount.com gcloud iam service-accounts keys delete KEY_ID --iam-account=SA@PROJECT... # Remove an attacker's IAM grant gcloud projects remove-iam-policy-binding PROJECT_ID \ --member="user:bad@evil.example" --role="roles/owner" gcloud compute firewall-rules update RULE --disabled # close a bad opening # Rotate exposed keys/secrets; snapshot evidence before destroying resources; # restrict the project (org policy / deny) while investigating.
REFERENCES#
# Microsoft Learn: Entra monitoring (diagnostic settings & tables), # ID Protection risk detection types, sign-in error codes, # "Revoke user access in an emergency" # Google Cloud: Cloud Audit Logs overview, Security Command Center, # Event Threat Detection # MITRE ATT&CK: T1078.004 (cloud accounts), T1098 / T1098.001 (cloud # credentials), T1528 (steal app access token), T1136.003 (create cloud # account), T1484.002 (trust modification / federation)
ENTRA ID AND GCP DETECTION CHEATSHEET
=====================================
Source: https://cyberramen.com
Defensive detection and incident-response reference for Microsoft Entra ID
(Azure AD) and Google Cloud (GCP). Blue-team only: what to log, what to hunt,
how to respond. AWS has its own sheet. KQL runs in Microsoft Sentinel / Log
Analytics (needs Entra P1/P2 to ingest sign-in logs); gcloud/KQL examples are
starting points - tune and allowlist before alerting.
ENTRA: LOGS TO COLLECT (diagnostic settings -> Log Analytics)
-------------------------------------------------------------
SigninLogs # interactive user sign-ins
AADNonInteractiveUserSignInLogs # tokens used without user interaction
AADServicePrincipalSignInLogs # app / service principal sign-ins
AADManagedIdentitySignInLogs # managed identity sign-ins
AuditLogs # directory changes (apps, roles, users)
AADProvisioningLogs # SCIM / provisioning
AADRiskyUsers / AADUserRiskEvents # ID Protection (P2); SP risk = Workload ID
ENTRA: ID PROTECTION RISK + SIGN-IN ERROR CODES
-----------------------------------------------
# riskEventType values worth alerting on:
anonymizedIPAddress # Tor / anonymous VPN
unlikelyTravel # atypical travel (impossible travel = mcasImpossibleTravel)
unfamiliarFeatures # unfamiliar sign-in properties
leakedCredentials # creds found in a dump / public repo (user risk)
passwordSpray # fires only on a SUCCESSFUL sprayed password
# Sign-in ResultType codes:
50126 # invalid username or password (spray / brute force)
50053 # account locked - smart lockout (too many bad passwords)
50074 # strong auth (MFA) required, not yet satisfied
500121 # MFA not completed / denied / timed out (push-bombing signal)
53003 # blocked by a Conditional Access policy
ENTRA: HUNT QUERIES (KQL)
-------------------------
# Password spray: one IP, many users, same failure
SigninLogs | where ResultType == "50126"
| summarize users=dcount(UserPrincipalName) by IPAddress, bin(TimeGenerated,1h)
| where users >= 10
# MFA fatigue / push bombing: repeated MFA-required/denied for one user
SigninLogs | where ResultType in ("50074", "500121")
| summarize n=count() by UserPrincipalName, bin(TimeGenerated,15m)
| where n >= 5
# Legacy auth (bypasses MFA) - should be blocked by Conditional Access
SigninLogs | where ClientAppUsed in ("Other clients","IMAP4","POP3","SMTP",
"MAPI","Exchange ActiveSync","Authenticated SMTP")
# Risky sign-ins Identity Protection flagged
SigninLogs | where RiskLevelDuringSignIn in ("high","medium")
or RiskState == "atRisk"
ENTRA: PERSISTENCE TO DETECT (AuditLogs OperationName)
------------------------------------------------------
"Consent to application" # illicit OAuth consent (T1528)
"Add delegated permission grant" # delegated scope added to an app
"Add app role assignment grant to user" # app role granted
"Add service principal credentials" # secret/cert added to SP (T1098.001)
"...Certificates and secrets management" # app cred added (en dash in name: match with 'has')
"Add owner to application" / "...to service principal" # app takeover
"Add member to role" # new privileged role holder
# Federation/trust change (Golden SAML risk, T1484.002): watch domain
# federation settings and any new/changed trusted token issuer.
ENTRA: INCIDENT RESPONSE (Microsoft Graph PowerShell)
-----------------------------------------------------
Connect-MgGraph -Scopes "User.ReadWrite.All","Directory.ReadWrite.All"
# Order matters: disable FIRST, then revoke (revoke alone doesn't block sign-in)
Update-MgUser -UserId user@corp.com -AccountEnabled:$false
Revoke-MgUserSignInSession -UserId user@corp.com # resets refresh tokens
# Note: not instant - issued access tokens can stay valid up to ~1 hour.
# Then: reset the password; review the user's registered MFA methods;
# audit app/SP credentials added recently; disable rogue apps;
# block legacy auth + require MFA/compliant device via Conditional Access.
GCP: AUDIT LOGS (Cloud Logging)
-------------------------------
Admin Activity # config/metadata changes; ALWAYS on, free, cannot disable
Data Access # reads + data-plane; OFF by default (enable per service)
System Event # Google-initiated changes; always on
Policy Denied # request blocked by a security policy; on by default
# logName suffixes (URL-encode the slash as %2F):
# .../logs/cloudaudit.googleapis.com%2Factivity (admin activity)
# .../logs/cloudaudit.googleapis.com%2Fdata_access
# .../logs/cloudaudit.googleapis.com%2Fsystem_event
# .../logs/cloudaudit.googleapis.com%2Fpolicy
# Key fields: protoPayload.authenticationInfo.principalEmail (who),
# protoPayload.methodName (what), protoPayload.resourceName, .serviceName
GCP: KEY methodName SIGNALS
---------------------------
SetIamPolicy # IAM binding change (T1098)
google.iam.admin.v1.CreateServiceAccountKey # new SA key (persistence)
google.iam.admin.v1.CreateServiceAccount # new service account
google.iam.admin.v1.CreateRole # new custom role
# Impersonation roles added via SetIamPolicy delta ADD:
# roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser
v1.compute.firewalls.insert / .patch / .delete # firewall opened/changed
storage.setIamPermissions # bucket made public/shared
GCP: HUNT (gcloud logging read)
-------------------------------
# New service-account keys in the last day
gcloud logging read \
'protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' \
--freshness=1d --limit=20 --format=json
# Any IAM policy change (who granted what to whom)
gcloud logging read 'protoPayload.methodName:"SetIamPolicy"' --freshness=1d \
--format='table(protoPayload.authenticationInfo.principalEmail,resource.type)'
# Admin Activity for one project
gcloud logging read \
'logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity"' \
--limit=20
# Also: Security Command Center findings + Event Threat Detection module.
GCP: INCIDENT RESPONSE
----------------------
gcloud iam service-accounts disable SA@PROJECT.iam.gserviceaccount.com
gcloud iam service-accounts keys list --iam-account=SA@PROJECT.iam.gserviceaccount.com
gcloud iam service-accounts keys delete KEY_ID --iam-account=SA@PROJECT...
# Remove an attacker's IAM grant
gcloud projects remove-iam-policy-binding PROJECT_ID \
--member="user:bad@evil.example" --role="roles/owner"
gcloud compute firewall-rules update RULE --disabled # close a bad opening
# Rotate exposed keys/secrets; snapshot evidence before destroying resources;
# restrict the project (org policy / deny) while investigating.
REFERENCES
----------
# Microsoft Learn: Entra monitoring (diagnostic settings & tables),
# ID Protection risk detection types, sign-in error codes,
# "Revoke user access in an emergency"
# Google Cloud: Cloud Audit Logs overview, Security Command Center,
# Event Threat Detection
# MITRE ATT&CK: T1078.004 (cloud accounts), T1098 / T1098.001 (cloud
# credentials), T1528 (steal app access token), T1136.003 (create cloud
# account), T1484.002 (trust modification / federation)
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.