← All cheat sheets

CLOUDTRAIL & AZURE MONITOR LOG ANALYSIS FOR SOC

Plain-text reference · 16 KB. Read it, search it (Ctrl-F) or print it.

A practical reference for detecting threats, investigating incidents,
and building detections in AWS CloudTrail and Azure Monitor/Sentinel.

CLOUDTRAIL FUNDAMENTALS#

# Enable CloudTrail (all regions, management + data events)
aws cloudtrail create-trail \
  --name security-trail \
  --s3-bucket-name cloudtrail-logs-bucket \
  --is-multi-region-trail \
  --enable-log-file-validation

aws cloudtrail start-logging --name security-trail

# Query CloudTrail with AWS CLI
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin

# Query with time range
aws cloudtrail lookup-events \
  --start-time "2026-03-01T00:00:00Z" \
  --end-time "2026-03-19T23:59:59Z" \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateUser

# Query by username
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=suspicious-user

# CloudTrail log structure (key fields):
#   eventTime, eventName, eventSource, awsRegion
#   sourceIPAddress, userAgent
#   userIdentity.type, userIdentity.arn, userIdentity.accountId
#   requestParameters, responseElements
#   errorCode, errorMessage

CRITICAL CLOUDTRAIL EVENTS TO MONITOR#

# AUTHENTICATION & ACCESS
ConsoleLogin                          # Console sign-in (check MFA, sourceIP)
ConsoleLoginFailure                   # Failed console login
SwitchRole                            # User assumed another role
GetSessionToken                       # Temporary credentials requested
GetFederationToken                    # Federated access token created
AssumeRole                            # Role assumption
AssumeRoleWithSAML                    # SAML-based federation
AssumeRoleWithWebIdentity             # Web identity federation

# USER & CREDENTIAL MANAGEMENT
CreateUser                            # New IAM user created
CreateLoginProfile                    # Console password set for user
CreateAccessKey                       # New access key pair created
UpdateLoginProfile                    # Password changed
DeleteUser                            # User deletion (covering tracks)
AddUserToGroup                        # Group membership change
AttachUserPolicy                      # Direct policy attachment

# POLICY & PERMISSION CHANGES
CreatePolicy                          # New IAM policy created
CreatePolicyVersion                   # Policy updated (check for wildcards)
AttachRolePolicy                      # Policy attached to role
PutRolePolicy                         # Inline policy added to role
PutUserPolicy                         # Inline policy added to user
AttachGroupPolicy                     # Policy attached to group

# PERSISTENCE MECHANISMS
CreateRole                            # New role created
UpdateAssumeRolePolicy                # Trust policy modified
CreateServiceLinkedRole               # Service-linked role created
CreateInstanceProfile                 # EC2 instance profile created
AddRoleToInstanceProfile              # Role added to instance profile

# DEFENSE EVASION
StopLogging                           # CloudTrail logging stopped *** HIGH PRIORITY ***
DeleteTrail                           # CloudTrail trail deleted *** HIGH PRIORITY ***
UpdateTrail                           # Trail configuration changed
PutEventSelectors                     # Event filtering changed
DisableRule                           # CloudWatch/EventBridge rule disabled
DeleteFlowLogs                        # VPC flow logs deleted
DeleteDetector                        # GuardDuty disabled

# DATA EXFILTRATION INDICATORS
GetObject                             # S3 object downloaded (data events)
PutBucketPolicy                       # Bucket policy changed (may allow public)
PutBucketAcl                          # Bucket ACL changed
CreateSnapshot                        # EBS snapshot (data theft)
ModifySnapshotAttribute               # Snapshot shared externally
ModifyImageAttribute                  # AMI shared externally
CopySnapshot                          # Cross-region/account snapshot copy
AuthorizeSecurityGroupIngress         # Firewall opened

# RESOURCE CREATION (CRYPTOMINING / ABUSE)
RunInstances                          # EC2 instances launched
CreateFunction                        # Lambda function created
CreateStack                           # CloudFormation stack deployed

ATHENA QUERIES FOR CLOUDTRAIL#

# Create Athena table for CloudTrail
CREATE EXTERNAL TABLE cloudtrail_logs (
    eventversion STRING, useridentity STRUCT<type:STRING,principalid:STRING,arn:STRING,accountid:STRING>,
    eventtime STRING, eventsource STRING, eventname STRING, awsregion STRING,
    sourceipaddress STRING, useragent STRING, requestparameters STRING,
    responseelements STRING, errorcode STRING, errormessage STRING
) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://cloudtrail-bucket/AWSLogs/<account-id>/CloudTrail/';

# Failed console logins
SELECT eventtime, useridentity.arn, sourceipaddress, errormessage
FROM cloudtrail_logs
WHERE eventname = 'ConsoleLogin' AND errorcode = 'Failed'
ORDER BY eventtime DESC LIMIT 100;

# Access key creation
SELECT eventtime, useridentity.arn, requestparameters, sourceipaddress
FROM cloudtrail_logs
WHERE eventname = 'CreateAccessKey'
ORDER BY eventtime DESC;

# CloudTrail tampering
SELECT eventtime, useridentity.arn, eventname, sourceipaddress
FROM cloudtrail_logs
WHERE eventname IN ('StopLogging', 'DeleteTrail', 'UpdateTrail', 'PutEventSelectors')
ORDER BY eventtime DESC;

# Unusual AssumeRole activity
SELECT eventtime, useridentity.arn, requestparameters, sourceipaddress
FROM cloudtrail_logs
WHERE eventname = 'AssumeRole'
  AND sourceipaddress NOT LIKE '10.%'
ORDER BY eventtime DESC LIMIT 200;

# S3 data exfiltration (large number of GetObject calls)
SELECT useridentity.arn, COUNT(*) as get_count, MIN(eventtime) as first_seen, MAX(eventtime) as last_seen
FROM cloudtrail_logs
WHERE eventname = 'GetObject'
GROUP BY useridentity.arn
HAVING COUNT(*) > 100
ORDER BY get_count DESC;

AZURE ACTIVITY LOG KEY EVENTS (ARM operations)#

# Subscription control plane: AzureActivity column OperationNameValue.
# Case varies between records, so match with =~ or in~. More operations
# and hunts: see the Azure Resource Incident Response sheet.

# Subscription & Resource
Microsoft.Compute/virtualMachines/write            # VM created or changed
Microsoft.Authorization/roleAssignments/write      # Azure RBAC assignment
Microsoft.Resources/subscriptions/resourceGroups/delete  # RG + resources
Microsoft.Network/networkSecurityGroups/write      # NSG created/changed
Microsoft.Network/networkSecurityGroups/securityRules/delete  # rule gone

# Defense Evasion
Microsoft.Insights/DiagnosticSettings/Delete       # logging disabled
Microsoft.Insights/DiagnosticSettings/Write        # logging modified
# Log profiles (legacy activity log export) retired 15 Sep 2026; export
# now runs only through diagnostic settings, so watch the two lines above.

ENTRA ID AUDIT LOG KEY EVENTS (AuditLogs OperationName)#

# Directory changes, not ARM. Sign-ins and risk are in other tables:
SigninLogs                                    # sign-in activity
SigninLogs ResultType "500121"                # MFA denied / not completed
AADUserRiskEvents                             # ID Protection risk (P2)
# More: see the Entra ID and GCP Detection sheet.

# HIGH PRIORITY EVENTS

# Authentication methods & consent
"User registered security info"               # MFA registration
"Consent to application"                      # OAuth consent grant

# Role & Permission Changes
"Add member to role"                          # Role assignment
"Add member to role completed (PIM activation)"  # PIM role activation
"Add eligible member to role in PIM"          # PIM eligibility (use has)
"Remove member from role"                     # Role removal

# User & Group Management
"Add user"                                    # New user created
"Delete user"                                 # User deleted
"Update user"                                 # User properties changed
"Add member to group"                         # Group membership
"Add owner to group"                          # Group ownership
"Reset password (by admin)"                   # Password reset
"Invite external user"                        # Guest user invited

# Application & Service Principal
"Add application"                             # App registration
"Add service principal"                       # Service principal created
"Add service principal credentials"           # Secret/cert added
"Add app role assignment to service principal" # API permissions granted
"Add owner to application"                    # App ownership changed

KQL QUERIES FOR MICROSOFT SENTINEL#

# Failed sign-ins with high volume (brute force)
SigninLogs
| where ResultType != "0"
| summarize FailedCount=count(), DistinctUsers=dcount(UserPrincipalName) by IPAddress, bin(TimeGenerated, 1h)
| where FailedCount > 20
| sort by FailedCount desc

# Successful login after multiple failures (credential stuffing success)
let FailedLogins = SigninLogs
| where ResultType != "0"
| summarize FailCount=count() by UserPrincipalName, IPAddress
| where FailCount > 5;
SigninLogs
| where ResultType == "0"
| join kind=inner FailedLogins on UserPrincipalName, IPAddress
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, FailCount

# Impossible travel detection
SigninLogs
| where ResultType == "0"
| summarize Locations=make_set(Location), LocationCount=dcount(Location) by UserPrincipalName, bin(TimeGenerated, 1h)
| where LocationCount > 1
| sort by TimeGenerated desc

# New app consent granted
AuditLogs
| where OperationName == "Consent to application"
| extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend AppName = tostring(TargetResources[0].displayName)
| project TimeGenerated, InitiatedBy, AppName, OperationName

# Service principal credential added
AuditLogs
| where OperationName has "Add service principal credentials"
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| extend TargetSP = tostring(TargetResources[0].displayName)
| project TimeGenerated, Actor, TargetSP, OperationName

# Global Admin role assignment
AuditLogs
| where OperationName == "Add member to role"
# Role name sits in the target's modifiedProperties, so match the text
| where tostring(TargetResources) has "Global Administrator"
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, Actor, TargetResources

# Conditional Access policy changes
AuditLogs
| where OperationName has "conditional access policy"
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| extend PolicyName = tostring(TargetResources[0].displayName)
| project TimeGenerated, Actor, OperationName, PolicyName

# MFA bypass attempts
SigninLogs
| where AuthenticationRequirement == "multiFactorAuthentication"
| where ResultType != "0"
| summarize Count=count() by UserPrincipalName, ResultDescription
| sort by Count desc

# Azure resource deletion (sabotage detection)
AzureActivity
| where OperationNameValue has "delete"
| where ActivityStatusValue in~ ("Success", "Succeeded")
| summarize DeleteCount=count() by Caller, bin(TimeGenerated, 1h)
| where DeleteCount > 5
| sort by DeleteCount desc

# Key Vault access anomalies
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName == "SecretGet"
| summarize Count=count() by CallerIPAddress, bin(TimeGenerated, 1h)
| where Count > 20
# Newer settings log to AZKVAuditLogs (see Azure Resource IR sheet)

# Detect diagnostic settings deletion (defense evasion)
AzureActivity
| where OperationNameValue =~ "MICROSOFT.INSIGHTS/DIAGNOSTICSETTINGS/DELETE"
| project TimeGenerated, Caller, ResourceGroup, OperationNameValue

CREDENTIAL THEFT DETECTION PATTERNS#

# AWS - Access key used from unusual IP
# Baseline normal IPs for each access key, alert on new ones
SELECT useridentity.accesskeyid, sourceipaddress, COUNT(*) as call_count
FROM cloudtrail_logs
WHERE eventtime > '2026-03-12'
GROUP BY useridentity.accesskeyid, sourceipaddress;

# AWS - Root account usage (should almost never happen)
SELECT eventtime, eventname, sourceipaddress
FROM cloudtrail_logs
WHERE useridentity.type = 'Root'
ORDER BY eventtime DESC;

# Azure - Token replay detection (ID Protection "anomalousToken", P2)
AADUserRiskEvents
| where RiskEventType == "anomalousToken"
| project TimeGenerated, UserPrincipalName, IpAddress, RiskLevel
# Forged SAML from a federated issuer: RiskEventType "tokenIssuerAnomaly"

# Azure - Credential harvesting from Key Vault
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName in ("SecretGet", "SecretList", "CertificateGet")
| summarize Operations=count() by CallerIPAddress, bin(TimeGenerated, 15m)
| where Operations > 50

PERSISTENCE DETECTION PATTERNS#

# AWS - New IAM user with console access
SELECT eventtime, useridentity.arn, requestparameters
FROM cloudtrail_logs
WHERE eventname IN ('CreateUser', 'CreateLoginProfile', 'CreateAccessKey')
ORDER BY eventtime DESC;

# AWS - Lambda backdoor (new function or updated code)
SELECT eventtime, useridentity.arn, requestparameters, sourceipaddress
FROM cloudtrail_logs
WHERE eventname IN ('CreateFunction20150331', 'UpdateFunctionCode20150331v2')
ORDER BY eventtime DESC;

# Azure - New service principal credentials
AuditLogs
| where OperationName has_any ("Add service principal credentials", "Update application")
| where TargetResources has "KeyDescription"
| project TimeGenerated, InitiatedBy, TargetResources

# Azure - Federation trust modification
AuditLogs
| where OperationName has "Set federation settings on domain"
| project TimeGenerated, InitiatedBy, TargetResources

EXFILTRATION DETECTION PATTERNS#

# AWS - S3 bucket policy made public
SELECT eventtime, useridentity.arn, requestparameters
FROM cloudtrail_logs
WHERE eventname IN ('PutBucketPolicy', 'PutBucketAcl')
ORDER BY eventtime DESC;
-- Check requestparameters for "Principal":"*" or AllUsers

# AWS - EBS snapshot shared externally
SELECT eventtime, useridentity.arn, requestparameters
FROM cloudtrail_logs
WHERE eventname = 'ModifySnapshotAttribute'
ORDER BY eventtime DESC;

# AWS - Unusual data transfer volumes
# Correlate with VPC Flow Logs for bytes transferred
SELECT srcaddr, dstaddr, SUM(bytes) as total_bytes
FROM vpc_flow_logs
WHERE dstaddr NOT LIKE '10.%' AND dstaddr NOT LIKE '172.%'
GROUP BY srcaddr, dstaddr
HAVING total_bytes > 1073741824
ORDER BY total_bytes DESC;

# Azure - Mass file download from SharePoint/OneDrive
OfficeActivity
| where Operation in ("FileDownloaded", "FileSyncDownloadedFull")
| summarize DownloadCount=count(), TotalFiles=dcount(OfficeObjectId) by UserId, bin(TimeGenerated, 1h)
| where DownloadCount > 50

# Azure - Storage account key regeneration (precursor to exfil)
AzureActivity
| where OperationNameValue =~
    "MICROSOFT.STORAGE/STORAGEACCOUNTS/REGENERATEKEY/ACTION"
| project TimeGenerated, Caller, ResourceGroup

SOC RESPONSE CHECKLIST#

# When suspicious CloudTrail event detected:
# 1. Identify the principal (userIdentity.arn)
# 2. Check sourceIPAddress against known ranges
# 3. Review userAgent for unusual tools (aws-cli from unexpected locations)
# 4. Correlate with GuardDuty findings
# 5. Check if access key was recently created
# 6. Review all actions by that principal in the time window
# 7. Disable compromised credentials immediately
aws iam update-access-key --access-key-id <key> --status Inactive --user-name <user>
aws iam delete-login-profile --user-name <user>

# When suspicious Azure sign-in detected:
# 1. Check sign-in logs for the user (location, device, app)
# 2. Review audit logs for post-auth activity
# 3. Check risky sign-in and risky user reports
# 4. Revoke sessions and reset credentials
# 5. Review conditional access policy hits
# 6. Check for consent grants and app registrations
# Graph PowerShell (the AzureAD module is retired):
#   Revoke-MgUserSignInSession -UserId <user-object-id-or-UPN>
# Disable the account first; steps in the Entra ID and GCP Detection sheet.

Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.