├── go.mod ├── .gitignore ├── go.sum ├── README.md └── resolveDomains.go /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Josue87/resolveDomains 2 | 3 | go 1.17 4 | 5 | require github.com/miekg/dns v1.1.42 // indirect 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/miekg/dns v1.1.42 h1:gWGe42RGaIqXQZ+r3WUGEKBEtvPHY2SXo4dqixDNxuY= 2 | github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= 3 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= 4 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 5 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 6 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 7 | golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= 8 | golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 9 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 10 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 11 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # resolveDomains 2 | 3 | Given a list of domains, you resolve them and get the IP addresses. 4 | 5 | # Installation 6 | 7 | If you want to make modifications locally and compile it, follow the instructions below: 8 | 9 | ``` 10 | > git clone https://github.com/Josue87/resolveDomains.git 11 | > cd resolveDomains 12 | > go build 13 | ``` 14 | 15 | If you are only interested in using the program: 16 | 17 | ``` 18 | > go get github.com/Josue87/resolveDomains 19 | ``` 20 | 21 | # Usage 22 | 23 | ``` 24 | > resolveDomains -d domainFiles.txt [-t 150] [-r 8.8.8.8:53] 25 | ``` 26 | 27 | Don't forget the ./ in front of the program name if you are compiling locally! 28 | 29 | # Example 30 | 31 | ![image](https://user-images.githubusercontent.com/16885065/119138781-8bbd9f00-ba42-11eb-87f8-63e38fc93e29.png) 32 | 33 | # Author 34 | 35 | This code has been developed by: 36 | 37 | * **Josué Encinar García** -- [@JosueEncinar](https://twitter.com/JosueEncinar) 38 | 39 | Code adapted from: 40 | 41 | * [Subdomain_guesser (Black Hat Go)](https://github.com/blackhat-go/bhg/blob/master/ch-5/subdomain_guesser/main.go) 42 | 43 | At the request of: 44 | 45 | * **Six2dez** -- [@six2dez1](https://twitter.com/six2dez1) 46 | 47 | Please feel free to modify the code or use it in your tools. 48 | -------------------------------------------------------------------------------- /resolveDomains.go: -------------------------------------------------------------------------------- 1 | // The code is adapted by @JosueEncinar from https://github.com/blackhat-go/bhg/blob/master/ch-5/subdomain_guesser/main.go 2 | // For @six2dez's reconfwt 3 | package main 4 | 5 | import ( 6 | "bufio" 7 | "flag" 8 | "fmt" 9 | "os" 10 | 11 | "github.com/miekg/dns" 12 | ) 13 | 14 | type empty struct{} 15 | 16 | type result struct { 17 | IPAddress string 18 | Hostname string 19 | } 20 | 21 | func lookupA(fqdn, resolver string) string { 22 | var m dns.Msg 23 | var in *dns.Msg 24 | var err error 25 | count := 0 26 | m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA) 27 | for { 28 | in, err = dns.Exchange(&m, resolver) 29 | if err != nil || len(in.Answer) < 1 { 30 | count += 1 31 | if count >= 5 { 32 | return "" 33 | } 34 | } else { 35 | break 36 | } 37 | } 38 | for _, answer := range in.Answer { 39 | if a, ok := answer.(*dns.A); ok { 40 | return a.A.String() // Only one ip is desired 41 | } 42 | } 43 | return "" 44 | } 45 | 46 | func lookupCNAME(fqdn, resolver string) []string { 47 | var m dns.Msg 48 | var fqdns []string 49 | m.SetQuestion(dns.Fqdn(fqdn), dns.TypeCNAME) 50 | in, err := dns.Exchange(&m, resolver) 51 | if err != nil || len(in.Answer) < 1 { 52 | return nil 53 | } 54 | for _, answer := range in.Answer { 55 | if c, ok := answer.(*dns.CNAME); ok { 56 | fqdns = append(fqdns, c.Target) 57 | } 58 | } 59 | return fqdns 60 | } 61 | 62 | func lookup(fqdn, resolver string) result { 63 | var cfqdn = fqdn 64 | for { 65 | cnames := lookupCNAME(cfqdn, resolver) 66 | if cnames == nil { 67 | break 68 | } else if len(cnames) > 0 { 69 | cfqdn = cnames[0] 70 | } 71 | } 72 | ip := lookupA(cfqdn, resolver) 73 | if ip != "" { 74 | return result{IPAddress: ip, Hostname: fqdn} 75 | } 76 | return result{} 77 | } 78 | 79 | func worker(tracker chan empty, fqdns chan string, gather chan result, resolver string) { 80 | for fqdn := range fqdns { 81 | result := lookup(fqdn, resolver) 82 | if result.Hostname != "" { 83 | gather <- result 84 | } 85 | } 86 | var e empty 87 | tracker <- e 88 | } 89 | 90 | func main() { 91 | var ( 92 | flDomains = flag.String("d", "", "List of domains to resolve.") 93 | flThreads = flag.Int("t", 100, "The amount of threads to use.") 94 | flResolver = flag.String("r", "8.8.8.8:53", "Resolver DNS to use.") 95 | ) 96 | flag.Parse() 97 | 98 | if *flDomains == "" { 99 | fmt.Println("-d are required") 100 | os.Exit(1) 101 | } 102 | 103 | var results []result 104 | 105 | fqdns := make(chan string, *flThreads) 106 | gather := make(chan result) 107 | tracker := make(chan empty) 108 | 109 | fh, err := os.Open(*flDomains) 110 | if err != nil { 111 | panic(err) 112 | } 113 | defer fh.Close() 114 | scanner := bufio.NewScanner(fh) 115 | 116 | for i := 0; i < *flThreads; i++ { 117 | go worker(tracker, fqdns, gather, *flResolver) 118 | } 119 | 120 | go func() { 121 | for r := range gather { 122 | results = append(results, r) 123 | } 124 | var e empty 125 | tracker <- e 126 | }() 127 | 128 | for scanner.Scan() { 129 | fqdns <- fmt.Sprintf("%s", scanner.Text()) 130 | } 131 | 132 | close(fqdns) 133 | for i := 0; i < *flThreads; i++ { 134 | <-tracker 135 | } 136 | close(gather) 137 | <-tracker 138 | 139 | for _, r := range results { 140 | fmt.Println(r.Hostname + " " + r.IPAddress) 141 | } 142 | } 143 | --------------------------------------------------------------------------------