Threat Research
AI Security

NotC2: How We Built an AI-Powered C2 Channel With AWS Services

Varonis Threat Labs built NotC2, a proof-of-concept C2 framework that uses native AWS and Amazon Bedrock to process natural-language commands.

November 6, 2026
7

Key Takeaways

  • Cloud-Native C2: NotC2 uses trusted AWS services (SQS, Lambda, SNS, and Bedrock) to blend command channels into normal cloud activity.
  • AI-Powered Execution: Amazon Bedrock translates natural-language prompts into AWS API calls, lowering the technical barrier for post-compromise reconnaissance.
  • Defensive Shift: Because traditional network blocking fails, defenders must rely on strict IAM least privilege and monitoring service relationships.

Command and control traditionally relies on custom protocols and dedicated servers that security tools can detect and block. What happens when attackers abuse legitimate cloud services to build their C2 infrastructure instead? 

That question led us to NotC2, a proof-of-concept framework that combines native AWS services with Amazon Bedrock. NotC2 assumes the attacker already holds AWS credentials and explores how trusted cloud services can support post-compromise C2 operations while blending into normal activity.

C2 learned to hide in plain sight

NotC2 builds on a tactic attackers already use elsewhere: hiding command channels inside trusted services. Telegram and Discord bot APIs deliver commands and exfiltrate data; Slack webhooks disguise stolen data as internal notifications. Pastebin, GitHub Gists, and Google Sheets serve as dead drops for encoded commands, through domains few organizations can afford to block.

Cloud storage extends the same idea. Commands and exfiltrated data can flow through Amazon S3, Google Drive, OneDrive, and Azure Blob Storage. These services are so fundamental to business operations that blocking them is often impractical. When attacks use the same channels as legitimate activity, defenders can no longer rely on blocking known “bad” destinations.

AWS services can be abused in much the same way. XRayC2, built by Dhiraj Mishra, embeds commands in X-Ray trace annotations, while compromised hosts poll for tasks through the same monitoring API the application already uses. Rhino Security Labs demonstrated Cobalt Strike beacons using S3 objects as the communication channel, polling the bucket for task objects and writing results back as response objects. In both cases, communication occurs over encrypted HTTPS to trusted AWS endpoints and is signed with legitimate AWS credentials, helping the activity resemble normal cloud traffic.

Earlier techniques used one AWS service at a time. We asked a different question: what if the entire C2 loop ran on AWS, including command delivery, execution, results, and even the expertise normally supplied by the operator?

Meet NotC2

NotC2 is a post-compromise command-and-control tool built entirely on native AWS services. "Not" stands for notification, after the service that delivers results back to the attacker, and "C2" for command and control. The name is a deliberate joke: despite sounding like "not C2," it is a C2 framework designed to resemble legitimate AWS activity.

NotC2 leverages four core AWS services:

1. Amazon SQS (Simple Queue Service) - a fully managed message queuing service that organizations use to decouple microservices, process background jobs, and buffer high-traffic workloads. In NotC2, it is the command input channel: the queue receives commands from the attacker's external server. Because the architecture is asynchronous and decoupled, there is no persistent connection to spot, and native Lambda integration triggers execution automatically whenever a message arrives.

Figure 1: Amazon SQS queue list showing the command queue environment
Figure 2: Amazon SQS configuration for the NotC2 command queue
Figure 3: AWS CLI command used to create the NotC2 SQS queue

2. AWS Lambda - a serverless compute service that runs code in response to events, with no servers to provision or manage. In NotC2, it is the execution engine: an event source mapping invokes the function for each new SQS message. The function processes the command and executes AWS operations using its Lambda execution role, limited to that role’s permissions in the compromised account. Each invocation lasts no more than 15 minutes and leaves no persistent process, though its activity may still appear in cloud logs.

3. Amazon SNS (Simple Notification Service) - a fully managed pub/sub messaging service for fan-out notifications and workflow triggers. In NotC2, it is the results channel: the function publishes command output to a topic, and SNS sends it to the attacker's external endpoint after the HTTPS subscription has been confirmed. There is no polling on the attacker’s side, and SNS retries failed deliveries according to its delivery policy, improving reliability without guaranteeing delivery.

Figure 4: Python logic for creating or resolving the Amazon SNS topic
Figure 5: SNS message structure used to return command results

4. Amazon Bedrock - a fully managed service providing access to foundation models from leading AI companies through a single API. In NotC2, it is the AI command interpreter: it translates the attacker's natural-language commands into AWS API calls.

ServiceStandard useNotC2 useWhat shows up in logs
SQSMessage queuing for decoupled microservicesCommand input channel: the attacker sends commands to the queue for Lambda to processCreateQueue logged by default. SendMessage and ReceiveMessage require enabling data events, and even then the logs do not contain the message body
LambdaServerless compute for event-driven applicationsExecution engine: triggered by SQS, interprets commands, runs AWS operationsManagement API calls are logged by default. Invoke requires enabling CloudTrail data events. Executions and errors appear in CloudWatch Logs when logging permissions are configured.
SNSPub/sub notifications to multiple subscribersResults channel: publishes command output to the attacker's external endpointCreateTopic and Subscribe logged by default. Publish requires enabling, and the log does not contain the message body
BedrockManaged access to foundation modelsAI operator: translates natural-language commands into AWS API callsConverse calls logged by default. The prompt content and the model's response are not logged

The AI operator

Amazon Bedrock’s integration represents an evolution in C2 capabilities. Traditional C2 frameworks require operators to have deep technical knowledge of target systems and precise command syntax. NotC2's AI integration fundamentally changes this dynamic.

Instead of a command like this:

aws ec2 describe-instances --region us-east-1 --filters "Name=instance-state-name,Values=running" --query "Reservations[*].Instances[*].[InstanceId,InstanceType,PrivateIpAddress]"

The attacker can simply type:

ai: list all running EC2 instances with their IPs

Figure 6: Natural-language AWS request compared with equivalent CLI syntax

Behind the scenes, a single generic tool specification (execute_aws_operation) accepts a service, an operation, and its parameters, which provides a common interface for supported AWS services. The model:

  1. Receives the natural-language prompt
  2. Determines the appropriate AWS service and operation
  3. Invokes the tool with the correct parameters
  4. Receives the results and formats a human-readable response
  5. Can chain multiple operations for complex tasks
Figure 7: Generic Bedrock tool definition for executing AWS operations

Operations can also become adaptive. When the orchestration loop returns API results and errors to the model, it can revise the request or propose a follow-up operation. Reconnaissance becomes conversational: the attacker can ask “show me what I have access to” or “list the database resources I can access” and let the model propose the relevant API calls. This lowers the expertise required to use compromised cloud access and makes multi-step reconnaissance easier, without granting permissions the attacker does not already possess.

Figure 8: NotC2 command flow across SQS, Lambda, Bedrock, and SNS

What it takes to deploy

Every stage of the loop is assembled from services inside the victim's account, which means the whole operation stands or falls on the permissions of the compromised credentials. Those requirements are split into two distinct phases: (1) initial deployment, when the C2 infrastructure is created, and (2) runtime execution, when commands actually run.

Phase 1: deployment permissions

After gaining initial access to AWS credentials, the attacker needs permissions to create and configure the C2 infrastructure. The compromised credentials might not have these permissions initially, which means privilege escalation or the discovery of more privileged credentials. The usual starting points include:

Compromised credentialsTypical permissions
Developer credentialsBroad permissions for specific services (S3, Lambda, DynamoDB), but no IAM modification rights
Application service accountsNarrow permissions for running specific workloads
CI/CD pipeline credentialsMay have deployment permissions, but restricted IAM access
Compromised EC2/Lambda rolesService-specific permissions without administrative capabilities

In the simplest deployment path, where a suitable Lambda execution role already exists, the deploying identity needs sqs:CreateQueue, lambda:CreateFunction, lambda:CreateEventSourceMapping, and iam:PassRole for that role. 

If the identity must create or modify the role, it also needs the relevant IAM role and policy-management permissions. Additional permissions may be required depending on how the function package, encryption, networking, and logging are configured.

Phase 2: the Lambda execution role

The Lambda function requires broad permissions to execute arbitrary AWS operations on behalf of the attacker. This is the operational heart of NotC2. 

The runtime role needs sqs:ReceiveMessage, sqs:DeleteMessage, and sqs:GetQueueAttributes to poll the queue; sns:CreateTopic and sns:ListSubscriptionsByTopic to validate the results topic and create it if needed; sns:Subscribe to attach the attacker's external server; sns:Publish to send results; and bedrock:InvokeModel to drive the AI interpreter. 

On top of that, the role needs permissions on the target resources themselves: listing S3 buckets requires s3:ListAllMyBuckets, and so on for every service the attacker wants to touch.

The attacker's best path is reusing existing roles wherever their permissions allow it, and enumeration tools like Pacu are built to find exactly that path, though enumeration itself needs permissions, typically List actions. A Lambda execution role that accumulates all of this is, functionally, a backdoor with an AI assistant.

The demo

We ran NotC2 against a live AWS environment. The full attack chain, from the first natural-language command to the results arriving at the attacker's server, is in the demo video:

Impact

To demonstrate the potential impact and ease of use, here are a few more visualized examples that do not appear in the demo video:

‍

Figure 10: NotC2 enumerating EC2 instances in the target AWS account
Figure 11: NotC2 discovering DynamoDB tables in the target AWS account
Figure 12: NotC2 identifying relational and NoSQL databases in the target account
Figure 13: NotC2 listing and highlighting Lambda functions in the target account

With appropriate permissions, a threat actor can perform destructive activity as well, such as remotely deleting all S3 buckets or EC2 instances.

The signal moved, it did not disappear

As explored above, cloud-native C2 presents a fundamentally different detection challenge.

Most of NotC2's command loop runs over encrypted HTTPS to trusted AWS endpoints, and every API call is signed with valid credentials. Results leave through SNS, so the Lambda function never connects to the attacker's server directly. The usual network indicators, such as suspicious domains, unknown IP addresses, custom protocols, and beaconing, largely vanish from the network. That holds even when the beaconing is jittered, as our Jitter-Trap research showed.

The activity, however, carries on inside the victim's own cloud logs. The signal is scattered across CloudTrail management and data events, Lambda execution logs, SNS delivery-status logs, and Bedrock model invocation logs. Management events reveal how the infrastructure was created and configured, and CloudTrail records them by default. The data events that expose the actual message flow are higher-volume and require explicit configuration.

What defenders can see

ServiceVisible by defaultRequires additional loggingWhat remains hidden or appears elsewhere
Amazon SQSManagement events such as CreateQueue and SetQueueAttributesData events such as SendMessage, ReceiveMessage, and DeleteMessageThe caller, source, time, and queue are visible, but the message body is redacted
AWS LambdaManagement events such as CreateFunction, CreateEventSourceMapping, and configuration changesInvoke is a Lambda data event and must be enabled explicitlyWhen logging permissions are present, CloudWatch Logs records executions, including START, END, and REPORT entries. Operations performed by the execution role appear in the relevant downstream services’ logs
Amazon SNSManagement events such as CreateTopic and SubscribePublish and PublishBatch are data eventsPublished message content and attributes are redacted. Separately configured delivery-status logs can show whether delivery to an HTTP or HTTPS endpoint succeeded
Amazon BedrockRuntime operations such as Converse and InvokeModel appear as CloudTrail management eventsBedrock model invocation logging must be enabled to capture model input and outputStandard CloudTrail records show that the model was invoked, but not the complete prompt or response

This distinction matters quite a lot. Seeing a queue, function, topic, or model invocation is not the same as seeing the command that passed through it. CloudTrail redacts SQS and SNS message content, while prompt-level Bedrock visibility comes from model invocation logging rather than the standard CloudTrail event.

Detection opportunities

Despite using legitimate AWS services, NotC2 presents several opportunities for detection:

1. Anomalous SNS subscriptions may indicate malicious activity. An SNS subscription created by a Lambda execution role that points to an external HTTP or HTTPS endpoint should be investigated. Legitimate Lambda workflows rarely create new external subscriptions at runtime, particularly to destinations the organization has not previously used.

2. Unusual Bedrock activity can provide another warning sign. A sudden increase in Converse or InvokeModel calls made under a Lambda execution role may be suspicious, especially if the function or role has not previously used Bedrock. The signal becomes stronger if the same role also begins accessing unrelated AWS services.

3. The complete NotC2 sequence can reveal the C2 loop. With the relevant logs enabled, defenders can correlate an SQS message from an unexpected source with a Lambda execution, Bedrock activity, downstream AWS API calls, and an SNS publish to an external subscriber within a short period. None of these events is inherently malicious on its own, but their sequence across the same queue, function, and topic provides a detection signal.

How defenders can close the gap

Those same dependencies also give defenders several ways to disrupt the attack chain:

1. Enforce strict IAM least privilege

Prevent identities and Lambda execution roles from accumulating permissions they do not require. Pay particular attention to the ability to create queues and functions, configure event source mappings, pass powerful roles to Lambda, invoke Bedrock, and create external SNS subscriptions.

This is the highest-leverage control. If a compromised identity cannot assemble the infrastructure, or if the Lambda execution role cannot access unrelated AWS resources, the NotC2 chain fails.

2. Restrict external communication paths

Limit unrestricted internet access from Lambda functions that do not require it. Direct egress controls reduce opportunities for additional payload delivery and direct exfiltration, but they do not stop NotC2 by themselves because SNS performs the external delivery.

Pair Lambda network restrictions with controls on SNS. Restrict who can create or modify external HTTP and HTTPS subscriptions, allow only approved external destinations, and limit functions to publishing through their intended topics. If the function cannot establish an external subscriber or publish results through a topic connected to one, the results channel fails.

What NotC2 actually proves

NotC2 shows where perimeter-focused security breaks down in serverless environments. 

When command delivery, execution, AI interpretation, and result handling all run through native services inside the victim's AWS account, there is no conventional C2 server to block. Defenders have to focus on workload identities, service relationships, and deviations from expected behavior.

Amazon Bedrock lowers the skill required to operate the framework. It turns natural-language commands into AWS API operations, speeding up cloud reconnaissance and making compromised access easier to use. The model stays within the identity’s assigned permissions. It helps the attacker understand and exploit whatever access those permissions allow.

NotC2 only works when the attacker can create or reuse the required infrastructure, attach a powerful execution role, invoke Bedrock, reach target resources, and establish a results channel. Block any one of those steps and the chain fails.

Security Researcher

Or Soria is a Security Researcher within the Varonis Research Team. Passionate about data-driven threat hunting, she specializes in turning anomalies into smarter, sharper detections. She's currently pursuing a Master's in Cyber and National Relations and likes chasing adventures around the world.

Ready to see Varonis in action?

Schedule a demo
https://cdn.prod.website-files.com/6aad3cd63e81c645c771a0be/6aad48e61926ad27c8821c7b_varonis-conversion-blue.mp4
https://www.youtube-nocookie.com/embed/717uPD8k5nc