OSINT e reconhecimento
Ética e privacidade em OSINT: o que você não deve coletar
Aprenda finalidade, proporcionalidade, consentimento e minimização de dados em OSINT, com noções de LGPD e GDPR e um modelo de plano de pesquisa.
Entenda como os logs de Certificate Transparency registram certificados TLS públicos e revise o crt.sh de um domínio seu, sem tocar nos hosts.
Certificate Transparency (CT) é um registro público de certificados TLS. Quando uma autoridade certificadora (CA) emite um certificado com confiança pública, ela grava esse certificado em um ou mais logs de CT. Qualquer pessoa pode ler esses logs, e ninguém consegue editá-los em silêncio. Para quem é dono de um domínio, isso significa um histórico pesquisável dos certificados públicos emitidos para nomes do seu domínio, inclusive os que ninguém da equipe lembra de ter pedido.
O protocolo está especificado na RFC 9162, "Certificate Transparency Version 2.0", publicada em dezembro de 2021. Ela substitui a especificação original, a RFC 6962. Antes de citar, confira o status: a RFC 9162 é um documento Experimental, não uma especificação de trilha de padrões da Internet, e a própria RFC diz isso. Mesmo assim, ela continua sendo a referência para entender como os logs funcionam, e os navegadores usam o mesmo desenho.
CT não criptografa nada e não protege um servidor sozinho. É um mecanismo de visibilidade. Ele mostra quais certificados foram emitidos, quando foram registrados e quais nomes cobrem. Não mostra se um host está no ar, o que ele serve ou quem o opera hoje.
A primeira pergunta de quase todo mundo é por que um certificado precisa aparecer num log público. A resposta é a fiscalização feita pelos navegadores, e o desenho inclui um passo que torna essa fiscalização possível sem uma dependência circular.
O próprio projeto explica o fluxo na página de funcionamento, em https://certificate.transparency.dev/howctworks/. Em forma simplificada:
O pré-certificado resolve um problema de ordem. A CA não consegue obter um SCT para o certificado final sem antes enviar algo a um log, e o navegador não deveria aceitar o certificado final antes de ele ter um SCT. O pré-certificado quebra esse ciclo.
Os logs são append-only. Entradas podem ser adicionadas, mas não apagadas, alteradas ou inseridas depois. Cada log mantém uma árvore de Merkle, que permite a qualquer pessoa verificar que um certificado está incluído (prova de inclusão) e que o log só cresceu com o tempo (prova de consistência). A seção 2 da RFC 9162 descreve a árvore. Você não precisa implementá-la para usar os dados.
Dois pontos importam para quem defende. Primeiro, a garantia é sobre registro, não sobre confiança. Um certificado registrado pode ser válido, ter sido emitido por engano ou de forma indevida, e o log não diz qual dos três. Segundo, a cobertura se limita a certificados de CAs com confiança pública. Certificados de uma PKI privada normalmente nunca chegam a um log público, então um resultado limpo no CT não encerra a verificação de todo o seu ambiente.
Três usos aparecem sempre.
Inventário. Equipes criam nomes para ambientes de teste, páginas de marketing, integrações com fornecedores e projetos antigos. Muitos desses nomes nunca entram na zona DNS que alguém revisa. Uma solicitação de certificado deixa registro, então o CT pode mostrar nomes que o seu inventário deixou de fora.
Certificados que ninguém pediu. Se um certificado aparece para o seu domínio e ninguém da equipe o solicitou, vale investigar. Pode ser um fornecedor agindo em seu nome, uma conta antiga, um provedor que você esqueceu ou um atacante que ganhou controle de um caminho de validação. O log sozinho não diz qual dos casos é, então o assunto vai para quem administra o DNS e as contas de certificado do domínio.
Higiene do ciclo de vida. Certificados expirados continuam aparecendo no CT. Esse histórico é útil: dá para ver quais nomes existiram e encontrar serviços desativados que ainda têm registros DNS.
Um resultado de CT é uma pista, não um veredito. Um nome pode estar desatualizado, pertencer a um fornecedor, ser um curinga que cobre muitos hosts ou vir de um erro de digitação. Cada pista precisa ser confirmada pelo dono do ativo.
O crt.sh é uma interface pública de busca sobre logs de CT, mantida por um terceiro. Você pode pesquisar pelo navegador ou receber JSON acrescentando output=json à consulta. Sua pesquisa vai para esse serviço, então pesquise apenas domínios que você pode discutir. Nome de domínio é informação pública. Um nome de produto ainda não anunciado ou um hostname interno não deve ser digitado numa caixa de busca de terceiros.
Existem outros serviços de busca em CT. Os resultados podem variar entre índices e entre momentos de consulta, então anote qual serviço você usou e quando.
O laboratório lê apenas dados públicos de CT. Você não se conecta a nenhum host encontrado. Uma consulta DNS de um nome é um pedido a um resolvedor, não uma conexão ao host, mas não vá além disso sem permissão do dono.
Abra https://crt.sh/?q=example.com no navegador. Troque example.com pelo seu domínio. Cada linha é um certificado. Leia o emissor, as datas de validade e os nomes listados. Depois teste a forma com curinga, https://crt.sh/?q=%.example.com, que pede nomes abaixo do domínio. Compare as quantidades das duas buscas.
Rode:
curl -s 'https://crt.sh/?q=example.com&output=json' | jq -r '.[].name_value' | sort -u | head -50O pipeline funciona em quatro partes. O curl baixa um array JSON, com um objeto por certificado. O jq -r '.[].name_value' imprime o campo name_value de cada objeto, sem aspas. Algumas entradas trazem vários nomes separados por quebra de linha, e o sort -u remove duplicados. O head -50 mantém a saída legível.
O jq não está instalado na minha máquina de teste, então não pude rodar essa linha aqui. Usei a mesma lógica com Python 3.12, depois de baixar o JSON com curl:
curl -s -o crt.json 'https://crt.sh/?q=example.com&output=json'import json
import sys
records = json.load(open(sys.argv[1], encoding="utf-8"))
names = set()
for record in records:
for name in record["name_value"].split("\n"):
names.add(name.strip())
for name in sorted(names)[:50]:
print(name)Salve como crt_names.py e rode com python crt_names.py crt.json. Esta é a saída que observei em 08/11/2026. O crt.sh respondeu HTTP 200 com 85 registros de certificado, que continham 12 nomes únicos:
*.example.com
AS207960 Test Intermediate - example.com
dev.example.com
emudhra-lab.example.com
example.com
m.example.com
m.testexample.com
products.example.com
[email protected]
support.example.com
[email protected]
www.example.comTrês coisas chamam a atenção. O curinga *.example.com cobre qualquer subdomínio direto, mas não diz quais hosts existem. A linha "AS207960 Test Intermediate - example.com" não é um hostname. Parece um nome de assunto copiado de um certificado de CA de teste. As entradas [email protected] e [email protected] parecem identidades de e-mail, de certificados emitidos para esse fim. Um script que trata cada linha como hostname gera ruído.
A ordem do sort -u depende da localidade do seu sistema, então pode diferir da saída do Python. O que importa é o conjunto de nomes.
Exporte os nomes do seu provedor DNS ou do arquivo de zona, um nome totalmente qualificado por linha, em minúsculas e sem ponto final. Depois compare as duas listas:
LC_ALL=C sort -u zone-names.txt > zone.sorted
LC_ALL=C sort -u ct-names.txt > ct.sorted
LC_ALL=C comm -13 zone.sorted ct.sortedO comm -13 mostra as linhas que aparecem só no segundo arquivo. São os nomes que aparecem no CT e não na sua zona. Curingas também aparecem aí, então confira-os à mão. Para a comparação completa, remova o recorte [:50] do script Python antes de gerar o ct-names.txt. Não rodei esse passo numa zona real, porque não controlo a zona de example.com. A comparação funciona do mesmo jeito com qualquer lista de nomes.
Alguns nomes são legítimos, mas ficam fora da zona que você exportou, por exemplo em outra zona no mesmo provedor ou atrás de um CNAME. Trate "não está no meu arquivo de zona" como uma pergunta, não como um achado.
| Achado | O que pode significar | Próximo passo |
|---|---|---|
| Na zona, certificado ainda válido | Esperado | Registre e siga em frente |
| Só no CT, certificado expirado | Serviço desativado ou nome antigo de teste | Confirme com o dono e atualize o inventário |
| Entrada com curinga | Cobre nomes que você talvez não liste | Verifique quais dos seus nomes ele protege |
| Texto livre ou identidade de e-mail | Não é hostname | Tire do inventário e guarde nas notas |
| Nome desconhecido, certificado atual | Possivelmente um serviço esquecido | Pergunte ao dono. Não sonde o host |
| Certificado de uma CA que sua equipe nunca usa | Possível emissão indevida ou problema de conta | Escale para quem controla o DNS e as contas de CA |
Guarde um registro curto de cada revisão, para que outra pessoa consiga repetir:
Domínio:
Consulta e data (UTC):
Fonte e formato (crt.sh, JSON):
Certificados retornados:
Nomes únicos:
Nomes que batem com a zona:
Nomes que precisam de confirmação do dono:
Dono contatado (quem, quando):Assine um monitor de CT para o seu domínio. O projeto CT observa que os monitores verificam os logs por você e podem avisar quando um certificado é registrado para o seu domínio. Assim, uma revisão pontual vira uma verificação contínua.
Leia as seções 2 e 8 da RFC 9162. A seção 2 cobre as árvores de Merkle por trás dos logs. A seção 8 trata de quem os verifica, incluindo os monitores, que são os que mais importam para o seu domínio.
Em seguida, como escrever seu primeiro relatório de segurança mostra como transformar uma pista como esta num texto curto que o dono do ativo consegue verificar e agir.
OSINT e reconhecimento
Aprenda finalidade, proporcionalidade, consentimento e minimização de dados em OSINT, com noções de LGPD e GDPR e um modelo de plano de pesquisa.
OSINT e reconhecimento
O que é OSINT, como verificar informações públicas, onde ficam os limites éticos e como escrever um relatório curto com evidências.