AnalysisType: rule
Filename: aws_cloudtrail_ses_check_send_quota.py
RuleID: "AWS.CloudTrail.SES.CheckSendQuota"
DisplayName: AWS CloudTrail SES Check Send Quota
Enabled: true
LogTypes:
- AWS.CloudTrail
Severity: Info
CreateAlert: false
Description: >
Detect when someone checks how many emails can be delivered via SES.
Excludes automated checks from AWS Trusted Advisor to reduce false positives.
Reference: >
https://stratus-red-team.cloud/attack-techniques/AWS/aws.discovery.ses-enumerate/
Tags:
- AWS CloudTrail
- SES
Tests:
- Name: GetSendQuota Event
ExpectedResult: true
Log:
{
"p_event_time": "2025-01-20 16:52:14.000000000",
"p_log_type": "AWS.CloudTrail",
"p_parse_time": "2025-01-20 17:00:54.217261818",
"additionalEventData": {
"SignatureVersion": "4"
},
"awsRegion": "us-west-2",
"eventCategory": "Management",
"eventID": "141c7b0f-3ec3-40bd-b551-5a33d1a794b4",
"eventName": "GetSendQuota",
"eventSource": "ses.amazonaws.com",
"eventTime": "2025-01-20 16:52:14.000000000",
"eventType": "AwsApiCall",
"eventVersion": "1.08",
"managementEvent": true,
"readOnly": true,
"recipientAccountId": "111122223333",
"requestID": "6495a102-3900-47fc-a8b4-88e4b4e56442",
"sourceIPAddress": "1.2.3.4",
"tlsDetails": {
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"clientProvidedHostHeader": "email.us-west-2.amazonaws.com",
"tlsVersion": "TLSv1.3"
},
"userAgent": "example-user-agent",
"userIdentity": {
"accessKeyId": "SAMPLE_ACCESS_KEY",
"accountId": "111122223333",
"arn": "arn:aws:sts::111122223333:assumed-role/SampleRole/bobson.dugnutt",
"principalId": "SAMPLE_PRINCIPAL_ID:bobson.dugnutt",
"sessionContext": {
"attributes": {
"creationDate": "2025-01-20T15:58:59Z",
"mfaAuthenticated": "false"
},
"sessionIssuer": {
"accountId": "111122223333",
"arn": "arn:aws:iam::111122223333:role/aws-reserved/sso.amazonaws.com/us-west-2/SampleRole",
"principalId": "SAMPLE_PRINCIPAL_ID",
"type": "Role",
"userName": "SampleRole"
}
},
"type": "AssumedRole"
}
}
- Name: GetSendQuota from Trusted Advisor (Should Not Alert)
ExpectedResult: false
Log:
{
"p_event_time": "2026-01-11 22:54:56.000000000",
"p_log_type": "AWS.CloudTrail",
"awsRegion": "us-east-1",
"eventCategory": "Management",
"eventID": "test-event-id",
"eventName": "GetSendQuota",
"eventSource": "ses.amazonaws.com",
"eventTime": "2026-01-11 22:54:56.000000000",
"eventType": "AwsApiCall",
"eventVersion": "1.08",
"managementEvent": true,
"readOnly": true,
"recipientAccountId": "187901811700",
"sourceIPAddress": "trustedadvisor.amazonaws.com",
"userAgent": "trustedadvisor.amazonaws.com",
"userIdentity": {
"type": "AssumedRole",
"principalId": "AROASXP6SDP2MIDOVDS5K:TrustedAdvisor_187901811700_7472a099-2df6-4080-b339-9681aa0a066a",
"arn": "arn:aws:sts::187901811700:assumed-role/AWSServiceRoleForTrustedAdvisor/TrustedAdvisor_187901811700_7472a099-2df6-4080-b339-9681aa0a066a",
"accountId": "187901811700",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "AROASXP6SDP2MIDOVDS5K",
"arn": "arn:aws:iam::187901811700:role/aws-service-role/trustedadvisor.amazonaws.com/AWSServiceRoleForTrustedAdvisor",
"accountId": "187901811700",
"userName": "AWSServiceRoleForTrustedAdvisor"
},
"attributes": {
"creationDate": "2026-01-11T22:54:56Z",
"mfaAuthenticated": "false"
}
}
}
}
# ------ paired body: aws_cloudtrail_ses_check_send_quota.py ------
from panther_aws_helpers import aws_rule_context
from panther_core import PantherEvent
def rule(event: PantherEvent) -> bool:
if event.get("eventName") == "GetSendQuota":
# Exclude AWS Trusted Advisor automated checks
role_name = event.deep_get("userIdentity", "sessionContext", "sessionIssuer", "userName")
if role_name == "AWSServiceRoleForTrustedAdvisor":
return False
return True
return False
def alert_context(event: PantherEvent) -> dict:
context = aws_rule_context(event)
context["accountRegion"] = f"{event.get('recipientAccountId')}_{event.get('eventRegion')}"
return context