> [!warning] Aviso Importante > Este playbook exige familiaridade com análise de trafego de rede, fingerprinting TLS e conceitos de C2 moderno. Falsos positivos sao frequentes em ambientes com ferramentas de monitoramento legítimas (PRTG, Zabbix, RMM). Sempre correlacione com telemetria de endpoint antes de escalar. --- ## Visão Geral Command and Control (C2) beaconing e o método pelo qual malware implantado em um host comprometido mantém comunicação regular com a infraestrutura do atacante para receber comandos, exfiltrar dados e fazer check-in de status. Frameworks modernos de adversary simulation como [[s0154-cobalt-strike]], [[brute-ratel-c4]] e [[s0633-sliver]] usam beaconing sofisticado com jitter, perfis maleaveis e canais cifrados para evadir detecção. **Contexto LATAM/Brasil:** - [[g0099-blind-eagle-apt-c-36]] (APT-C-36) usa variantes de njRAT e AsyncRAT com C2 hospedado em infraestrutura comprometida no Brasil e Colombia - [[s0531-grandoreiro]] opera C2 distribuido com domain generation algorithm (DGA) para targets financeiros brasileiros - Grupos de ransomware como [[lockbit]] e [[cl0p]] usam Cobalt Strike como ferramenta de pos-comprometimento padrao antes do deploy do ransomware - Infraestrutura C2 em nuvem (AWS, Azure, GCP) e cada vez mais comum para evadir blocklists de IP **Frameworks C2 mais vistos em incidentes reais:** | Framework | Protocolo padrao | Fingerprint principal | Grupos que usam | |-----------|-----------------|----------------------|----------------| | [[s0154-cobalt-strike]] | HTTPS | JARM: `07d14d16d21d21d00042d41d00041d2aa5ce6a70de7ba95aef77a77b00a0af` | Maioria dos APTs, ransomware groups | | [[brute-ratel-c4]] | HTTPS | User-Agent customizado, requests muito regulares | Patchwork, BianLian | | Sliver | mTLS, HTTP, DNS | Certificados autoassinados, padding aleatorio | Red teams, alguns APTs | | Havoc | HTTPS | SMB named pipes, sleep mask | Grupos de crime organizado | | Metasploit Meterpreter | HTTPS/TCP | SSL fingerprint distintivo | Amplo uso (script kiddies a APT) | --- ## Fluxo de Detecção de Beaconing ```mermaid flowchart TD A([Inicio do Hunting<br/>C2 Beaconing]) --> B[Coletar Logs de Rede<br/>Proxy / DNS / NetFlow / EDR] B --> C{Tipo de<br/>Análise} C -->|Trafego HTTPS| D[JARM Fingerprinting<br/>TLS Client Hello] C -->|DNS| E[Análise de Frequencia<br/>DNS Beaconing] C -->|HTTP/S periodicidade| F[Jitter Analysis<br/>Estatistica temporal] C -->|Certificados TLS| G[JA3/JA3S Fingerprinting<br/>Client + Server] D --> H{Score JARM<br/>Matches Known C2?} E --> I{Dominio com<br/>Alta Entropia?} F --> J{Desvio Padrao<br/>Menor que 5%?} G --> K{JA3 Hash em<br/>Blocklists?} H -->|Sim| L[Hipotese C2 Ativa<br/>Alta Confianca] I -->|Sim| L J -->|Sim| L K -->|Sim| L H -->|Nao| M[Continuar Hunting<br/>Outros Vetores] I -->|Nao| M J -->|Nao| M K -->|Nao| M L --> N[Correlacionar com EDR<br/>Processo que gerou trafego] N --> O{Processo<br/>Legitimado?} O -->|Nao| P[ESCALAR PARA IR<br/>C2 Confirmado] O -->|Incerto| Q[Análise Profunda<br/>Memory + PE Analysis] Q --> P style A fill:#1a3a5c,color:#fff style P fill:#ff4444,color:#fff style L fill:#ff8800,color:#fff ``` --- ## Diagrama - Padroes de Comúnicação C2 ```mermaid graph TB subgraph ATK ["Infraestrutura do Atacante"] TS["Team Server<br/>Cobalt Strike / Sliver"] R1["Redirector 1<br/>Cloudflare / CDN"] R2["Redirector 2<br/>VPS Comprometida"] end subgraph ENV ["Rede da Vitima"] H1["Host Comprometido<br/>Beacon ativo"] H2["Segundo Hop<br/>Pivot via SMB"] DNS_I["DNS Interno"] end subgraph DETECT ["Pontos de Detecção"] FW["Firewall / NGFW<br/>JARM + JA3"] PROXY["Proxy Web<br/>URL Pattern + UA"] DNS_LOG["DNS Resolver<br/>Frequencia + Entropia"] EDR["EDR Endpoint<br/>Processo + Memoria"] end H1 -->|HTTPS beaconing<br/>jitter 30s +/- 20%| R1 H1 -->|DNS beaconing<br/>subdomains aleatorios| DNS_I H2 -->|SMB C2<br/>named pipe| H1 R1 --> TS R2 --> TS FW -.->|Inspeciona TLS| H1 PROXY -.->|Loga requests| H1 DNS_LOG -.->|Monitora queries| DNS_I EDR -.->|Monitora processo| H1 style TS fill:#8b0000,color:#fff style H1 fill:#cc4400,color:#fff style DETECT fill:#003366,color:#fff ``` --- ## Hipotese 1 - JARM Fingerprinting JARM e um fingerprint ativo do lado do servidor TLS. Envia 10 probes TLS específicos e agrupa as respostas em um hash de 62 chars. Servidores C2 como Cobalt Strike usam configuracoes TLS padroes que geram hashes distintos mesmo com certificados diferentes. ### JARM Hashes Conhecidos de C2 (públicos) ``` # Cobalt Strike padrao (Java TLS stack) 07d14d16d21d21d00042d41d00041d2aa5ce6a70de7ba95aef77a77b00a0af # Metasploit Meterpreter 07d19d1ad21d21d00042d43d00041de5fb3038104f457d92ba8ab1b30041db # Cobalt Strike 4.x com malleable profile 2ad2ad16d2ad2ad22c42d42d000000f8d94c50c6f9b6594f87e20c5da4f29 # Sliver (variacoes multiplas - verificar via Shodan) 00000000000000000000000000000000000000000000000000000000000000 ``` > [!warning] JARM e probabilistico - o mesmo hash pode pertencer a software legitimo. Use como hipotese inicial, nao como evidência definitiva. ### Splunk - Busca por JARM Suspeito via Zeek ```spl index=zeek sourcetype=zeek:ssl | stats count by server_name, já3, já3s, válidation_status | where válidation_status != "ok" OR isnull(server_name) | lookup c2_jarm_hashes.csv já3s AS já3s OUTPUT threat_name | where isnotnull(threat_name) | table _time, id.orig_h, id.resp_h, server_name, já3, já3s, threat_name ``` ### KQL - Microsoft Sentinel - JA3 Hash Suspeito ```kql CommonSecurityLog | where DeviceVendor == "Palo Alto Networks" | extend já3_hash = extract(@"JA3:([a-f0-9]{32})", 1, AdditionalExtensions) | where já3_hash in ( "51c64c77e60f3980eea90869b68c58a8", // Cobalt Strike default "a0e9f5d64349fb13191bc781f81f42e1", // CobaltStrike 4.x "72a589da586844d7f0818ce684948eea" // Metasploit ) | summarize count() by SourceIP, DestinationIP, DestinationPort, já3_hash | order by count_ desc ``` --- ## Hipotese 2 - Jitter Analysis (Análise Estatistica Temporal) Beacons C2 usam sleep intervals com jitter para evadir detecção. Um beacon com sleep de 60s e jitter de 20% vai beacon entre 48s e 72s. Isso cria uma distribuição estatistica caracteristica - desvio padrao baixo e constante ao longo do tempo. ### Splunk - Detecção de Beaconing por Regularidade ```spl index=proxy OR index=zeek | bin _time span=1m | stats count by src_ip, dest_ip, _time | eventstats avg(count) AS avg_count, stdev(count) AS stdev_count by src_ip, dest_ip | where stdev_count < 2 AND avg_count > 0 | eval beacon_score = round((1 - (stdev_count / avg_count)) * 100, 2) | where beacon_score > 85 | stats avg(beacon_score) AS score, count AS total_intervals by src_ip, dest_ip | where total_intervals > 20 | sort -score ``` ### KQL - Microsoft Sentinel - Frequencia Suspeita de Conexoes ```kql let timeWindow = 6h; let minConnections = 15; let maxStdDevRatio = 0.15; NetworkCommúnicationEvents | where Timestamp > ago(timeWindow) | summarize ConnectionCount = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), IntervalStdDev = stdev(totimespan(Timestamp - prev(Timestamp, 1))) by LocalIP, RemoteIP, RemotePort | where ConnectionCount > minConnections | extend DurationMinutes = datetime_diff('minute', LastSeen, FirstSeen) | extend AvgIntervalSeconds = DurationMinutes * 60 / ConnectionCount | extend StdDevSeconds = totimespan(IntervalStdDev) / 1s | extend JitterRatio = StdDevSeconds / AvgIntervalSeconds | where JitterRatio < maxStdDevRatio | project LocalIP, RemoteIP, RemotePort, ConnectionCount, AvgIntervalSeconds, JitterRatio | order by JitterRatio asc ``` --- ## Hipotese 3 - DNS Beaconing C2 via DNS usa subdomains aleatorios de alto comprimento e entropia para codificar dados. O padrao de queries e muito mais frequente que DNS normal para o mesmo dominio base. ### Splunk - Entropia de Subdomains DNS ```spl index=dns | rex field=query "^(?P<subdomain>.+?)\.(?P<domain>[^.]+\.[^.]+)quot; | eval char_count = len(subdomain) | eval entropy = -sum(map(lambda c: (count(subdomain, c) / char_count) * log(count(subdomain, c) / char_count + 0.0001, 2), split(subdomain, ""))) | where char_count > 20 AND entropy > 3.5 | stats count AS query_count, avg(entropy) AS avg_entropy by domain, src_ip | where query_count > 50 | sort -avg_entropy ``` ### KQL - Microsoft Sentinel - DNS de Alta Frequência e Entropia ```kql DnsEvents | where TimeGenerated > ago(1h) | extend Domain = extract(@"([a-zA-Z0-9-]+\.[a-zA-Z]{2,})quot;, 1, Name) | extend Subdomain = replace_string(Name, strcat(".", Domain), "") | extend SubLen = strlen(Subdomain) | where SubLen > 15 | summarize QueryCount = count(), UniqueSubdomains = dcount(Subdomain) by ClientIP, Domain, bin(TimeGenerated, 5m) | where QueryCount > 30 or UniqueSubdomains > 20 | order by QueryCount desc ``` --- ## Ferramentas de Hunting | Ferramenta | Uso | Comando Chave | |------------|-----|---------------| | **JARM** (Salesforce) | Fingerprinting ativo de servidores TLS | `python3 jarm.py <target_ip> <port>` | | **já3er.com** | Lookup de hashes JA3 conhecidos | API: `curl https://já3er.com/search/<hash>` | | **Zeek (Bro)** | Captura e análise de trafego SSL/TLS | Logs `ssl.log` com campos `já3`, `já3s` | | **Wireshark** | Análise de pacotes beacon pattern | Filtro: `tls.handshake.type == 1` | | **Shodan** | Busca de servidores C2 conhecidos | `ssl.jarm:<hash>` ou `product:cobalt strike` | | **NetworkMiner** | Extração de artefatos de PCAP | Aba Credentials + Host Details | | **Velociraptor** | Hunt em escala de processos com conexoes C2 | `Windows.Network.ListeningPorts` | | **Volatility** | Análise de conexoes de rede em memoria | `python3 vol.py windows.netstat` | --- ## Indicadores de Comprometimento por Framework ### Cobalt Strike ``` # Artefatos em disco %TEMP%\*.dll (injetados via reflective loading) %TEMP%\*.ps1 (stagers PowerShell) %APPDATA%\Microsoft\[nome_aleatorio].dll # Processos hollowing comuns rundll32.exe sem argumento svchost.exe com parent incomum notepad.exe com conexão de rede ativa # Named pipes padrao \\.\pipe\msagent_[hex] \\.\pipe\MSSE-[digits]-server \\.\pipe\status_[hex] ``` ### Brute Ratel C4 ``` # Artefatos (badgers) BRC4.exe, badger.exe calc.exe com conexoes de rede (process hollowing) # HTTP headers distintos User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Firefox/[versao_antiga] Content-Type: application/octet-stream com body cifrado ``` ### Sysmon - Eventos Criticos para C2 ``` EventID 3 - Network connection (processos inesperados conectando externamente) EventID 8 - CreateRemoteThread (injecao em processo alvo) EventID 10 - ProcessAccess (LSASS access, também relevante) EventID 17 - Pipe created (named pipes C2 Cobalt Strike) EventID 22 - DNS query (lookup de dominio C2) EventID 25 - ProcessTampering (unmapping de PE - reflective loading) ``` --- ## Checklist de Hunting - [ ] Coletar logs Zeek/proxy dos ultimos 7 dias com campos SSL completos (já3, já3s, server_name) - [ ] Executar JARM scan passivo contra todos IPs externos identificados nos logs - [ ] Rodar query de jitter analysis no SIEM - focar em conexoes > 20 intervalos com baixo stdev - [ ] Analisar DNS logs buscando dominios com subdomains de alta entropia (> 3.5 bits/char) - [ ] Verificar named pipes ativos em todos os endpoints via Velociraptor ou EDR - [ ] Comparar hashes JA3 contra blocklists publicas (já3er.com, abuse.ch) - [ ] Buscar processos incomuns com conexoes de rede em EventID Sysmon 3 - [ ] Verificar injecao de DLL via EventID Sysmon 8 (CreateRemoteThread) - [ ] Correlacionar IPs externos contra Shodan para verificar perfil do servidor - [ ] Documentar hipoteses com evidencias antes de escalar para IR --- ## Automacao SOAR ### Splunk SOAR - Playbook de Validação de C2 ```python # Acao automatica quando beacon score > 85 def válidaté_c2_beacon(container, ip_suspeito): # 1. Lookup JA3 hash result_já3 = phantom.act("lookup_ip", parameters=[{"ip": ip_suspeito}]) # 2. Enrich com VirusTotal result_vt = phantom.act("hunt_ip", parameters=[{"ip": ip_suspeito}], app="virustotal") # 3. Se VT score > 5 - criar ticket if result_vt["positives"] > 5: phantom.act("creaté_ticket", parameters=[{ "summary": f"C2 Beacon Confirmado: {ip_suspeito}", "severity": "High", "description": f"Beacon score: {beacon_score}%" }]) ``` ### Microsoft Sentinel - Analytics Rule ```kql // Nome: Suspicious C2 Beaconing Pattern // Frequencia: A cada 1 hora // Limiar: Gerar alerta quando encontrar padroes suspeitos let beaconThreshold = 0.10; // 10% max jitter ratio let minConnections = 20; NetworkCommúnicationEvents | where Timestamp > ago(1h) | summarize Count = count(), Times = make_list(Timestamp, 1000) by LocalIP, RemoteIP, RemotePort | where Count > minConnections | extend JitterRatio = array_length(array_sort_asc(Times)) // simplificado | where RemotePort !in (80, 443, 53, 8080, 8443) // excluir portas comuns | extend AlertSeverity = "High" ``` --- ## Referências - [[s0154-cobalt-strike]] - framework C2 mais utilizado em incidentes reais - [[brute-ratel-c4]] - alternativa ao Cobalt Strike usada por APTs - [[g0099-blind-eagle-apt-c-36]] - APT LATAM com C2 em infraestrutura brasileira - [[s0531-grandoreiro]] - trojan bancario com C2 DGA-based - [[t1071-application-layer-protocol|T1071 - Application Layer Protocol]] - técnica MITRE ATT&CK - [[t1573-encrypted-channel|T1573 - Encrypted Channel]] - canal cifrado para evasão - [[t1132-data-encoding|T1132 - Data Encoding]] - codificacao de dados C2 - [[_defenses]] - hub de defesas do vault - [[_detections]] - estrategias de detecção - [JARM Fingerprinting - Salesforce Engineering](https://engineering.salesforce.com/easily-identify-malicious-servers-on-the-internet-with-jarm-e095edac525a) - [JA3 - TLS Fingerprinting](https://github.com/salesforce/já3) - [Cobalt Strike JARM Fingerprints - SANS](https://isc.sans.edu/diary/Identifying+Cobalt+Strike+Servers/27411) --- *Ultima revisao: 2026-03-27 | Proxima revisao recomendada: 2026-09-27*