GTIG Agentic Cloud Credential Harvesting – Machine-Speed Multi-Agent Operations

Threat Overview

Google Threat Intelligence Group reported on September 8, 2026 that a suspected financially motivated threat actor compromised cloud infrastructure and used an autonomous multi-agent framework to plan, build, and execute a mass credential-harvesting campaign in under six hours. Google stated that the framework autonomously managed vulnerability scanning, troubleshot failures, rotated source IPs, and harvested thousands of third-party credentials. GTIG separately identified an exposed reconnaissance and credential-management framework containing more than 23,800 harvested secrets, including cloud and AI API keys. For MSSP customers, the major change is attack compression: infrastructure abuse, scanning, credential harvesting, and operational troubleshooting can occur in parallel at machine speed from legitimate cloud address space.

References

  • Google Threat Intelligence Group, September 8, 2026: From prompting to autonomy – the evolution of adversarial AI.
  • The Hacker News, September 8, 2026: Autonomous AI agents compromise cloud infrastructure.

Impacted Systems

This is behavior-based threat activity rather than a product-specific vulnerability. Relevant environments include cloud identities, compute, public IP resources, secret stores, cloud API credentials, and network infrastructure. GTIG did not identify a single affected cloud provider, CVE, product version, or fixed build. Risk is highest where compromised identities can create compute, expose services, read secrets, or change privileges with limited guardrails.

Why this matters

A single compromised cloud identity or workload can become a high-velocity scanning and credential-harvesting platform. Traditional thresholds based on human operator speed may miss the earliest phase because resource creation, privilege changes, secret access, scanning, and source-IP rotation can cluster within minutes.

Exploitation Status

Confirmed observed threat activity by GTIG. Google reported a real campaign that compromised cloud infrastructure and executed an autonomous operational workflow in under six hours. No universal IOC set or cloud-specific exploit was published, so hunting is behavior-based.

What this hunt looks for

High-velocity cloud resource changes, bursts of public compute provisioning, new role assignments, abnormal secret access, Entra sign-in IP rotation, new sign-in IPs followed by Azure control-plane activity, AWS credential or compute creation bursts, and scanning-like network behavior.

Required logs

AzureActivity, Entra SigninLogs, Azure Key Vault diagnostics in AzureDiagnostics, AWSCloudTrail where AWS is in scope, and CommonSecurityLog for network-security telemetry.

First Pass – High-Velocity Azure Resource Changes by One Caller

AzureActivity
| where TimeGenerated >= ago(7d)
| where ActivityStatusValue =~ "Success"
| where OperationNameValue endswith "/WRITE" or OperationNameValue endswith "/ACTION"
| summarize Changes=count(),Resources=dcount(ResourceId),Operations=make_set(OperationNameValue,50),FirstSeen=min(TimeGenerated),LastSeen=max(TimeGenerated) by Caller,CallerIpAddress,bin(TimeGenerated,1h)
| where Changes >= 25 or Resources >= 10
| order by Changes desc

Burst Creation of Public IPs or Compute Resources

AzureActivity
| where TimeGenerated >= ago(7d)
| where ActivityStatusValue =~ "Success"
| where OperationNameValue has_any ("PUBLICIPADDRESSES/WRITE","VIRTUALMACHINES/WRITE","NETWORKINTERFACES/WRITE")
| summarize Events=count(),Operations=make_set(OperationNameValue,20),Resources=make_set(ResourceId,50) by Caller,CallerIpAddress,bin(TimeGenerated,1h)
| where Events >= 5
| order by TimeGenerated desc

New Azure Role Assignments

AzureActivity
| where TimeGenerated >= ago(30d)
| where OperationNameValue =~ "MICROSOFT.AUTHORIZATION/ROLEASSIGNMENTS/WRITE"
| project TimeGenerated,Caller,CallerIpAddress,ResourceGroup,ResourceId,ActivityStatusValue,CorrelationId
| order by TimeGenerated desc

High-Volume Azure Key Vault Secret or Key Access

AzureDiagnostics
| where TimeGenerated >= ago(7d)
| where ResourceProvider =~ "MICROSOFT.KEYVAULT"
| where OperationName has_any ("SecretGet","SecretList","KeyGet","KeyList")
| summarize Requests=count(),Operations=make_set(OperationName,20),Vaults=make_set(Resource,20),FirstSeen=min(TimeGenerated),LastSeen=max(TimeGenerated) by CallerIPAddress
| where Requests >= 50
| order by Requests desc

Entra Sign-In IP Rotation

SigninLogs
| where TimeGenerated >= ago(7d)
| summarize Attempts=count(),DistinctIPs=dcount(IPAddress),IPs=make_set(IPAddress,50),Countries=make_set(tostring(LocationDetails.countryOrRegion),20),Apps=make_set(AppDisplayName,20) by UserPrincipalName,bin(TimeGenerated,1h)
| where DistinctIPs >= 5
| order by TimeGenerated desc

Rare New Sign-In IP Followed by Azure Activity

let Known=SigninLogs
| where TimeGenerated between (ago(30d)..ago(2d))
| summarize by UserPrincipalName,IPAddress;
let NewSignins=SigninLogs
| where TimeGenerated >= ago(2d)
| join kind=leftanti Known on UserPrincipalName,IPAddress
| project SigninTime=TimeGenerated,UserPrincipalName,IPAddress;
NewSignins
| join kind=inner (AzureActivity | where TimeGenerated >= ago(2d) | project ActivityTime=TimeGenerated,Caller,CallerIpAddress,OperationNameValue,ResourceId,ActivityStatusValue) on $left.UserPrincipalName == $right.Caller
| where CallerIpAddress == IPAddress and ActivityTime between (SigninTime .. SigninTime + 2h)
| project SigninTime,ActivityTime,UserPrincipalName,IPAddress,OperationNameValue,ResourceId,ActivityStatusValue
| order by ActivityTime desc

AWS Credential and Compute Creation Bursts

AWSCloudTrail
| where TimeGenerated >= ago(7d)
| where EventName in~ ("CreateAccessKey","CreateUser","AttachUserPolicy","PutUserPolicy","RunInstances","CreateRole","AttachRolePolicy")
| summarize Events=count(),Actions=make_set(EventName,30),SourceIPs=make_set(SourceIpAddress,20) by UserIdentityArn,bin(TimeGenerated,1h)
| where Events >= 5
| order by TimeGenerated desc

Network Scanning From a Single Source

CommonSecurityLog
| where TimeGenerated >= ago(24h)
| where isnotempty(SourceIP) and isnotempty(DestinationIP)
| summarize Connections=count(),DistinctTargets=dcount(DestinationIP),DistinctPorts=dcount(DestinationPort),Targets=make_set(DestinationIP,50),Ports=make_set(DestinationPort,50) by SourceIP,bin(TimeGenerated,10m)
| where DistinctTargets >= 25 or DistinctPorts >= 20
| order by DistinctTargets desc

Detection Notes

The strongest signals are high-velocity administrative changes combined with unusual identities or new source IPs, rapid compute/public-IP creation, unexpected role assignments, and abnormal secret access. Legitimate deployment automation can create similar patterns, so change context is important. AWS hunting requires AWSCloudTrail ingestion, and Key Vault hunting requires diagnostic logs. Without cloud control-plane and sign-in telemetry, much of this activity may be invisible or appear only as generic network scanning.

Leave a comment