← 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#

# HIGH PRIORITY EVENTS

# Authentication
"Sign-in activity"                            # Azure AD sign-in logs
"Risky sign-in"                               # Identity Protection alerts
"MFA denied"                                  # Blocked MFA attempt
"User registered security info"               # MFA registration
"Consent to application"                      # OAuth consent grant

# Role & Permission Changes
"Add member to role"                          # Role assignment
"Add eligible member to role in PIM"          # PIM role activation
"Remove member from role"                     # Role removal
"Add role assignment"                         # Azure RBAC change

# 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 user password"                         # 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
"Consent to application"                      # App consent granted
"Add app role assignment to service principal" # API permissions granted
"Add owner to application"                    # App ownership changed

# Subscription & Resource
"Create or Update Virtual Machine"            # VM creation
"Create role assignment"                       # RBAC assignment
"Delete resource group"                       # Resource deletion
"Create or Update Network Security Group"     # NSG changes
"Delete Network Security Group Rule"          # Firewall rule removed

# Defense Evasion
"Delete diagnostic setting"                   # Logging disabled
"Update diagnostic setting"                   # Logging modified
"Deletes the activity log profile"            # Activity log export removed

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"
| extend RoleName = tostring(TargetResources[0].displayName)
| where RoleName == "Global Administrator"
| extend AddedUser = tostring(TargetResources[2].userPrincipalName)
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| project TimeGenerated, Actor, AddedUser, RoleName

# 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 == "Success"
| 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, identity_claim_upn_s, bin(TimeGenerated, 1h)
| where Count > 20

# 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
SigninLogs
| where TokenIssuerType == "AzureAD"
| where RiskLevelDuringSignIn in ("high", "medium")
| where RiskDetail has "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
# PowerShell: Revoke-AzureADUserAllRefreshToken -ObjectId <user-object-id>

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