12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- package scan
- import (
- "crypto/tls"
- "crypto/x509"
- "net"
- "sync"
- "time"
- "github.com/cloudflare/cfssl/bundler"
- )
- // Broad contains scanners for large swaths of TLS hosts on the internet.
- var Broad = &Family{
- Description: "Large scale scans of TLS hosts",
- Scanners: map[string]*Scanner{
- "IntermediateCAs": {
- "Scans a CIDR IP range for unknown Intermediate CAs",
- intermediateCAScan,
- },
- },
- }
- func incrementBytes(bytes []byte) {
- lsb := len(bytes) - 1
- bytes[lsb]++
- if bytes[lsb] == 0 {
- incrementBytes(bytes[:lsb])
- }
- }
- var (
- caBundleFile = "/etc/cfssl/ca-bundle.crt"
- intBundleFile = "/etc/cfssl/int-bundle.crt"
- numWorkers = 32
- timeout = time.Second
- )
- // intermediateCAScan scans for new intermediate CAs not in the trust store.
- func intermediateCAScan(addr, hostname string) (grade Grade, output Output, err error) {
- cidr, port, _ := net.SplitHostPort(addr)
- _, ipnet, err := net.ParseCIDR(cidr)
- if err != nil {
- return Skipped, nil, nil
- }
- b, err := bundler.NewBundler(caBundleFile, intBundleFile)
- if err != nil {
- return
- }
- var wg sync.WaitGroup
- wg.Add(numWorkers)
- dialer := &net.Dialer{Timeout: timeout}
- config := &tls.Config{InsecureSkipVerify: true}
- addrs := make(chan string)
- chains := make(chan []*x509.Certificate, numWorkers)
- go func() {
- for chain := range chains {
- b.Bundle(chain, nil, bundler.Force)
- }
- }()
- for i := 0; i < numWorkers; i++ {
- go func() {
- for addr := range addrs {
- conn, err := tls.DialWithDialer(dialer, Network, addr, config)
- if err != nil {
- continue
- }
- conn.Close()
- if conn.ConnectionState().HandshakeComplete {
- chains <- conn.ConnectionState().PeerCertificates
- }
- }
- wg.Done()
- }()
- }
- for ip := ipnet.IP.To16(); ipnet.Contains(ip); incrementBytes(ip) {
- addrs <- net.JoinHostPort(ip.String(), port)
- }
- close(addrs)
- wg.Wait()
- close(chains)
- grade = Good
- return
- }
|