Dead Drop Resolver
Malware reads its real C2 address from content stashed on a legitimate website or social profile, hiding the live infrastructure behind a trusted host.
A dead drop resolver decouples the implant from its real command-and-control server. Instead of hard-coding a C2 IP or domain, the malware first reaches out to a perfectly legitimate, high-reputation host — a GitHub README, a TechNet forum post, a Twitter or microblog profile, a Pastebin entry, a comment on a blog — and reads a small piece of attacker-controlled content there. That content, often obfuscated or encoded, contains (or decodes to) the address of the live C2. The legitimate site is the resolver; it never carries actual C2 traffic.
The payoff for the attacker is resilience and stealth. The initial outbound request goes to a domain that egress filters and proxies trust, blending into normal browsing. When the operator wants to rotate infrastructure, they simply edit the dead-drop content; takedowns of one C2 don't break the implant, which just re-reads the resolver for the new address. BLACKCOFFEE hid its C2 inside encoded strings on TechNet forum pages, MiniDuke pulled tasking from Twitter accounts (with a GitHub/Reddit fallback), and HAMMERTOSS chained Twitter, GitHub, and cloud storage.
For an analyst the goal is to identify the resolver URL, recover the decoding routine, and follow the breadcrumb to the second-stage address before the operator rotates it.
How it works
The implant fetches a resolver page, locates a marker, and decodes the bytes between markers into the real C2 endpoint:
// Illustrative resolver-read logic — descriptive, not deployable.
// Fetch a benign page, extract the tagged blob, decode to a C2 address.
int resolve_c2(const char *resolver_url, char *c2_out, size_t out_len)
{
char page[8192];
http_get(resolver_url, page, sizeof page); // benign, trusted host
// operator wraps the payload in a fixed sentinel pair
char *start = strstr(page, "@@MNGR@@"); // begin marker
char *end = start ? strstr(start, "@@END@@") : NULL;
if (!start || !end) return -1;
size_t blob = (size_t)(end - (start + 8));
base64_decode(start + 8, blob, c2_out, out_len); // -> "203.0.113.10:443"
return 0;
}The decoded value may be a raw IP:port, a domain, or a further-encrypted blob. Tells for a reverser: a hard-coded URL pointing at a social/dev/paste platform, a sentinel/marker string pair, and a decode routine (base64, XOR, custom alphabet) whose output is then fed into the connection logic rather than displayed. Many families layer the resolver behind the platform's own API (a GitHub Gist raw URL, a Twitter user-timeline endpoint) so the request looks like an ordinary API call.
Detection & analysis
Static analysis:
- Recover the resolver URL and the marker strings. A hard-coded link to a public profile, gist, paste, or forum thread — especially paired with sentinel tokens and a decoder whose output never reaches the UI — is the defining static signature. The decode routine tells you exactly how to read the dead drop yourself.
- Trace the data flow from the HTTP response into the decoder and onward into
connect/WSAConnect/socket setup. If the decoded bytes become a connection target, you have confirmed a resolver and can recover the live C2 once you fetch and decode the current page. - Note any account names, gist IDs, or search terms embedded in the binary — these identify the specific attacker-controlled drop and let defenders request takedown or monitor for rotation.
Dynamic analysis:
- Detonate in a sandbox with full proxy logging. The first beacon will be a GET to a legitimate platform, followed (after a pause) by a connection to a previously unseen address — that second hop is the resolved C2. Capture both.
- Diff the fetched resolver content against the platform's normal page to isolate the injected blob, then run it through the reversed decoder to read the C2 endpoint directly.
- Watch for a process that contacts a developer/social/paste site but does not otherwise behave like a browser (no referrers, no asset loads, a single bare API request) and then immediately opens a session to an unrelated host.
Detection rule hint:
Alert when a non-browser process issues a single bare request to a known dead-drop-capable platform (gist/pastebin/raw social API) and, within a short window, initiates an outbound connection to a fresh, low-reputation IP that never appeared in DNS or web logs before — the trusted-fetch-then-pivot-to-unknown-host sequence, with no surrounding browser traffic, is the behavioural fingerprint of a dead drop resolver.