09 - Normalização e Deduplicação de Indicadores
video: https://youtu.be/... no frontmatter da nota.Normalização e Deduplicação de Indicadores
Nota do capítulo 02 (Fontes de Dados e Coleta), que trata da qualidade técnica do material coletado antes do uso operacional.
Define as regras de canonicalização por tipo de indicador, os critérios de deduplicação exata e fuzzy e o ciclo de expiração por TTL.
Depende do pipeline de coleta (nota 08) e alimenta diretamente a resolução de entidades, a qualidade de dados e a distribuição ao SIEM e ao EDR.
1. Contexto e Posicionamento na Biblioteca
Indicadores chegam ao TIP em dezenas de variantes do mesmo objeto: um feed escreve o domínio em maiúsculas com ponto final, outro entrega a URL com porta padrão e fragmento, um terceiro publica o IP em notação decimal pouco usual. Sem um passo formal de normalização, a mesma entidade ocupa várias entradas na base, contagens de fonte se inflam, correlações ficam impossíveis e o analista perde confiança no repositório. A normalização é, portanto, o contrato que torna comparáveis observáveis vindos de fontes heterogêneas, e a deduplicação é o que garante que cada entidade ocupe um único registro com histórico consolidado.
Este arquivo detalha a fase de processamento descrita no pipeline da nota 08 e materializa na prática o controle CTI.5 (processamento e normalização) da seção 15. A regra central é que todo indicador entra na base em uma única forma canônica por tipo, acompanhada de metadados de origem, primeiro e último visto, confiança e etiquetas. As notas de qualidade (11) e de resolução de entidades (10) assumem que essas chaves canônicas existem, por isso a disciplina aqui é pré-requisito de quase todo o capítulo.
2. Desarme Prévio e Princípios da Canonicalização
Antes de canonicalizar, é preciso desarmar (defang) o material ofuscado que protege o leitor e os sistemas contra acesso acidental: hxxp://, [.], (.) e domínio[.]com são formas comuns em relatórios e feeds. A conversão para a forma armada só deve ocorrer dentro do pipeline, em ambiente controlado, e jamais em notificações por e-mail ou canais de chat que podem acionar o próprio IOC. O desarme e o rearme fazem parte das regras de manuseio, e a forma canônica armada fica restrita ao TIP e aos destinos técnicos autorizados.
Três princípios guiam todas as regras de canonicalização. Primeiro, a canônica é determinística: a mesma entrada sempre produz a mesma saída, em qualquer worker, em qualquer momento. Segundo, a canônica é mínima: remove-se tudo que não altera a identidade técnica do objeto, como caixa, ponto final e porta padrão. Terceiro, a canônica preserva a semântica de segurança: não se resolve domínio para IP, não se extrai hash de arquivo da URL e não se descarta informação que muda o julgamento analítico, como o caminho exato de uma URL de phishing.
O princípio da determinística só se sustenta com testes. Cada regra de canonicalização deve ser coberta por vetores de teste versionados junto ao código do worker, cobrindo as variantes reais já observadas de cada fonte e os casos de borda clássicos por tipo, e toda exceção encontrada em produção vira novo vetor antes de virar ajuste. Times que mantêm esse pacote de vetores mudam de regra com confiança e conseguem demonstrar, em auditoria ou em disputa com fornecedor, exatamente como cada valor foi transformado, pois a função canônica é pública, testada e idêntica em todos os estágios.
3. Regras de Canonicalização por Tipo de Indicador
Cada tipo de observável tem armadilhas específicas, e a tabela abaixo consolida as regras operacionais recomendadas para os tipos de maior volume na prática. A coluna de exemplo mostra variantes reais de feeds apontando para a mesma entidade, o que ilustra por que a chave canônica é obrigatória antes de qualquer contagem ou correlação.
| Tipo | Regras de canonicalização | Exemplo de variantes recebidas | Forma canônica |
|---|---|---|---|
| IPv4 | Validar; recusar octetos com zeros à esquerda ambíguos; proibir faixas internas sem etiqueta | 172.016.001.001, 172.16.1.1 | 172.16.1.1 |
| IPv6 | Normalizar conforme RFC 5952: minúsculas, compressão canônica de zeros | 2001:0DB8:0000:0000:0000:0000:0000:0001 | 2001:db8::1 |
| Domínio | Minúsculas; remover ponto final; converter punycode e guardar alias unicode; extrair domínio registrável via Public Suffix List | Example.COM., xn--80ak6aa92e.com | example.com |
| URL | Minúsculas de scheme e host; remover porta padrão; normalizar percent-encoding; descartar fragmento; avaliar caminho com um único slash | hxxp://Example.com:80/phish.php#/login | http://example.com/phish.php |
| Hash MD5/SHA-1/SHA-256 | Minúsculas hexadecimais; algoritmo explícito no tipo; recusar comprimento incompatível | D41D8CD98F00B204E9800998ECF8427E | d41d8cd98f00b204e9800998ecf8427e |
| E-mail como observável | Minúsculas; separar parte local de domínio; canonicalizar o domínio pelas regras acima | User@Example.COM. | user@example.com |
O caso do punycode mere destaque porque é vetor de ataque, não apenas ruído de formato. Domínios internacionalizados codificam caracteres não ASCII como rótulos xn--, e um homoglifo cirílico de marca conhecida pode parecer legítimo na tela enquanto canonicaliza para uma forma totalmente distinta. A política recomendada é armazenar a forma punycode como canônica (é ela que resolve em DNS) e manter o alias unicode decodificado como atributo de triagem, com verificação de confusão visual contra marcas monitoradas pela organização.
4. Implementação Prática em Pseudocódigo
O pseudocódigo abaixo concentra as regras dos tipos mais comuns em funções puras, prontas para testes unitários. O ponto central do desenho é o despachante por tipo: o pipeline decide o tipo antes de canonicalizar, porque regras não são intercambiáveis, e toda função devolve a chave canônica mais atributos auxiliares que a deduplicação consumirá.
import ipaddress
from urllib.parse import urlsplit, urlunsplit
def desarmar(valor):
"""Converte formas ofuscadas (hxxp, [.]) na forma técnica."""
return valor.replace("hxxp", "http").replace("hXXp", "http").replace("[.]", ".").replace("(.)", ".")
def canonicalizar_ip(valor):
ip = ipaddress.ip_address(valor) # recusa formas invalidas e ambiguas
if ip.version == 6:
return str(ip).lower() # forma compacta RFC 5952
return str(ip)
def canonicalizar_dominio(valor):
dominio = desarmar(valor).strip().rstrip(".").lower()
punycode = dominio.startswith("xn--") or ".xn--" in dominio
alias_unicode = None
if punycode:
try:
alias_unicode = dominio.encode("ascii").decode("idna")
except UnicodeError:
registrar_rejeicao(valor, motivo="punycode_invalido")
return None, None
return dominio, alias_unicode
def canonicalizar_url(valor):
partes = urlsplit(desarmar(valor).strip())
porta = "" if partes.port in (None, 80, 443) else f":{partes.port}"
host = (partes.hostname or "").lower()
caminho = partes.path if partes.path != "/" else ""
return urlunsplit((partes.scheme.lower(), f"{host}{porta}", caminho, partes.query, ""))
def canonicalizar_hash(valor, algoritmo):
hexa = valor.strip().lower()
tamanhos = {"md5": 32, "sha1": 40, "sha256": 64}
if len(hexa) != tamanhos[algoritmo]:
raise ValueError(f"hash incompativel com {algoritmo}")
return hexa
Cada função deve estar coberta por testes com as variantes da tabela da seção 3, e o pipeline deve rejeitar, com contagem e amostra, qualquer entrada que falhe a validação em vez de gravar lixo silenciosamente. A taxa de rejeição por fonte é, inclusive, um dos indicadores de qualidade monitorados na nota 11, pois mudanças abruptas costumam sinalizar alteração de formato na origem.
5. Deduplicação Exata: Chave, Fusão e Metadados
A deduplicação exata opera sobre a chave canônica tipo e valor, aplicada como restrição de unicidade no banco do TIP. Quando a segunda ocorrência chega, o sistema não cria registro novo: funde os metadados no registro existente com regras determinísticas. As regras de fusão recomendadas são: primeiro visto mantém a data mais antiga; último visto mantém a mais recente; a lista de fontes recebe a nova origem com timestamp; a confiança sobe por política (por exemplo, média ponderada ou máximo, com teto por fonte); e as etiquetas se acumulam, com resolução de conflito explícita, pois a mesma entidade pode ser etiquetada de forma diferente por feeds distintos. O exemplo abaixo mostra a fusão de dois registros que chegam com formas diferentes do mesmo domínio:
antes:
registro_1:
valor_recebido: "Example.COM."
valor_canonico: "example.com"
fonte: feed_a
primeiro_visto: "2025-09-01"
ultimo_visto: "2025-10-10"
confianca: 60
registro_2:
valor_recebido: "example.com"
valor_canonico: "example.com"
fonte: feed_b
primeiro_visto: "2025-10-15"
ultimo_visto: "2025-11-20"
confianca: 80
depois:
registro_fundido:
valor_canonico: "example.com"
fontes: [feed_a, feed_b]
fontes_independentes: 2
primeiro_visto: "2025-09-01"
ultimo_visto: "2025-11-20"
confianca: 80
etiquetas: [phishing, campanha_setembro]
A contagem de fontes independentes após a fusão é um dos sinais de relevância mais baratos que existem. Um IP visto por três feeds tecnicamente distintos tem peso analítico maior que o mesmo IP repetido dez vezes pelo mesmo feed, por isso o TIP deve distinguir ocorrências de fontes independentes de repetições da mesma fonte. Essa distinção, se não for feita na deduplicação, será impossível de reconstruir depois e contaminará qualquer pontuação de prioridade construída sobre a base.
Dois casos de borda exigem decisão documentada. O primeiro é o conflito de julgamento: um feed marca o domínio como malicioso e outro como legítimo, situação comum com CDN e serviços de hospedagem legítimos que hospedam phishing. A política recomendada é manter as etiquetas contraditórias visíveis, registrar o conflito e priorizar a fonte com histórico de precisão maior, nunca sobrescrever silenciosamente. O segundo é a mudança de identidade técnica do valor após reavaliação de regra de canonicalização, que exige job de migração versionada, nunca edição manual pontual.
6. Deduplicação Fuzzy e Agrupamento de Similares
Deduplicação fuzzy responde a outra pergunta: quais registros distintos representam a mesma campanha ou a mesma infraestrutura quase idêntica. Para artefatos binários, os fuzzy hashes contextuais, como ssdeep e TLSH, permitem ligar amostras de uma família mesmo que os hashes criptográficos (SHA-256) difiram por compilação diferente. Para domínios, as técnicas úteis são a distância de Damerau-Levenshtein pequena em relação a marcas monitoradas (capturando typosquatting) e a detecção de homoglifos pelo algoritmo de esqueleto do Unicode (UTS 39), que revela a troca de letras cirílicas por latinas.
Um fluxo típico de agrupamento fuzzy roda como job fora do caminho crítico: gera a chave fuzzy de cada novo artefato, compara contra o índice de chaves próximas e propõe vínculos para revisão, nunca funde automaticamente. A fusão automática em fuzzy é perigosa porque a similaridade é evidência, não identidade: dois domínios a uma edição de distância podem ser campanha do mesmo ator ou simplesmente domínios distintos registrados por terceiros. A saída correta do job é um parâmetro de relacionamento com grau de similaridade, consumido pela resolução de entidades da nota 10.
def eh_candidato_typosquatting(dominio, marcas, limiar=2):
"""Comparação por Damerau-Levenshtein com guarda de tamanho."""
registravel = extrair_registravel(dominio)
for marca in marcas:
if abs(len(registravel) - len(marca)) > limiar:
continue
if damerau_levenshtein(registravel, marca) <= limiar:
return True, marca
return False, None
O exemplo acima mostra a forma mais simples e barata de triagem de typosquatting, executada na ingestão de domínios e acoplada às marcas definidas pelos PIRs. O resultado positivo não cria indicador malicioso: cria vínculo de atenção com pontuação, etiqueta de campanha provável e tarefa de revisão humana, preservando a separação entre similaridade e veredito.
7. TTL e Ciclo de Vida do Indicador Normalizado
Indicador não é eterno, e a base sem expiração degrada em dois efeitos: falso positivos crescentes, quando endereços reciclados voltam a usuários legítimos, e custo de busca que cresce sem agregar. O TTL (time to live) define por quanto tempo o indicador permanece ativo para detecção, e deve ser definido por tipo e por natureza da infraestrutura, com base em quão rápido cada objeto muda de mãos no mundo real. A tabela abaixo traz pontos de partida operacionais, a serem calibrados com as métricas de falso positivo da nota 11.
| Tipo de indicador | TTL sugerido | Racional operacional |
|---|---|---|
| IPv4 dinâmico (ISP, VPN compartilhado) | 30 a 60 dias | Endereço reciclado rápido; risco de FP alto após troca de usuário |
| IPv4 de infraestrutura dedicada | 90 a 180 dias | Servidor dedicado raramente muda de função sem movimento visível |
| Domínio | 90 a 180 dias | Páginas caem rápido, mas domínio pode reaparecer em campanha seguinte |
| URL | 30 a 90 dias | Artefato costuma ser derrubado ou migrar de caminho |
| Hash de malware (MD5/SHA-256) | 180 a 365 dias | Arquivo reaparece em recompilações e úteis a retro-hunt prolongado |
A expiração deve ser implementada como decaimento de confiança, não como exclusão física. Um modelo prático é o decaimento exponencial diário, em que a confiança efetiva multiplica a confiança original por um fator menor que um por dia decorrido, com limiar que marca o indicador como expirado para detecção. O registro permanece na base com histórico completo, o que mantém viável a pergunta clássica do hunting e da resposta a incidente: isso já apareceu aqui antes, mesmo que não deva mais bloquear nada. Expirar e apagar são operações distintas, e a política de apagar é assunto da nota de governança e retenção.
8. Erros Comuns e Pontos de Atenção
O erro mais custoso é canonicalizar tarde, deixando cada consumidor aplicar sua própria conversão ad hoc, o que garante divergência entre SIEM, TIP e EDR para a mesma entidade. A canonicalização deve ocorrer uma única vez, na ingestão, e os consumidores recebem a forma canônica pronta. Erra também quem canonicaliza demais, resolvendo domínio para IP ou cortando parâmetros de URL com informação de campanha, destruindo semântica que a análise precisaria depois.
Na deduplicação, o erro clássico é fundir metadados com última escrita vence (last write wins), apagando fontes e datas que sustentariam a contagem de fontes independentes. Outro erro recorrente é tratar feed como fonte independente quando todos replicam a mesma origem primária, inflando falsamente a relevância. Na deduplicação fuzzy, o risco invertido é automatizar a fusão por similaridade, gerando agregações falsas entre infraestruturas distintas; a saída correta é sempre vínculo proposto com pontuação e revisão.
Sobre TTL, o equilíbrio é político e técnico ao mesmo tempo: times de bloqueio tendem a pedir TTL longo para reter proteção, e times de resposta pedem curto para reduzir FPs. A saída saudável é TTL diferenciado por tipo com decaimento por confiança e por fonte, revisado trimestralmente com dados reais de acionamento e falso positivo. Indicadores ligados a TTPs e campanhas relevantes podem receber extensão manual justificada, registrada como decisão analítica, e não como exceção invisível na base.
9. Integração com o Restante da Biblioteca
As chaves canônicas definidas aqui são o vocabulário comum assumido por todo o restante do capítulo: o pipeline da nota 08 as usa como chave de idempotência das mensagens, a resolução de entidades da nota 10 constrói os grafos sobre objetos já canônicos, e a qualidade da nota 11 mede, entre outras coisas, a taxa de rejeição e de duplicação resultante destas regras. Na distribuição, o export para o SIEM e para o EDR leva somente a forma canônica com TTL ativo, garantindo que contagens do lado da detecção batam com o TIP.
Com o capítulo 03 (indicadores), este arquivo operacionaliza a distinção entre o observável cru e o indicador com julgamento: a canonicalização pertence ao observável, e a pontuação, ao indicador. Com a seção 15, materializa os salvaguardas do controle CTI.5 e apoia os controles de bloqueio da PRT, fornecendo a camada de confiança necessária para decidir o que chega à prevenção automatizada. Um próximo passo de maturidade é publicar estas regras como pacote de validação reutilizável, com vetores de teste por tipo, permitindo que qualquer fonte nova entre em produção provando conformidade canônica antes de tocar a base.