The pattern repeats itself: “weird” traffic no longer looks weird. A Command & Control (C2) channel that goes through legitimate cloud services inherits their reputation, their encryption, and their appearance as standard corporate activity. What used to be “an IP on a VPS” can today be a call to a storage API, a query to a repository, or a pull to a CDN endpoint.
In corporate environments this has a double impact: on the one hand, perimeter controls tend to allow those domains (because the business needs them); on the other, IT teams often have accumulated exceptions (proxy, CASB, firewalls, egress) that facilitate camouflage. The result is that detecting and cutting C2 without breaking operations requires discipline and well-chosen telemetry.
What went wrong: why a “legitimate” C2 passes through controls that do work against traditional C2
When C2 relies on cloud services, the attacker benefits from three things that in enterprises we usually consider “good”: TLS by default, shared high-prestige endpoints, and access patterns that are confused with internal automation. At the proxy or firewall level, blocking “the whole domain” is rarely viable if we are talking about providers used by developers or by the business itself.
The real consequence is operational: the SOC sees an outbound flow to a recognized provider and does not escalate it; or it escalates it, but IT downgrades it because there is a pipeline that “always talked to that”. In real incidents, the time lost often comes from internal discussions about exceptions, not from a lack of technical indicators.
There is also a cost angle: many “legitimate” C2 channels use cheap APIs with high quotas. If the malware also implements backoff and jitter, the traffic looks even more human and less like “beaconing”. That shifts the focus from volume-based detection to identity-based (who) and context-based detection (from where and for what).
How it materializes: abuse patterns over storage, messaging, repositories, and functions
The basic idea is simple: the attacker needs a mailbox for instructions and a mailbox for results. Cloud services offer this in multiple formats (objects, messages, issues, releases, secrets, blobs, queues). Instead of a persistent socket, it uses “polling” to an API with authentication and normal JSON/HTTP responses.
In enterprises, this blends with legitimate integrations: CI/CD agents that download artifacts, scripts that consume webhooks, serverless functions that call external APIs. If authorization is not anchored to expected identities and networks, the C2 channel remains protected by our own permissiveness.
- Object storage as a mailbox: objects that are updated with commands and read periodically. In operations, it looks like repeated GET/HEAD to a bucket/container with seemingly random names.
This hurts especially when the environment uses that same provider for data lakes or backups. A security team can block by “path” or “bucket” only if it has identity control (which credential accesses) and context control (from which subnet/egress), not just by domain.
- Repositories and “paste” as a text channel: issues, gists, snippets, or comments where the attacker posts instructions and the agent exfiltrates results as commits or comments.
At the corporate level, the signal is not “accesses a repo”, but “accesses a repo that does not belong to the organization” or “accesses with a token that does not come from the corporate SSO flow”. Without that distinction, development noise masks the incident.
- Messaging/queues: queues or topics as a control-plane (commands) and data-plane (results). On networks, it looks like telemetry or asynchronous integration.
The risk here is bypassing classic DLP: the content travels encapsulated as small messages, often compressed or application-level encrypted. If egress is open for “integrations”, the attacker only needs credentials or an embedded token.
Early signals that do work: identity, periodicity, and “usage context” above domains
Effective detection of C2 over legitimate cloud is not won with a domain list (because they are the same ones the company uses), but with identity and behavior correlations. In incidents, what makes the difference is responding to “which workload/user initiated this?” and “is it consistent with its purpose?” more than “where did it go?”.
In practice, there are usually three useful signals: periodicity (beaconing with jitter), use of credentials outside their expected environment (token on a non-corporate endpoint, from an egress IP that does not match), and creation/reading of resources with naming or patterns foreign to internal standards. When the attacker uses cloud services, they often leave traces in API logs: repetitive calls, authorization errors, or prior “enumeration”.
- API access with weak or unexpected identity: static keys on endpoints that should use SSO/OIDC, or tokens used from user workstations when they should be used from runners/services.
A typical case: a personal token appears in proxy telemetry from a laptop, accessing an “integration” resource. If your organization expects those integrations to egress from a fixed VPC/egress, that deviation is a high-value alert.
- Constant “polling” pattern: small requests every N seconds/minutes to the same resource, with slight variation.
This often goes unnoticed if you only look at volume. It works better if you aggregate by process/host (EDR), by user-agent, and by logical destination (path/API). In mature enterprises, this materializes as detection rules by periodicity and by destination “rarity” relative to the asset’s role.
How to do it in practice: verifiable guardrails in AWS (example) to reduce C2 over legitimate services
The most consistent way to reduce “legitimate” C2 is to limit who can talk to what and from where, and leave traceability on every call. In AWS, this translates into: (1) controlled egress (NAT/egress proxy), (2) access to services via private endpoints when applicable, and (3) IAM policies that restrict by organization, network, and role.
A concrete pattern: if your standard is that workloads access S3 only to buckets in your organization, enforce that contract by policy. That way, even if malware obtains credentials from a role, it will have a hard time using S3 as a mailbox in an external bucket. The same applies to other services when an equivalent condition exists.
Example IAM policy (illustrative) to limit access to S3 to buckets under your control and harden sensitive actions. Adjust to your needs and validate with tests in a non-production environment:
- Restrict by organization (S3 Access Points/account conditions): use conditions such as
aws:ResourceAccountto prevent access to resources in other accounts when the role should only operate in your own accounts.
In operations, this prevents the classic C2 case that writes/reads from an attacker’s bucket. If a legitimate application needs cross-account access, it is handled explicitly (with dedicated roles), instead of leaving it open “just in case”.
- Enforce expected endpoints: when you use VPC endpoints for AWS services, combine routing and egress control so that traffic to APIs goes through the intended path, not the open Internet.
The gain here is double: you reduce the exfiltration surface and increase visibility. When the endpoint is private, you can correlate at the VPC Flow Logs/CloudTrail level more accurately and detect deviations (e.g., API calls from unauthorized subnets).
- Block “unlikely” actions for the role: explicitly deny listing or administration operations if the role should only read/write specific prefixes.
In real incidents, the attacker often explores (List/Enumerate) before using the channel. Removing that capability reduces implantation time and increases the number of errors, which generates signals in CloudTrail and in the runtime itself.
Validation: verify that CloudTrail is enabled at the organization/account level and that you capture data events where they add value (for example, on critical buckets). Check that workload roles do not have wildcard permissions and that cross-account accesses are justified. On the network side, validate that Internet egress from server subnets passes through the defined control points and that there are no alternative routes (parallel NATs, permissive SG/NACL) that allow bypassing inspection.
Recommendations for corporate environments
A C2 channel based on legitimate cloud services works because it leverages what the enterprise already allows: reputable domains, TLS, common APIs, and historical exceptions. The defense that scales best is not to block providers, but to add friction where the business does not notice it: strong identity, least privilege, and controlled egress paths.
Operationally, prioritize context-based detections: call periodicity, unusual destinations for the asset’s role, and use of credentials outside the expected flow (SSO/OIDC vs static tokens). When you find a suspicious pattern, the goal is not to “close the Internet”, but to cut the specific path: revoke credentials, restrict policies, and force access to go through traceable corporate endpoints/egress.
If your guardrails are verifiable (CloudTrail and data events where appropriate, IAM policies with conditions, egress without parallel routes), “legitimate” C2 stops being invisible: it becomes costly for the attacker and faster to isolate without disrupting the teams that truly need those services.
Interested in Cloud Security?
Technical analysis, hands-on labs and real-world cloud security insights.