ct-watch
A Go library to monitor Certificate Transparency logs. Streams newly issued SSL/TLS certificates from all publicly trusted CT logs.
What Are Certificate Transparency Logs?
Certificate Transparency (CT) logs are public, append-only records of all SSL/TLS certificates issued by trusted Certificate Authorities. They make certificate issuance fully visible, enabling instant detection of suspicious or unauthorized certificates.
Certificate Transparency is designed to prevent and mitigate incidents like this one.
How Is It Useful?
Modern browsers enforce Certificate Transparency – the browser won't initiate an HTTPS connection with a certificate from a trusted CA unless it is published in CT logs. In practice, this means that by monitoring CT logs, you can see all domains that have HTTPS enabled with a trusted CA as soon as the certificate is issued.
This has many applications around cybersecurity and threat intelligence:
- Phishing Detection: Monitor for typosquatting domains (e.g.,
paypa1.com targeting paypal.com)
- Brand Protection: Detect unauthorized certificates for your domains
- Asset Discovery: Find all subdomains in the organization
- Threat Intelligence: Build your own database of domains, enrich them, and calculate risk and reputation based on your own criteria
We rely on this library to scrape domains for our own Domain Search.
Usage
package main
import (
"context"
"fmt"
"os"
"github.com/google/certificate-transparency-go/x509"
// import ct-watch
"github.com/malfors-hq/ct-watch"
)
// create a certificate processor
// it is called for each discovered certificate in real time
type DomainProcessor struct{}
func (p *DomainProcessor) Process(cert *x509.Certificate) error {
// write your own logic to process a certificate
// e.g. save to a database, extract DNS names, enrich, assess suspicion, report, etc.
for _, dnsName := range cert.DNSNames {
fmt.Println(dnsName) // in this example, we just print all domains to stdout
}
return nil
}
func main() {
// initialize & start a watcher
watcher := ctwatch.New(ctwatch.Options{
Logger: nil, // optional: provide a *log.Logger if you want to see debug logs
Processors: []ctwatch.X509CertProcessor{&DomainProcessor{}}, // pass one or more processors
})
if err := watcher.Start(context.Background()); err != nil {
os.Exit(1)
}
}
Acknowledgments
Built on top of Google's Certificate Transparency Go library.
Some inspiration came from CaliDog/certstream-server.