NanoCore: Non-Application Layer Protocol (Raw Socket C2)
NanoCore does not speak HTTP to its controller. The client opens a raw TCP socket to the configured host and port and exchanges its own length-prefixed, encrypted messages over it. There is no request line, no headers, no TLS handshake — nothing an application-layer proxy or a URL blocklist can read.
MITRE ATT&CK: Non-Application Layer Protocol (T1095)
Why it matters for detection
Most C2 detection leans on application-layer structure: URI patterns, JA3/JA4 hashes, user agents, SNI. A raw socket offers none of that. What is left is shape: who is connecting, to where, on what port, how often, and for how long.
| Property | NanoCore’s raw channel |
|---|---|
| Transport | TCP, arbitrary port — commonly high and non-standard |
| Application protocol | none — custom binary framing |
| Handshake | none, so no TLS metadata and no JA3/JA4 |
| Proxy visibility | none, unless the proxy is a transparent TCP relay |
| Beacon shape | long-lived connection or regular short reconnects |
Reference implementation
No code is recreated here. The socket-C2 mechanics are already demonstrated end to end in my earlier project:
shaddy43/ReverseShell_NC — a reverse shell over a raw TCP socket, with the client/server handling that this technique needs. It is the same primitive NanoCore relies on: connect a socket, hand the other end an interactive process, and let the operator drive it.
Reading that alongside the detections below is the point — the detections key on the behaviour the socket produces, and that project shows the behaviour being produced.
Detection rules and hunting queries: Detection
Disclaimer
For educational purposes only!!!