AnalysisType: rule
Filename: aws_rds_snapshot_deleted.py
RuleID: "AWS.RDS.SnapshotDeleted"
DisplayName: "AWS RDS Snapshot Deleted"
Enabled: true
Status: Experimental
LogTypes:
- AWS.CloudTrail
Tags:
- AWS
- Defense Evasion
- Impact
- Data Destruction
- Indicator Removal
- RDS
Severity: High
Description: >
Detects deletion of RDS snapshots. Attackers delete backups to prevent recovery or hide
evidence of data exfiltration. Multiple snapshot deletions may indicate ransomware preparing
to encrypt databases without recovery options.
Runbook: |
1. Find all snapshot deletion events by the user ARN in the past 24 hours to identify bulk deletion patterns
2. Check if the deleted snapshot was shared with external accounts in the 7 days before deletion
3. Look for database deletion or modification events from this user in the 2 hours after this snapshot deletion
Reference: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html
Reports:
MITRE ATT&CK:
- TA0040:T1485 # Data Destruction
- TA0005:T1070 # Indicator Removal
DedupPeriodMinutes: 60
SummaryAttributes:
- eventName
- userIdentity:principalId
- requestParameters:dBSnapshotIdentifier
- requestParameters:dBClusterSnapshotIdentifier
- p_any_aws_account_ids
Threshold: 1
Tests:
- Name: DB Snapshot Deleted
ExpectedResult: true
Log:
eventVersion: "1.08"
userIdentity:
type: AssumedRole
principalId: "AIDAI23HXS3EXAMPLE:user"
arn: "arn:aws:sts::123456789012:assumed-role/PowerUserRole/user"
accountId: "123456789012"
accessKeyId: "ASIAIOSFODNN7EXAMPLE"
eventTime: "2024-01-16T08:15:00Z"
eventSource: rds.amazonaws.com
eventName: DeleteDBSnapshot
awsRegion: us-west-2
sourceIPAddress: "198.51.100.25"
userAgent: "aws-cli/2.13.0"
requestParameters:
dBSnapshotIdentifier: "backup-2024-01-15"
responseElements:
dBSnapshotIdentifier: "backup-2024-01-15"
dBSnapshotArn: "arn:aws:rds:us-west-2:123456789012:snapshot:backup-2024-01-15"
status: "deleted"
snapshotType: "manual"
requestID: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
eventID: "f1e2d3c4-b5a6-7890-1234-567890abcdef"
readOnly: false
eventType: AwsApiCall
managementEvent: true
recipientAccountId: "123456789012"
eventCategory: Management
- Name: DB Cluster Snapshot Deleted
ExpectedResult: true
Log:
eventVersion: "1.08"
userIdentity:
type: IAMUser
principalId: "AIDAI23HXS3EXAMPLE"
arn: "arn:aws:iam::123456789012:user/contractor"
accountId: "123456789012"
accessKeyId: "AKIAIOSFODNN7EXAMPLE"
userName: contractor
eventTime: "2024-01-16T08:15:00Z"
eventSource: rds.amazonaws.com
eventName: DeleteDBClusterSnapshot
awsRegion: us-east-1
sourceIPAddress: "203.0.113.100"
userAgent: "Boto3/1.26.0"
requestParameters:
dBClusterSnapshotIdentifier: "aurora-cluster-backup-2024"
responseElements:
dBClusterSnapshotIdentifier: "aurora-cluster-backup-2024"
dBClusterSnapshotArn: "arn:aws:rds:us-east-1:123456789012:cluster-snapshot:aurora-cluster-backup-2024"
status: "deleted"
snapshotType: "manual"
requestID: "b2c3d4e5-f6a7-8901-bcde-f1234567890a"
eventID: "g2f3e4d5-c6b7-8901-2345-678901bcdefg"
readOnly: false
eventType: AwsApiCall
managementEvent: true
recipientAccountId: "123456789012"
eventCategory: Management
- Name: Snapshot Deletion Failed
ExpectedResult: false
Log:
eventVersion: "1.08"
userIdentity:
type: IAMUser
principalId: "AIDAI23HXS3EXAMPLE"
arn: "arn:aws:iam::123456789012:user/developer"
accountId: "123456789012"
accessKeyId: "AKIAIOSFODNN7EXAMPLE"
userName: developer
eventTime: "2024-01-16T08:15:00Z"
eventSource: rds.amazonaws.com
eventName: DeleteDBSnapshot
awsRegion: us-west-2
sourceIPAddress: "10.0.1.50"
userAgent: "aws-cli/2.13.0"
requestParameters:
dBSnapshotIdentifier: "backup-2024-01-15"
errorCode: InvalidDBSnapshotState
errorMessage: "Cannot delete snapshot in current state"
requestID: "c3d4e5f6-a7b8-9012-cdef-1234567890ab"
eventID: "h3g4f5e6-d7c8-9012-3456-789012cdefgh"
readOnly: false
eventType: AwsApiCall
managementEvent: true
recipientAccountId: "123456789012"
eventCategory: Management
- Name: Different RDS Event
ExpectedResult: false
Log:
eventVersion: "1.08"
userIdentity:
type: AssumedRole
principalId: "AIDAI23HXS3EXAMPLE:user"
arn: "arn:aws:sts::123456789012:assumed-role/Admin/user"
accountId: "123456789012"
eventTime: "2024-01-16T08:15:00Z"
eventSource: rds.amazonaws.com
eventName: CreateDBSnapshot
awsRegion: us-west-2
sourceIPAddress: "10.0.1.100"
requestParameters:
dBSnapshotIdentifier: "new-backup"
dBInstanceIdentifier: "my-database"
requestID: "d4e5f6a7-b8c9-0123-def0-1234567890bc"
eventID: "i4h5g6f7-e8d9-0123-4567-890123defghi"
readOnly: false
eventType: AwsApiCall
managementEvent: true
recipientAccountId: "123456789012"
eventCategory: Management
# ------ paired body: aws_rds_snapshot_deleted.py ------
from panther_aws_helpers import aws_rule_context
def rule(event):
if event.get("eventSource") != "rds.amazonaws.com":
return False
deletion_events = ["DeleteDBSnapshot", "DeleteDBClusterSnapshot"]
if event.get("eventName") not in deletion_events:
return False
return event.deep_get("errorCode") is None
def title(event):
event_name = event.get("eventName", "Unknown")
snapshot_id = event.deep_get("requestParameters", "dBSnapshotIdentifier") or event.deep_get(
"requestParameters", "dBClusterSnapshotIdentifier", default="<UNKNOWN>"
)
user = event.deep_get("userIdentity", "userName") or event.deep_get(
"userIdentity", "principalId", default="<UNKNOWN_USER>"
)
resource_type = "Snapshot" if event_name == "DeleteDBSnapshot" else "Cluster Snapshot"
return f"RDS {resource_type} Deleted: [{snapshot_id}] by [{user}]"
def dedup(event):
snapshot_id = event.deep_get("requestParameters", "dBSnapshotIdentifier") or event.deep_get(
"requestParameters", "dBClusterSnapshotIdentifier", default="unknown"
)
account_id = event.deep_get("recipientAccountId", default="unknown")
region = event.get("awsRegion", "unknown")
return f"{account_id}:{region}:{snapshot_id}"
def alert_context(event):
context = aws_rule_context(event)
context["snapshot_identifier"] = event.deep_get(
"requestParameters", "dBSnapshotIdentifier"
) or event.deep_get("requestParameters", "dBClusterSnapshotIdentifier", default="N/A")
context["snapshot_arn"] = event.deep_get("responseElements", "dBSnapshotArn") or event.deep_get(
"responseElements", "dBClusterSnapshotArn", default="N/A"
)
return context