diff --git a/README.md b/README.md index ddfd2be..0dd9b34 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Reality - Tls - Scanner +# Reality - TLS - Scanner Build ``` @@ -10,5 +10,5 @@ Usage Recommend to run this tool locally. It may cause VPS to be flagged if you run scanner in the cloud. ``` ./RealiTLScanner -addr www.microsoft.com -./RealiTLScanner -addr 20.81.111.85 -`` +./RealiTLScanner -addr 20.81.111.85 -thread 10 +``` diff --git a/main.go b/main.go index 037e7c3..51b6fcf 100644 --- a/main.go +++ b/main.go @@ -4,38 +4,49 @@ import ( "crypto/tls" "flag" "fmt" + "math/big" "net" + "sync" "time" ) func main() { addrPtr := flag.String("addr", "127.0.0.1", "Destination to start scan") portPtr := flag.String("port", "443", "Port to scan") + threadPtr := flag.Int("thread", 2, "Number of threads to scan in parallel") flag.Parse() - fmt.Println("Reality Tls Scanner running: ", *addrPtr, ":", *portPtr) + fmt.Println("Reality TLS Scanner running: ", *addrPtr, ":", *portPtr) s := Scanner { addr: *addrPtr, port: *portPtr, timeout: 10 * time.Second, - numberOfThread: 1, + numberOfThread: *threadPtr, + mu: new(sync.Mutex), } s.Run() } type Scanner struct { - addr string - port string - timeout time.Duration + addr string + port string + timeout time.Duration numberOfThread int + mu *sync.Mutex + high net.IP + low net.IP } -func (s Scanner) Run() { +func (s *Scanner) Run() { conn, err := net.DialTimeout("tcp", s.addr+":"+s.port, s.timeout) if err != nil { fmt.Println("Dial failed: ", err) return } line := "" + conn.RemoteAddr().String() + " \t----- " + s.mu.Lock() + s.high = conn.RemoteAddr().(*net.TCPAddr).IP + s.low = conn.RemoteAddr().(*net.TCPAddr).IP + s.mu.Unlock() conn.SetDeadline(time.Now().Add(s.timeout)) c := tls.Client(conn, &tls.Config { InsecureSkipVerify: true, @@ -44,11 +55,65 @@ func (s Scanner) Run() { err = c.Handshake() if err != nil { fmt.Println("", line, "TLS handshake failed: ", err) - return + } else { + defer c.Close() + state := c.ConnectionState() + fmt.Println("", line, "Found TLS v", TlsDic[state.Version], "\tALPN", state.NegotiatedProtocol, "\t", state.PeerCertificates[0].Subject) } - defer c.Close() - state := c.ConnectionState() - fmt.Println("", line, "Found TLS v", TlsDic[state.Version], "\tALPN", state.NegotiatedProtocol, "\t", state.PeerCertificates[0].Subject) + for i := 0; i < s.numberOfThread; i++ { + go s.Scan(i % 2 == 0) + } + for { + // now the scans are performed in goroutines + } +} + +func (s *Scanner) Scan(increment bool) { + var addr string + s.mu.Lock() + if increment { + s.high = nextIP(s.high, increment) + addr = s.high.String() + } else { + s.low = nextIP(s.low, increment) + addr = s.low.String() + } + s.mu.Unlock() + conn, err := net.DialTimeout("tcp", addr+":"+s.port, s.timeout) + if err != nil { + fmt.Println("Dial failed: ", err) + } else { + line := "" + conn.RemoteAddr().String() + " \t----- " + conn.SetDeadline(time.Now().Add(s.timeout)) + c := tls.Client(conn, &tls.Config { + InsecureSkipVerify: true, + NextProtos: []string{"h2", "http/1.1"}, + }) + err = c.Handshake() + if err != nil { + fmt.Println("", line, "TLS handshake failed: ", err) + } else { + defer c.Close() + state := c.ConnectionState() + fmt.Println("", line, "Found TLS v", TlsDic[state.Version], "\tALPN", state.NegotiatedProtocol, "\t", state.PeerCertificates[0].Subject) + } + } + go s.Scan(increment) +} + +func nextIP(ip net.IP, increment bool) net.IP { + // Convert to big.Int and increment + ipb := big.NewInt(0).SetBytes([]byte(ip)) + if increment { + ipb.Add(ipb, big.NewInt(1)) + } else { + ipb.Sub(ipb, big.NewInt(1)) + } + + // Add leading zeros + b := ipb.Bytes() + b = append(make([]byte, len(ip)-len(b)), b...) + return net.IP(b) } var TlsDic = map[uint16]string{