-
Notifications
You must be signed in to change notification settings - Fork 0
/
scope-resolver.go
145 lines (121 loc) · 3.06 KB
/
scope-resolver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"bufio"
"context"
"crypto/tls"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"sync"
"time"
)
// 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)
}
}
}