Contribution
This post adds a defensive detection method for direct-to-IP command-and-control that works across AWS, Azure and GCP. Its original contribution is a DNS provenance join: retain the IP answers returned to each workload, join them to later network flows, then investigate accepted public egress that has no preceding answer. The method also adds an escalation path for FTP-banner dead drops, where a small port 21 exchange is the configuration event and the later web connection is the payload channel.
The pattern
DNS monitoring has an awkward blind spot. It can tell a defender which names a workload requested, but malware does not have to request a name. A hard-coded address can take the resolver out of the path entirely. The resulting connection still crosses the cloud network boundary, yet a DNS-only control sees no query to classify, block or sinkhole.
Unit 42 measured this gap across more than four million dynamic-analysis reports collected during a 30-day period. Among samples with command-and-control activity, 45.32 per cent made at least one direct-to-IP connection. Direct-to-IP traffic accounted for 23.17 per cent of all C2 connection attempts. After the researchers removed bulk port-scanning behaviour, the sample figure remained 41.97 per cent. These are study results, not an alert threshold, but they make a narrow point: a clean DNS log is not evidence of clean egress.
The examples span several different network shapes. A Phorpiex dropper fetched configuration and later payloads from a raw IP address. A separate campaign sent an obfuscated \\GET request directly to rotating public-cloud addresses. The request began with a backslash followed by GET, then carried an encoded string between 250 and 666 characters. SectopRAT used direct IP connections for browser-proxy traffic, including /churl requests that relayed visited URLs and /fsave requests that carried submitted form fields. Mozi and the Boatnet Mirai variant used direct addresses for payload delivery to older and embedded systems.
A second research stream shows that the first raw-IP connection does not have to be the final C2 channel. SOCRadar documented active abuse of FTP banners as dead-drop resolvers. A malicious shortcut contacted an FTP service and read attacker-supplied commands from the server's initial banner. Those commands led to WebDAV retrieval and DLL execution. Further infrastructure analysis found two previously undocumented remote-access tools, E4del and PINHOLE, in separate clusters using the same delivery idea.
E4del ran malicious Electron code under a signed Discord executable, established login persistence and communicated through encrypted HTTP posts to a hard-coded address. PINHOLE used PowerShell, a command script and certutil during delivery, then obtained later C2 configuration through legitimate web services and Cloudflare Workers. The FTP banner was therefore a bootstrap channel. Treating the final HTTPS session as the only observable C2 event loses the earlier, stranger connection that explained how the host learnt what to do next.
The two studies expose the same control failure from opposite directions. Direct-to-IP malware avoids DNS because it already knows an address. FTP-banner abuse avoids embedding the complete instruction or final address because it retrieves configuration from a protocol response. In both cases, the defender needs to ask whether an outbound destination has a recorded naming history, then correlate unexplained egress with endpoint execution and later data movement.
Why it matters to cloud defenders
Cloud workloads produce the right ingredients, but providers store them in separate products. Network flow logs record source and destination addresses, ports, protocol, direction and traffic volume. Resolver logs record names and returned answers. Asset inventory ties an interface address to an instance, container node or serverless workload. Endpoint or runtime telemetry supplies the process that opened the connection. A useful alert joins those planes instead of asking any one log to prove command-and-control.
AWS documents VPC Flow Logs as records of IP flows on network interfaces, normally described by a five-tuple. Route 53 Resolver query logging can record the originating VPC, source address, instance identity, query name, record type, response code and returned answer. There is a catch: the Resolver logs unique queries and does not write another event when it serves the answer from cache. A detector must therefore retain the first answer for its TTL rather than demand a DNS event immediately before every connection.
Azure virtual network flow logs operate at Layer 4 and record flows across a virtual network at one-minute intervals. Their records include the network interface, five-tuple, direction, state and throughput. Google Cloud VPC Flow Logs aggregate sampled packets by IP connection and can cover VM instances, GKE nodes, Direct VPC egress from Cloud Run, VLAN attachments and Cloud VPN tunnels. Google states plainly that packet sampling is involved, so a missing flow cannot be read as proof that no connection occurred.
The DNS side also differs. Cloud DNS logging tracks queries resolved for VPC networks and can include Compute Engine instances, GKE containers and on-premises clients using inbound forwarding. Each provider has different coverage and retention. The normalised join below is portable, but the confidence attached to a negative match must reflect those gaps.
Direct-to-IP C2 matters most on workloads where DNS is expected to explain nearly all public egress. A build runner that contacts fixed package mirrors, a backend that reaches a short list of APIs or a private cluster with an egress proxy should have a high DNS-coherence baseline. A browser host, public recursive resolver, CDN node or vulnerability scanner will naturally contact many addresses that are hard to attribute to one local query. The detector should apply that distinction per workload role, not suppress raw-IP traffic across the estate.
The cloud consequence arrives after execution. A remote-access tool on a build worker may reach environment variables, registry tokens or workload credentials. On a user desktop, PINHOLE's reported browser-credential capability and SectopRAT's captured form fields can lead to session theft. The data payoff may then leave through the same channel under ATT&CK T1041, Exfiltration Over C2 Channel. Capability is not proof of use, so responders should separate confirmed network and process events from possible credential or data exposure.
ATT&CK mapping
The observed entry in the FTP-banner chain maps to T1204.002, User Execution: Malicious File. SOCRadar's starting artefact was a malicious shortcut presented through a Spanish-language lure. The technique describes the user action that starts the chain; it does not describe the later FTP traffic.
Execution maps to T1059, Command and Scripting Interpreter. The documented delivery used PowerShell and command scripts, with certutil and archive expansion in the PINHOLE path. T1059.001, PowerShell, is the more precise sub-technique for that stage, but the parent is listed in the article metadata because it already has a hand-authored a13e technique page. T1105, Ingress Tool Transfer, also applies where the chain downloads the next script, archive or binary; it remains in prose because it does not yet have that page.
Command-and-control maps to T1071.001, Application Layer Protocol: Web Protocols. Unit 42 observed HTTP, HTTPS and WebSocket examples, while SOCRadar described HTTP posts and web-service-backed configuration after the FTP bootstrap. Direct addressing changes how the destination is found. It does not stop HTTP or WebSocket from being the application-layer protocol.
The chain ends at collection or exfiltration only when telemetry supports it. SectopRAT's /fsave traffic is direct evidence of submitted fields leaving a victim in Unit 42's analysed activity. E4del and PINHOLE have file, screenshot or credential-related functions, but a function in malware does not prove that an operator invoked it on every host. Map T1041 only after the C2 channel carries collected data, and preserve the relevant proxy, packet or endpoint evidence.
Detection guidance
Build a short-lived DNS answer ledger before writing the alert. For each successful A or AAAA answer, retain workload_id, answer_ip, query_name, answer_time and expiry_time. Derive the expiry from the returned TTL where the log supplies it. Where it does not, use a bounded local retention value and mark the match as lower confidence. Store workload identity rather than source address alone because addresses are reused and network address translation can merge several callers.
Normalise accepted public egress into network_flows with workload_id, flow_time, destination_ip, destination_port, protocol, bytes_sent and bytes_received. The first-stage hunt is an anti-join:
SELECT
f.workload_id,
f.flow_time,
f.destination_ip,
f.destination_port,
f.protocol,
f.bytes_sent,
f.bytes_received
FROM network_flows AS f
LEFT JOIN dns_answer_ledger AS d
ON d.workload_id = f.workload_id
AND d.answer_ip = f.destination_ip
AND f.flow_time >= d.answer_time
AND f.flow_time < d.expiry_time
WHERE f.action = 'ACCEPT'
AND f.destination_scope = 'PUBLIC'
AND f.bytes_sent > 0
AND d.answer_ip IS NULL;
This query is a candidate generator, not a page-worthy alert by itself. Exclude provider-owned infrastructure that is intentionally reached by address, approved proxies, private address space and documented fixed-address services. Account for DNS performed outside the monitored resolver, including DNS-over-HTTPS, local caches and service meshes. If the detector cannot establish that a workload's resolver path is covered, label the result unknown DNS provenance rather than DNS bypass.
Measure a DNS-coherence ratio for each workload role: the share of accepted public destinations that match a live entry in the answer ledger. Baseline the ratio over a representative business cycle. Escalate a negative join when the destination is first-seen for that workload, the workload normally has high coherence, and endpoint telemetry shows a new or unusual process opening the socket. This avoids importing Unit 42's laboratory percentages into a production threshold where browser, proxy and server populations behave differently.
FTP-banner dead drops deserve a separate branch. Prioritise a first-seen public destination on TCP port 21 when the source process descends from a shortcut handler, PowerShell, cmd.exe, rundll32.exe, certutil.exe or an unexpected Electron application. Flow logs cannot reveal the banner text, so retrieve network detection or packet metadata where policy permits. A short client connection that receives more than it sends, followed by WebDAV retrieval or a new HTTP destination from the same process tree, is much stronger than port 21 alone.
On endpoints, correlate the network candidate with process ancestry and file creation. The SOCRadar chain offers specific shapes: a .lnk launch, PowerShell reaching an FTP address, rundll32 executing a downloaded DLL, a signed Discord.exe loading altered Electron application content, or certutil -decode followed by archive expansion and execution from a temporary directory. Do not alert on every use of these programs. Bind the events to one host and process tree, then require unexplained egress or an unusual output path.
Where a proxy or network sensor records application data, hunt the protocol details reported by Unit 42. The malformed \\GET method with a long encoded body is unusual enough to investigate without relying on an IP list. /churl and /fsave requests to raw addresses are useful incident indicators, particularly when their client process is not an approved browser. Keep the reported addresses as scoping data, but do not build the durable rule around them; Unit 42 observed address and port rotation, and shared cloud hosting makes broad address blocking unsafe.
False positives fall into four groups. Fixed-address infrastructure may be legitimate. Resolver visibility may be incomplete. Shared resolvers can make the answer appear under another identity. Flow sampling can hide surrounding context. Tuning should fix the identity or coverage problem before adding a destination allow-list. An unexplained connection from a high-coherence workload remains useful even when the destination is not yet known to threat intelligence.
What to do now
Enable resolver query logging and VPC or virtual-network flow logging on the workloads where public egress matters most. Verify coverage with a controlled DNS lookup and connection, then with a controlled direct-address connection. Record which event each provider emits and how long it takes to arrive.
Build the answer ledger with TTL-aware expiry and stable workload identity. Test cache behaviour explicitly. AWS warns that a cached Resolver response does not create a second query log, so an immediate-event join will manufacture false positives.
Run the anti-join in hunt mode. Rank results by workload DNS coherence, first-seen destination, unusual process ancestry and destination port. Review the highest-ranked results before turning the logic into an alert.
Add an FTP-bootstrap correlation for managed Windows endpoints and administrative workstations. Preserve shortcut, PowerShell, command-shell,
rundll32,certutil, Electron and network events under one process-tree identifier.Scope confirmed hosts beyond the first socket. Search for later HTTP, HTTPS or WebSocket connections, payload writes, persistence changes and outbound data. Rotate credentials according to what the process could reach, but label capability and confirmed theft separately.
Keep DNS controls, but test them against a direct-address path. Protective DNS still blocks a large class of threats. The mistake is treating no malicious lookup as no malicious connection. Network flows and endpoint ancestry are the evidence that closes that gap.