Repository: hakluke/hakip2host Branch: main Commit: da8b628d62c8 Files: 4 Total size: 4.6 KB Directory structure: gitextract_4ypvgk_p/ ├── .gitignore ├── README.md ├── go.mod └── hakip2host.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib hakip2host # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ ================================================ FILE: README.md ================================================ # hakip2host hakip2host takes a list of IP addresses via stdin, then does a series of checks to return associated domain names. Current supported checks are: - DNS PTR lookups - Subject Alternative Names (SANs) on SSL certificates - Common Names (CNs) on SSL certificates ## Installation Install golang, then: ``` go install github.com/hakluke/hakip2host@latest ``` ## Help ``` ./hakip2host --help ``` ## Example usage ``` hakluke$ prips 173.0.84.0/24 | ./hakip2host [DNS-PTR] 173.0.84.23 new-creditcenter.paypal.com. [DNS-PTR] 173.0.84.11 slc-a-origin-www-1.paypal.com. [DNS-PTR] 173.0.84.10 admin.paypal.com. [DNS-PTR] 173.0.84.30 ss-www.paypal.com. [DNS-PTR] 173.0.84.5 www.gejscript-paypal.com. [DNS-PTR] 173.0.84.24 slc-a-origin-demo.paypal.com. [DNS-PTR] 173.0.84.20 origin-merchantweb.paypal.com. [SSL-SAN] 173.0.84.67 uptycspay.paypal.com [SSL-SAN] 173.0.84.67 a.paypal.com [SSL-CN] 173.0.84.67 api.paypal.com [SSL-SAN] 173.0.84.76 svcs.paypal.com [SSL-SAN] 173.0.84.76 uptycshon.paypal.com [SSL-SAN] 173.0.84.76 uptycshap.paypal.com [SSL-SAN] 173.0.84.76 uptycsven.paypal.com [SSL-SAN] 173.0.84.76 uptycsize.paypal.com [SSL-SAN] 173.0.84.76 uptycspay.paypal.com [SSL-CN] 173.0.84.76 svcs.paypal.com ``` ================================================ FILE: go.mod ================================================ module github.com/hakluke/hakip2host go 1.16 ================================================ FILE: hakip2host.go ================================================ package main import ( "bufio" "context" "crypto/tls" "flag" "fmt" "log" "net" "net/http" "os" "strings" "sync" "time" ) // This function grabs the SSL certificate, then dumps the SAN and CommonName func sslChecks(ip string, resChan chan<- string, client *http.Client) { url := ip // make sure we use https as we're doing SSL checks if strings.HasPrefix(ip, "http://") { url = strings.Replace(ip, "http://", "https://", 1) } else if !strings.HasPrefix(ip, "https://") { url = "https://" + ip } req, reqErr := http.NewRequest("HEAD", url, nil) if reqErr != nil { return } resp, clientErr := client.Do(req) if clientErr != nil { return } if resp.TLS != nil && len(resp.TLS.PeerCertificates) > 0 { dnsNames := resp.TLS.PeerCertificates[0].DNSNames for _, name := range dnsNames { resChan <- "[SSL-SAN] " + ip + " " + string(name) } resChan <- "[SSL-CN] " + ip + " " + resp.TLS.PeerCertificates[0].Subject.CommonName } } // Do a DNS PTR lookup on the IP func dnsChecks(ip string, resChan chan<- string, resolver *net.Resolver) { addr, err := resolver.LookupAddr(context.Background(), ip) if err != nil { return } for _, a := range addr { resChan <- "[DNS-PTR] " + ip + " " + a } } func worker(jobChan <-chan string, resChan chan<- string, wg *sync.WaitGroup, transport *http.Transport, client *http.Client, resolver *net.Resolver) { defer wg.Done() for job := range jobChan { sslChecks(job, resChan, client) dnsChecks(job, resChan, resolver) } } func main() { workers := flag.Int("t", 32, "numbers of threads") resolverIP := flag.String("r", "", "IP of DNS resolver for lookups") dnsProtocol := flag.String("protocol", "udp", "Protocol for DNS lookups (tcp or udp)") resolverPort := flag.Int("p", 53, "Port to bother the specified DNS resolver on") flag.Parse() scanner := bufio.NewScanner(os.Stdin) jobChan := make(chan string) resChan := make(chan string) done := make(chan struct{}) // Set up TLS transport var transport = &http.Transport{ Dial: (&net.Dialer{ Timeout: 5 * time.Second, }).Dial, TLSHandshakeTimeout: 5 * time.Second, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } // Set up HTTP client var client = &http.Client{ Timeout: time.Second * 10, Transport: transport, } // Set up DNS resolver var resolver *net.Resolver if *resolverIP != "" { resolver = &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d := net.Dialer{} return d.DialContext(ctx, *dnsProtocol, fmt.Sprintf("%s:%d", *resolverIP, *resolverPort)) }, } } var wg sync.WaitGroup wg.Add(*workers) go func() { wg.Wait() close(done) }() for i := 0; i < *workers; i++ { go worker(jobChan, resChan, &wg, transport, client, resolver) } go func() { for scanner.Scan() { jobChan <- scanner.Text() } if err := scanner.Err(); err != nil { log.Println(err) } close(jobChan) }() for { select { case <-done: return case res := <-resChan: if strings.HasSuffix(res, ".") { res = res[:len(res)-1] } fmt.Println(res) } } }