T1580

Cloud Infrastructure Discovery

This detection identifies adversaries enumerating cloud infrastructure resources across AWS, Azure, and GCP environments. Attackers leverage cloud provider APIs and CLI tools to discover compute instances, storage buckets, databases, snapshots, and network configurations using compromised credentials. The detection monitors for high-volume or broad-scope API calls characteristic of automated enumeration tools like Pacu, bulk read operations across multiple resource types in short time windows, and enumeration patterns associated with threat actors like Scattered Spider and Storm-0501 who use cloud discovery to identify high-value targets before establishing persistence or staging data exfiltration.

Microsoft Sentinel / Defender
kusto
let AwsDiscoveryAPIs = dynamic([
    "DescribeInstances", "DescribeVolumes", "DescribeSnapshots", "DescribeImages",
    "ListBuckets", "HeadBucket", "GetPublicAccessBlock", "GetBucketAcl", "GetBucketPolicy",
    "DescribeDBInstances", "DescribeDBClusters", "DescribeDBSnapshots",
    "DescribeSecurityGroups", "DescribeVpcs", "DescribeSubnets",
    "DescribeNetworkInterfaces", "DescribeRouteTables", "DescribeInternetGateways",
    "ListFunctions", "ListTables", "DescribeClusters", "GetCallerIdentity",
    "ListRoles", "ListUsers", "ListBuckets", "DescribeLoadBalancers",
    "DescribeAutoScalingGroups", "DescribeKeyPairs"
]);
let AzureDiscoveryOps = dynamic([
    "microsoft.compute/virtualmachines/read",
    "microsoft.storage/storageaccounts/read",
    "microsoft.sql/servers/read",
    "microsoft.network/virtualnetworks/read",
    "microsoft.keyvault/vaults/read",
    "microsoft.containerservice/managedclusters/read",
    "microsoft.resources/subscriptions/resources/read"
]);
let lookback = 15m;
let BurstThreshold = 10;
let APISpreadThreshold = 5;
// AWS CloudTrail: detect burst enumeration
let AwsEnumeration = AWSCloudTrail
| where TimeGenerated >= ago(1h)
| where EventName in (AwsDiscoveryAPIs)
| where isnotempty(UserIdentityArn)
| summarize
    DiscoveryCount = count(),
    DistinctAPIs = dcount(EventName),
    APIList = make_set(EventName, 50),
    DistinctRegions = dcount(AWSRegion),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    SourceIPs = make_set(SourceIPAddress, 10)
    by UserIdentityArn, UserIdentityAccountId, bin(TimeGenerated, lookback)
| where DiscoveryCount >= BurstThreshold or DistinctAPIs >= APISpreadThreshold
| extend CloudProvider = "AWS", Identity = UserIdentityArn, AccountId = UserIdentityAccountId
| project TimeGenerated, CloudProvider, Identity, AccountId, DiscoveryCount, DistinctAPIs, APIList, DistinctRegions, SourceIPs, FirstSeen, LastSeen;
// Azure Activity: detect bulk read enumeration
let AzureEnumeration = AzureActivity
| where TimeGenerated >= ago(1h)
| where tolower(OperationNameValue) in (AzureDiscoveryOps)
| where ActivityStatusValue =~ "Success"
| summarize
    DiscoveryCount = count(),
    DistinctOps = dcount(OperationNameValue),
    OpList = make_set(OperationNameValue, 50),
    DistinctResourceGroups = dcount(ResourceGroup),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    SourceIPs = make_set(CallerIpAddress, 10)
    by Caller, SubscriptionId, bin(TimeGenerated, lookback)
| where DiscoveryCount >= BurstThreshold or DistinctOps >= APISpreadThreshold
| extend CloudProvider = "Azure", Identity = Caller, AccountId = SubscriptionId, APIList = OpList, DistinctRegions = DistinctResourceGroups
| project TimeGenerated, CloudProvider, Identity, AccountId, DiscoveryCount, DistinctAPIs = DistinctOps, APIList, DistinctRegions, SourceIPs, FirstSeen, LastSeen;
// Union and score
union AwsEnumeration, AzureEnumeration
| extend
    RiskScore = case(
        DistinctAPIs >= 10 and DiscoveryCount >= 50, 90,
        DistinctAPIs >= 7 and DiscoveryCount >= 20, 70,
        DistinctAPIs >= 5 or DiscoveryCount >= 10, 50,
        30
    )
| sort by RiskScore desc, DiscoveryCount desc
| project TimeGenerated, CloudProvider, Identity, AccountId, DiscoveryCount, DistinctAPIs, APIList, DistinctRegions, SourceIPs, FirstSeen, LastSeen, RiskScore
high severity medium confidence

Data Sources

AWS CloudTrail (via Sentinel connector) Azure Activity Logs

Required Tables

AWSCloudTrail AzureActivity

False Positives

  • Legitimate cloud management platforms (Terraform, Pulumi, CloudFormation) performing state refresh that enumerate all resources at plan/apply time
  • Security posture management tools (Wiz, Prisma Cloud, Orca) performing scheduled asset inventory scans across the entire environment
  • Cloud cost management and optimization tools (CloudHealth, Spot.io) querying instance and storage metadata for billing analysis
  • CI/CD pipelines with infrastructure-as-code that execute bulk describe operations during deployment validation
  • Cloud backup agents (Veeam, Cohesity) performing pre-backup infrastructure discovery to identify targets

Unlock Pro Content

Get the full detection package for T1580 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections