# NotC2: Proof-of-Concept Framework Abuses Amazon Bedrock, SQS, Lambda and SNS as Cloud Command-and-Control

> Varonis Threat Labs (published 2026-11-06) describes NotC2, a proof-of-concept post-compromise C2 framework that chains Amazon SQS, Lambda and SNS with Amazon Bedrock as a natural-language interface to AWS APIs. It is abuse of legitimate services with already-held credentials, not a Bedrock vulnerability or initial-access exploit, and no in-the-wild use is reported.

- **Published:** 2026-11-09T06:02:18Z
- **Last reviewed:** 2026-11-09T06:02:18Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-5527
- **Card image:** https://intel.threadlinqs.com/og/threat/TL-2026-5527.png
- **ID:** TL-2026-5527
- **Severity:** MEDIUM
- **Category:** MALWARE
- **Status:** MONITORING
- **Detections:** 9 (1 shown free below) · **IOCs:** 7

## Description

NotC2 is a proof-of-concept post-compromise command-and-control framework built by Varonis Threat Labs (author credited: Or Soria, Varonis Research Team). The name derives from 'notification' (the SNS service that returns results to the operator) plus 'C2'. It distributes command delivery, execution, interpretation and result return across four native AWS services so that the traffic resembles routine cloud activity.

Architecture: (1) An external attacker server submits a natural-language command (example prompt: 'ai: list all running EC2 instances with their IPs') to an Amazon SQS queue in the compromised account. (2) A Lambda event source mapping invokes a Lambda function for each new SQS message; each invocation is limited to 15 minutes and leaves no persistent implant process. (3) The function sends the prompt to Amazon Bedrock (Converse / InvokeModel), which acts as the interpreter and translates it into AWS API calls through a single generic tool specification, execute_aws_operation, that accepts a service, an operation and parameters. API responses and errors are returned to the model, which can revise its request or chain follow-up operations. Lambda executes the resulting calls under its execution role. (4) Results are published to an Amazon SNS topic, which delivers them to an attacker-controlled HTTPS endpoint after the attacker confirms the subscription; the Lambda function never contacts the attacker directly.

Prerequisites and IAM: the technique does not bypass IAM authorization or create permissions; the attacker must already hold credentials with sufficient rights. Deployment needs, in the simplest case, sqs:CreateQueue, lambda:CreateFunction, lambda:CreateEventSourceMapping and iam:PassRole for an existing Lambda role (creating or modifying a role needs additional IAM permissions). The runtime role needs sqs:ReceiveMessage, sqs:DeleteMessage, sqs:GetQueueAttributes, sns:CreateTopic, sns:ListSubscriptionsByTopic, sns:Subscribe, sns:Publish, bedrock:InvokeModel, plus permissions for whatever target services are queried (e.g. s3:ListAllMyBuckets). Varonis notes enumeration tools such as Pacu can help find reusable roles with sufficient permissions. Researchers demonstrated enumeration of EC2 instances, DynamoDB tables, relational and NoSQL databases and Lambda functions in a live AWS environment; destructive actions (e.g. deleting S3 buckets or EC2 instances) are described as possible with sufficient permissions but were not demonstrated. The practical effect is lowering the expertise needed to use stolen cloud access and easing multi-step reconnaissance.

Detection: Network blocking is insufficient because traffic goes to legitimate AWS endpoints, and Lambda egress restrictions alone cannot stop SNS-mediated delivery. The decisive signal is an unusual relationship between otherwise legitimate services. Varonis recommends correlating CloudTrail management and data events (data events must be explicitly enabled), Lambda execution logs, SNS delivery-status logs and Bedrock model invocation logs (needed for prompt visibility, since CloudTrail redacts SQS/SNS message content). Key indicators: SNS subscriptions created by Lambda execution roles pointing at external HTTP/HTTPS endpoints; Converse/InvokeModel calls from Lambda roles that have not used Bedrock before or that begin touching unrelated services; and a short-window sequence of SQS message from an unexpected source, Lambda execution, Bedrock activity, downstream API calls and an SNS publish to an external subscriber.

Context: the source lists no CVE, CVSS, IOCs, attribution or code repository. Code has not been released, so exploitability is rated THEORETICAL on the platform scale although the PoC was demonstrated by the researchers. Severity MEDIUM is the analyst's judgment. Related cloud-native C2 research includes Rhino Security Labs' Cobalt Strike over S3, the HazyBeacon campaign (CL-STA-1020, Lambda Function URL proxying), Sonrai's AgentCore Code Interpreter global-S3 reverse shell and Upwind's AgentCore OIDC-discovery C2.

## MITRE ATT&CK

- T1102.002 Web Service: Bidirectional Communication
- T1071 Application Layer Protocol
- T1648 Serverless Execution
- T1059.009 Command and Scripting Interpreter: Cloud API
- T1078.004 Valid Accounts: Cloud Accounts
- T1580 Cloud Infrastructure Discovery
- T1526 Cloud Service Discovery

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**NotC2 - SNS HTTP/HTTPS Subscription Created by Assumed Role (Result-Return Channel)** (`TL-2026-5527-SPL-003`)

TL-2026-5527 NotC2 result-return channel. Detects sns:Subscribe with protocol http or https issued by an assumed-role session, flagging Lambda-originated subscriptions (exec-env/AWS_Lambda user agent) as highest priority. In NotC2 the function publishes command output to an SNS topic whose external HTTPS subscription delivers it to the operator, so the Lambda never connects out directly. This is the primary indicator Varonis recommends alerting on.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1102.002, T1071, T1041
- **Data sources:** aws_cloudtrail:index=aws sourcetype=aws:cloudtrail, AWSCloudTrail, cloudtrail
- **Severity:** high
- **Confidence:** high

### Splunk SPL

```spl
index=aws sourcetype="aws:cloudtrail" earliest=-24h eventSource="sns.amazonaws.com" eventName="Subscribe" userIdentity.type=AssumedRole NOT errorCode=*
| eval protocol=lower('requestParameters.protocol'), endpoint='requestParameters.endpoint'
| where protocol="http" OR protocol="https"
| eval endpoint_host=replace(endpoint,"^https?://([^/:]+).*$","\1")
| eval lambda_context=if(match(userAgent,"exec-env/AWS_Lambda"),"yes","no")
| eval endpoint_class=if(match(endpoint_host,"[.]amazonaws[.]com$"),"aws_hosted","non_aws")
| table _time recipientAccountId awsRegion userIdentity.arn sourceIPAddress userAgent requestParameters.topicArn protocol endpoint endpoint_host lambda_context endpoint_class
| sort - _time
```

### Microsoft KQL

```kql
AWSCloudTrail
| where TimeGenerated > ago(24h)
| where EventSource == 'sns.amazonaws.com' and EventName == 'Subscribe' and UserIdentityType == 'AssumedRole' and isempty(ErrorCode)
| extend Req = parse_json(RequestParameters)
| extend Protocol = tolower(tostring(Req.protocol)), Endpoint = tostring(Req.endpoint), TopicArn = tostring(Req.topicArn)
| where Protocol in ('http', 'https')
| extend LambdaContext = UserAgent has 'exec-env/AWS_Lambda'
| extend EndpointHost = extract(@'^https?://([^/:]+)', 1, Endpoint)
| project TimeGenerated, RecipientAccountId, AWSRegion, UserIdentityArn, SourceIpAddress, UserAgent, TopicArn, Protocol, Endpoint, EndpointHost, LambdaContext
| order by TimeGenerated desc
```

### Sigma

```yaml
title: NotC2 - SNS HTTP or HTTPS Subscription Created by Assumed Role
id: c4d91e60-7a2b-4e83-b5f1-0d3a68e92c03
status: experimental
description: Detects an SNS Subscribe call with an http or https protocol made by an assumed-role session. NotC2 uses an external HTTPS SNS subscription to return command results to the operator. Highest priority when the user agent shows a Lambda execution environment.
references:
  - https://www.varonis.com/blog/notc2-ai-powered-c2-channel
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-11-09
tags:
  - attack.command-and-control
  - attack.t1102.002
  - attack.t1071
  - attack.exfiltration
  - attack.t1041
logsource:
  product: aws
  service: cloudtrail
detection:
  selection:
    eventSource: sns.amazonaws.com
    eventName: Subscribe
    userIdentity.type: AssumedRole
    requestParameters.protocol:
      - http
      - https
  filter_error:
    errorCode|exists: true
  condition: selection and not filter_error
falsepositives:
  - Approved webhook integrations (PagerDuty, Slack, SaaS monitoring) subscribed to SNS topics by automation roles
level: high
```

**Known false positives:**

- Approved webhook subscriptions (incident-response, chat-ops or SaaS monitoring endpoints) created by automation roles
- Infrastructure-as-code pipelines provisioning HTTPS SNS subscriptions to partner endpoints

**Tuning notes:** Allowlist approved endpoint hosts and the automation roles that create them (lookup on endpoint_host and userIdentity.arn). Prioritise lambda_context=yes with endpoint_class=non_aws. Remember the endpoint must confirm the subscription, so also review SNS delivery-status logs for the same topic ARN. Enable CloudTrail management events for SNS in all regions.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- NotC2 - First-Time Bedrock Invocation From a Lambda Execution Role (locked: unlock with TL Creds)
- NotC2 - Lambda Role Uses Bedrock and SNS Within 30 Minutes (Command-to-Result Sequence) (locked: unlock with TL Creds)
- NotC2 - execute_aws_operation Tool Specification in Lambda or Bedrock Logs (locked: unlock with TL Creds)
- NotC2 - Lambda Role Creates SNS Topic and Subscription at Runtime (locked: unlock with TL Creds)
- NotC2 - SQS Queue Policy or Permission Grants SendMessage to External or Wildcard Principal (locked: unlock with TL Creds)
- NotC2 - IAM Policy Grants Bedrock Invoke Plus SNS and SQS Runtime Permissions (locked: unlock with TL Creds)
- NotC2 - Queue-to-Lambda Deployment Chain (CreateQueue + CreateFunction + SQS Event Source Mapping) (locked: unlock with TL Creds)
- NotC2 - Lambda Role Combines Bedrock Invocation With Multi-Service Discovery (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sources

- [NotC2: AI-Powered C2 Channel (Varonis Threat Labs)](https://www.varonis.com/blog/notc2-ai-powered-c2-channel)
- [NotC2 AI-Powered Hacking Tool Turns Amazon Bedrock Into a Cloud Command-and-Control System (GBHackers)](https://gbhackers.com/notc2-ai-powered-hacking/)
- [HazyBeacon abuses AWS Lambda function (GBHackers)](https://gbhackers.com/hazybeacon-abuses-aws-lambda-function/)
- [Global S3: Another C2 Channel for AgentCore Code Interpreters (Sonrai Security)](https://sonraisecurity.com/blog/global-s3-another-c2-channel-for-agentcore-code-interpreters)
- [No Way Out? Bypassing the AWS Data Perimeter with Bedrock AgentCore (Upwind)](https://www.upwind.io/?p=21407)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-5527
