Cloud Storage Object Discovery
This detection identifies adversary enumeration of cloud storage objects across AWS S3, Azure Blob Storage, and GCP Cloud Storage. Attackers use native cloud APIs (e.g., ListObjectsV2 for S3, List Blobs for Azure) to survey accessible buckets and containers, typically as a precursor to data staging or exfiltration. The detection looks for anomalous listing activity including high-volume object enumeration, access from unexpected identities or IPs, enumeration across multiple buckets in short time windows, and listing operations performed by service principals or IAM roles outside their expected behavioral baseline. Tools such as Pacu and Peirates are known to automate these enumeration workflows.
What is T1619 Cloud Storage Object Discovery?
Cloud Storage Object Discovery (T1619) maps to the Discovery tactic — the adversary is trying to figure out your environment in MITRE ATT&CK.
This page provides production-ready detection logic for Cloud Storage Object Discovery, covering the data sources and telemetry it touches: AWS CloudTrail (via Microsoft Sentinel AWSCloudTrail connector), Azure Storage Analytics / Diagnostic Logs (StorageBlobLogs). The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Discovery
- Technique
- T1619 Cloud Storage Object Discovery
- Canonical reference
- https://attack.mitre.org/techniques/T1619/
let LookbackWindow = 1h;
let HighVolumeThreshold = 50;
let UniqueBucketThreshold = 5;
// AWS S3 enumeration via CloudTrail
let AWSS3Discovery = AWSCloudTrail
| where TimeGenerated >= ago(LookbackWindow)
| where EventName in ("ListBuckets", "ListObjects", "ListObjectsV2", "ListObjectVersions", "ListMultipartUploads", "GetBucketAcl", "GetBucketPolicy", "GetBucketLocation")
| extend UserIdentity = coalesce(UserIdentityArn, UserIdentityUserName, UserIdentityPrincipalid)
| summarize
OperationCount = count(),
UniqueBuckets = dcount(tostring(RequestParameters)),
Operations = make_set(EventName),
SourceIPs = make_set(SourceIpAddress),
AWSRegions = make_set(AWSRegion),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by UserIdentity, UserIdentityType, UserAgent, bin(TimeGenerated, 10m)
| where OperationCount > HighVolumeThreshold or UniqueBuckets > UniqueBucketThreshold
| extend Platform = "AWS", Severity = iff(OperationCount > 200 or UniqueBuckets > 20, "High", "Medium")
| project TimeGenerated, Platform, UserIdentity, UserIdentityType, UserAgent, OperationCount, UniqueBuckets, Operations, SourceIPs, AWSRegions, FirstSeen, LastSeen, Severity;
// Azure Blob Storage enumeration
let AzureBlobDiscovery = StorageBlobLogs
| where TimeGenerated >= ago(LookbackWindow)
| where OperationName in ("ListBlobs", "ListContainers", "GetContainerProperties", "GetBlobServiceProperties", "ListBlobsFlatSegment", "ListBlobsHierarchySegment")
| summarize
OperationCount = count(),
UniqueContainers = dcount(Uri),
Operations = make_set(OperationName),
SourceIPs = make_set(CallerIpAddress),
Accounts = make_set(AccountName),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by AuthenticationType, RequesterObjectId, UserAgentHeader, bin(TimeGenerated, 10m)
| where OperationCount > HighVolumeThreshold or UniqueContainers > UniqueBucketThreshold
| extend
Platform = "Azure",
Severity = iff(OperationCount > 200 or UniqueContainers > 20, "High", "Medium"),
UserIdentity = coalesce(RequesterObjectId, "Anonymous"),
UserAgent = UserAgentHeader,
AWSRegions = dynamic([])
| project TimeGenerated, Platform, UserIdentity, AuthenticationType, UserAgent, OperationCount, UniqueContainers, Operations, SourceIPs, Accounts, FirstSeen, LastSeen, Severity;
// Union and surface results
AWSS3Discovery
| union AzureBlobDiscovery
| sort by OperationCount desc Detects high-volume or broad cloud storage enumeration across AWS S3 (via CloudTrail ListObjectsV2/ListBuckets and related APIs) and Azure Blob Storage (via StorageBlobLogs List operations). Alerts when a single identity performs more than 50 listing operations or touches more than 5 unique buckets/containers within a 10-minute window, which is indicative of automated reconnaissance tools like Pacu or Peirates.
Data Sources
Required Tables
False Positives
- Legitimate cloud-native backup solutions (e.g., Veeam, AWS Backup, Azure Backup) that enumerate storage objects on a schedule
- Data lake or ETL pipeline services (Azure Data Factory, AWS Glue) that list objects as part of normal pipeline execution
- Security posture management tools (Prisma Cloud, Wiz, AWS Security Hub) performing periodic storage inventory scans
- DevOps CI/CD pipelines that sync or audit S3/Blob content as part of deployment workflows
- Cloud cost optimization tools (CloudHealth, Spot.io) enumerating storage for billing analysis
Sigma rule & cross-platform mapping
The detection logic for Cloud Storage Object Discovery (T1619) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1619
References (7)
- https://attack.mitre.org/techniques/T1619/
- https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
- https://learn.microsoft.com/en-us/rest/api/storageservices/list-blobs
- https://github.com/RhinoSecurityLabs/pacu
- https://github.com/inguardians/peirates
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html
- https://learn.microsoft.com/en-us/azure/storage/blobs/monitor-blob-storage
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1AWS S3 Bucket and Object Enumeration with AWS CLI
Expected signal: CloudTrail will generate events: eventName=ListBuckets, eventName=ListObjectsV2 (one per bucket enumerated), eventName=GetBucketLocation, eventName=GetBucketAcl, eventName=GetBucketPolicy. All events will share the same userIdentity.arn and originating sourceIPAddress. Events appear in CloudTrail within 15 minutes (standard delivery) or near-real-time (CloudTrail Lake).
- Test 2Pacu Framework AWS Storage Enumeration Module
Expected signal: CloudTrail events with userAgent containing 'Boto3' (Pacu uses Boto3 SDK). EventNames: ListBuckets, GetBucketAcl, GetBucketLocation, DescribeVolumes, DescribeSnapshots. The Pacu session generates many rapid sequential API calls detectable by rate and ordering patterns.
- Test 3Azure Blob Storage Container and Object Enumeration via Azure CLI
Expected signal: Azure StorageBlobLogs table will contain OperationName values: ListContainers, ListBlobs, GetContainerProperties. CallerIpAddress will reflect the test machine IP. AuthenticationType will show 'StorageKey' (when using account key) or 'OAuth' (when using service principal). AzureActivity log will show Microsoft.Storage/storageAccounts/listKeys/action if keys were retrieved.
Unlock Pro Content
Get the full detection package for T1619 including response playbook, investigation guide, and atomic red team tests.