OSINT e recon
Flusso OSINT da zero, con IA come copilota
Flusso OSINT ripetibile per un bersaglio che puoi guardare: definisci ambito, raccogli a fasi, correla e la chat di NotHoly riassume.
Come i log di Certificate Transparency registrano i certificati TLS pubblici e come esaminare i risultati di crt.sh per un dominio di tua proprietà senza toccarne gli host.
Certificate Transparency (CT) è un registro pubblico dei certificati TLS. Quando un'autorità di certificazione (CA) emette un certificato pubblicamente attendibile, lo scrive in uno o più log CT. Chiunque può leggere i log, e nessuno può modificarli di nascosto. Se possiedi un dominio, hai quindi una cronologia consultabile dei certificati pubblici emessi per i nomi sotto quel dominio, compresi quelli che nessuno del tuo team ricorda di aver richiesto.
Il protocollo è specificato in RFC 9162, "Certificate Transparency Version 2.0", pubblicata nel dicembre 2021. Sostituisce la specifica originale, RFC 6962. Controlla la riga di stato prima di citarla. RFC 9162 è un documento Experimental, non una specifica dell'Internet Standards Track, e la RFC stessa lo dichiara. Resta comunque il riferimento per il funzionamento dei log, e i browser si appoggiano allo stesso design.
CT non cifra niente e da solo non protegge un server. È un meccanismo di visibilità. Ti dice quali certificati sono stati emessi, quando sono stati registrati e quali nomi coprono. Non ti dice se un host è online, cosa espone o chi lo gestisce oggi.
La prima domanda che si fa la maggior parte delle persone è perché un certificato debba comparire in un log pubblico. La risposta è che lo impongono i browser, e il design include un passaggio che rende possibile questo obbligo senza una dipendenza circolare.
Il progetto CT spiega il flusso nella sua pagina sul funzionamento, all'indirizzo https://certificate.transparency.dev/howctworks/. In forma semplificata:
Il precertificato risolve un problema di ordine. Una CA non può ottenere un SCT per il certificato finale senza prima inviare qualcosa a un log, e un browser non dovrebbe accettare il certificato finale prima che abbia un SCT. Il precertificato spezza quel ciclo.
I log sono di sola aggiunta. Le voci si possono aggiungere, ma non cancellare, modificare o inserire a posteriori. Ogni log mantiene un albero di Merkle, che permette a chiunque di verificare che un dato certificato sia incluso (una prova di inclusione) e che il log sia solo cresciuto nel tempo (una prova di coerenza). La sezione 2 di RFC 9162 descrive l'albero. Per usare i dati non devi implementarlo.
Per chi difende contano due dettagli. Primo, la garanzia riguarda la registrazione, non la fiducia. Un certificato registrato può essere valido, errato o emesso in modo improprio, e il log non può dirti quale dei tre. Secondo, la copertura è limitata ai certificati delle CA pubblicamente attendibili. I certificati di una CA privata di solito non arrivano mai a un log pubblico, quindi un risultato CT pulito non assolve tutta la tua infrastruttura.
Tre usi tornano di continuo.
Inventario. I team creano hostname per ambienti di test, pagine di marketing, integrazioni con vendor e vecchi progetti. Molti di quei nomi non arrivano mai nel file di zona DNS che qualcuno controlla. Una richiesta di certificato lascia una traccia, quindi CT può far emergere nomi sfuggiti al tuo inventario.
Individuare certificati che nessuno ha richiesto. Se compare un certificato per il tuo dominio e nessuno del tuo team lo ha chiesto, merita un'occhiata. Può essere un vendor che agisce per conto tuo, un vecchio account, un provider che avevi dimenticato o un attaccante che ha preso il controllo di un percorso di validazione. Il log da solo non può dirti quale, quindi porti il caso a chi gestisce il DNS e gli account dei certificati del dominio.
Igiene del ciclo di vita. I certificati scaduti compaiono ancora in CT. Quella cronologia è utile. Puoi vedere quali nomi esistevano e trovare servizi dismessi che hanno ancora record DNS.
Un risultato CT è una pista, non un verdetto. Un nome può essere obsoleto, appartenere a un vendor, essere un wildcard che copre molti host o nascere da un refuso. Ogni pista va confermata dal proprietario dell'asset.
crt.sh è un'interfaccia di ricerca pubblica per i log CT, gestita da terzi. Puoi cercare in un browser, oppure ottenere JSON aggiungendo output=json alla query. La tua query va a quel servizio, quindi cerca solo domini di cui puoi parlare. Un nome di dominio è un'informazione pubblica. Il nome di un prodotto non annunciato o un hostname interno non va digitato nella casella di ricerca di terzi.
Esistono altri servizi di ricerca CT. I risultati possono variare da un indice all'altro e a seconda del momento della query, quindi annota quale servizio hai usato e quando.
Il laboratorio legge solo dati CT pubblici. Non ti colleghi a nessun host che trovi. Una ricerca DNS di un nome è una query a un resolver, non una connessione all'host, ma non andare oltre senza il permesso del proprietario.
Apri https://crt.sh/?q=example.com in un browser. Sostituisci example.com con il tuo dominio. Ogni riga è un certificato. Leggi l'emittente, le date di validità e i nomi elencati. Poi prova la forma wildcard, https://crt.sh/?q=%.example.com, che chiede i nomi sotto il dominio. Confronta i conteggi delle due ricerche.
Esegui:
curl -s 'https://crt.sh/?q=example.com&output=json' | jq -r '.[].name_value' | sort -u | head -50La pipeline ha quattro parti. curl scarica un array JSON con un oggetto per certificato. jq -r '.[].name_value' stampa senza virgolette il campo name_value di ogni oggetto. Alcune voci contengono più nomi separati da a capo, e sort -u toglie i duplicati. head -50 mantiene leggibile l'output.
Sulla mia macchina di test jq non è installato, quindi qui non ho potuto eseguire quella riga. Ho eseguito la stessa logica con Python 3.12 dopo aver scaricato il JSON con 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)Salvalo come crt_names.py ed eseguilo con python crt_names.py crt.json. Questo è l'output che ho osservato il 2026-11-08. crt.sh ha risposto HTTP 200 con 85 record di certificati, che contenevano 12 nomi distinti:
*.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.comSpiccano tre cose. Il wildcard *.example.com copre qualsiasi sottodominio diretto, ma non dice quali host esistono. La riga "AS207960 Test Intermediate - example.com" non è un hostname. Sembra un subject name copiato da un certificato di una CA di test. Le voci [email protected] e [email protected] sembrano identità email di certificati emessi a quello scopo. Uno script che tratta ogni riga come un hostname produrrà rumore.
L'ordine di sort -u dipende dal locale, quindi può differire dall'output di Python. Quello che conta è l'insieme dei nomi.
Esporta i nomi dal tuo provider DNS o dal file di zona, un nome completo per riga, in minuscolo, senza punto finale. Poi confronta i due elenchi:
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.sortedcomm -13 stampa le righe presenti solo nel secondo file. Sono i nomi che compaiono in CT ma non nella tua zona. Lì compariranno anche i wildcard, quindi controllali a mano. Per il confronto completo, togli la slice [:50] dallo script Python prima di scrivere ct-names.txt. Non ho eseguito questo passo su una zona reale, perché non controllo la zona di example.com. Il confronto funziona allo stesso modo con qualsiasi elenco di nomi.
Alcuni nomi sono legittimi ma stanno fuori dalla zona che hai esportato, per esempio in un'altra zona presso lo stesso provider o dietro un CNAME. Considera "non presente nel mio file di zona" una domanda, non un finding.
| Finding | Cosa può significare | Passo successivo |
|---|---|---|
| Nella zona, certificato ancora valido | Atteso | Registralo e vai avanti |
| Solo in CT, certificato scaduto | Servizio dismesso o vecchio nome di test | Conferma con il proprietario, poi aggiorna l'inventario |
| Voce wildcard | Copre nomi che potresti non elencare | Controlla quali dei tuoi nomi protegge |
| Testo libero o identità email | Non è un hostname | Toglilo dall'inventario, tienilo negli appunti |
| Nome sconosciuto, certificato attuale | Forse un servizio dimenticato | Chiedi al proprietario. Non sondare l'host |
| Certificato di una CA che il tuo team non usa mai | Possibile emissione impropria o problema di account | Porta il caso a chi controlla gli account DNS e CA |
Tieni una breve scheda per ogni controllo, così la persona successiva può ripeterlo:
Domain:
Query and date (UTC):
Source and format (crt.sh, JSON):
Certificates returned:
Unique names:
Names matching the zone:
Names needing owner confirmation:
Owner contacted (who, when):Iscriviti a un monitor CT per il tuo dominio. Il progetto CT spiega che i monitor controllano i log per te e possono avvisarti quando viene registrato un certificato per il tuo dominio. Così un controllo una tantum diventa un controllo continuo.
Leggi le sezioni 2 e 8 di RFC 9162. La sezione 2 riguarda gli alberi di Merkle su cui si reggono i log. La sezione 8 riguarda le parti che li controllano, compresi i monitor, che sono quelli che contano per il tuo dominio.
Poi, come scrivere il tuo primo report di sicurezza mostra come trasformare una pista come questa in un breve writeup che il proprietario dell'asset può verificare e su cui può agire.
OSINT e recon
Flusso OSINT ripetibile per un bersaglio che puoi guardare: definisci ambito, raccogli a fasi, correla e la chat di NotHoly riassume.
OSINT e recon
Enumera i sottodomini di un ambito tuo: subfinder, amass, findomain e chaos via anew e httpx, con la chat di NotHoly per il triage.
OSINT e recon
Raccogli URL e parametri di un ambito tuo con gospider, hakrawler, waybackurls e gau, poi filtra con qsreplace e la chat di NotHoly.