Skip to content

Instantly share code, notes, and snippets.

@itxsoumya
Created February 5, 2021 11:34
Show Gist options
  • Save itxsoumya/3b22972578c8852b80576e7c9e897da9 to your computer and use it in GitHub Desktop.
Save itxsoumya/3b22972578c8852b80576e7c9e897da9 to your computer and use it in GitHub Desktop.
find out subdomain using golang :)
package main
import (
"bufio"
"errors"
"flag"
"fmt"
"os"
"github.com/miekg/dns"
)
type empty struct{}
type result struct {
IPAddress string
Hostname string
}
func main() {
var (
flDomain = flag.String("d", "", "The Domain to perform guessing against")
flWordlist = flag.String("w", "", "The wordlist use for guessing")
flWorkerCount = flag.Int("c", 1000, "The ammount of workers to use")
flServerAddr = flag.String("s", "8.8.8.8:53", "The dns Server to use")
)
flag.Parse()
checkArgs(flDomain, flWordlist)
// fmt.Println(*flWorkerCount, *flServerAddr)
var results []result
fqdns := make(chan string, *flWorkerCount)
gather := make(chan []result)
tracker := make(chan empty)
fh, err := os.Open(*flWordlist)
if err != nil {
panic(err)
}
defer fh.Close()
scanner := bufio.NewScanner(fh)
for i := 0; i < *flWorkerCount; i++ {
go worker(tracker, fqdns, gather, *flServerAddr)
}
for scanner.Scan() {
fqdns <- fmt.Sprintf("%s.%s", scanner.Text(), *flDomain)
}
go func() {
for r := range gather {
results = append(results, r...)
}
var e empty
tracker <- e
}()
close(fqdns)
for i := 0; i < *flWorkerCount; i++ {
<-tracker
}
close(gather)
<-tracker
for _, r := range results {
fmt.Printf("%s\t%s\n", r.Hostname, r.IPAddress)
}
}
// returns list of ip address
func lookupA(fqdn, serverAddr string) ([]string, error) {
var m dns.Msg
var ips []string
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA)
in, err := dns.Exchange(&m, serverAddr)
if err != nil {
return ips, err
}
if len(in.Answer) < 1 {
return ips, errors.New("no answer")
}
for _, answer := range in.Answer {
if a, ok := answer.(*dns.A); ok {
ips = append(ips, a.A.String())
}
}
return ips, nil
}
// returns a list of hostnames
func lookupCNAME(fqdn, serverAddr string) ([]string, error) {
var m dns.Msg
var fqdns []string
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeCNAME)
in, err := dns.Exchange(&m, serverAddr)
if err != nil {
return fqdns, err
}
if len(in.Answer) < 1 {
return fqdns, errors.New("no answer")
}
for _, answer := range in.Answer {
if c, ok := answer.(*dns.CNAME); ok {
fqdns = append(fqdns, c.Target)
}
}
return fqdns, nil
}
func lookup(fqdn, serverAddr string) []result {
var results []result
var cfqdn = fqdn
for {
cnames, err := lookupCNAME(cfqdn, serverAddr)
if err == nil && len(cnames) > 0 {
cfqdn = cnames[0]
continue // we hae to process the next CNAME
}
ips, err := lookupA(cfqdn, serverAddr)
if err != nil {
break // there are no records for this host name
}
for _, ip := range ips {
results = append(results, result{IPAddress: ip, Hostname: fqdn})
}
break // we have processed all the requests
}
return results
}
// worker function
func worker(tracker chan empty, fqdns chan string, gather chan []result, serverAddr string) {
for fqdn := range fqdns {
results := lookup(fqdn, serverAddr)
if len(results) > 0 {
gather <- results
}
}
var e empty
tracker <- e
}
func checkArgs(d *string, w *string) {
if *d == "" || *w == "" {
fmt.Println("domain and wordlist are required")
os.Exit(1)
}
}
@itxsoumya
Copy link
Author

find sub domain using golang :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment