← Rule library
high KQL AWS
Bulk Object Download From Cloud Storage
Reads are normal. Reads at volume by one principal across many objects in an hour, excluding principals whose baseline already moves data in bulk, are not.
Rule source
// Bulk Object Download From Cloud Storage
// T1567.002 - Exfiltration to Cloud Storage
// Reads are normal; reads at volume by one principal across many objects in a
// short window, from an IP that principal has not used before, are not.
let window = 1h;
let min_objects = 500;
AWSCloudTrail
| where TimeGenerated > ago(window)
| where EventName in ("GetObject", "CopyObject")
| where isempty(ErrorCode)
| extend Bucket = tostring(parse_json(RequestParameters).bucketName)
| summarize
Objects = dcount(tostring(parse_json(RequestParameters).key)),
Buckets = make_set(Bucket, 10),
SourceIPs = make_set(SourceIpAddress, 5),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by UserIdentityArn, SourceIpAddress
| where Objects >= min_objects
| join kind=leftanti (
// Principals that move data in bulk as their job - ETL, backup, replication.
AWSCloudTrail
| where TimeGenerated between (ago(30d) .. ago(window))
| where EventName == "GetObject"
| summarize Baseline = dcount(tostring(parse_json(RequestParameters).key))
by UserIdentityArn
| where Baseline > 10000
| project UserIdentityArn
) on UserIdentityArn
| order by Objects desc Required telemetry
AWS CloudTrail - GetObject and CopyObject data events
Confirm this source is arriving before you judge the rule. A detection built on telemetry you do not collect looks identical to one that simply never fires.
Known false positives
- ETL, backup and replication principals - excluded by 30 day baseline, not by name
- Analytics jobs that legitimately scan a bucket end to end
Validation
Scripted download of 800 objects from a lab bucket under a fresh IAM role
Re-run quarterly. Rules decay because the environment moves underneath them - agent upgrades, schema changes and config edits all break detections silently.