// This is a very simple tool for checking for POODLE issues in TLS servers. // See https://www.imperialviolet.org/2014/12/08/poodleagain.html package main import ( "bufio" "crypto/tls" "errors" "flag" "fmt" "net" "os" "strings" "sync" "time" ) var ( hostsFile *string = flag.String("hosts", "", "Filename containing hosts to query") onlyAffected *bool = flag.Bool("only-affected", false, "Only show output for affected sites") ) func scanHost(hostname string) error { dialer := net.Dialer{ Timeout: 15 * time.Second, } if !strings.Contains(hostname, ":") { hostname = hostname + ":443" } conn, err := tls.DialWithDialer(&dialer, "tcp", hostname, &tls.Config{ InsecureSkipVerify: true, BreakCBCPadding: true, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, }, }) if err != nil { return err } defer conn.Close() version := conn.ConnectionState().Version if version == tls.VersionSSL30 { return errors.New("SSLv3 negotiated") } conn.Write([]byte("GET / HTTP/1.1\r\nHost: test\r\n\r\n")) var buf [512]byte n, err := conn.Read(buf[:]) if err != nil { return err } fmt.Printf("%d: %s\n", n, buf[:n]) return nil } func worker(hosts <-chan string, done *sync.WaitGroup) { defer done.Done() for hostname := range hosts { err := scanHost(hostname) if err != nil { if !*onlyAffected { fmt.Fprintf(os.Stderr, "%s: %s\n", hostname, err) } continue } fmt.Printf("%s\n", hostname) } } func main() { flag.Parse() var wg sync.WaitGroup const numWorkers = 512 hostnames := make(chan string, numWorkers) for i := 0; i < numWorkers; i++ { wg.Add(1) go worker(hostnames, &wg) } for _, hostname := range os.Args[1:] { hostnames <- hostname } if len(*hostsFile) > 0 { hosts, err := os.Open(*hostsFile) if err != nil { panic(err) } defer hosts.Close() inHosts := bufio.NewScanner(hosts) for inHosts.Scan() { hostnames <- inHosts.Text() } if err := inHosts.Err(); err != nil { panic(err) } } close(hostnames) wg.Wait() }