> [!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*