136 lines
2.8 KiB
Go
136 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"time"
|
|
|
|
"patdown/common"
|
|
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
type multiflag []string
|
|
|
|
type Pair struct {
|
|
Nameserver string
|
|
Domain string
|
|
}
|
|
|
|
func (m *multiflag) String() string {
|
|
return "irc.supernets.org #superbowl"
|
|
}
|
|
|
|
func (m *multiflag) Set(value string) error {
|
|
*m = append(*m, value)
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
domain = flag.String("t", "", "domain to query")
|
|
workers = flag.Int("c", 100, "number of workers")
|
|
delay = flag.Int("s", 100, "delay (sleep) between queries in milliseconds")
|
|
nameserver multiflag
|
|
)
|
|
|
|
func message(domain string, reqtype uint16, ra bool) *dns.Msg {
|
|
msg := new(dns.Msg)
|
|
msg.Id = dns.Id()
|
|
msg.RecursionDesired = ra
|
|
msg.Question = make([]dns.Question, 1)
|
|
msg.Question[0] = dns.Question{dns.Fqdn(domain), reqtype, dns.ClassINET}
|
|
return msg
|
|
}
|
|
|
|
func query(q <-chan Pair, tracker chan<- interface{}) {
|
|
for pair := range q {
|
|
msg := message(pair.Domain, dns.TypeA, false)
|
|
// fmt.Println("Querying ", pair.Domain, " on ", pair.Nameserver)
|
|
in, err := dns.Exchange(msg, pair.Nameserver+":53")
|
|
if err != nil {
|
|
common.Error(err.Error())
|
|
continue
|
|
}
|
|
|
|
if len(in.Answer) > 0 {
|
|
fmt.Printf("[%s] associated domain %s found on %s\n", common.Vendors[common.Domains[pair.Domain]], pair.Domain, pair.Nameserver)
|
|
}
|
|
time.Sleep(time.Duration(*delay) * time.Millisecond)
|
|
}
|
|
tracker <- 1337
|
|
}
|
|
|
|
func testns(ns string) error {
|
|
msg := message("supernets.org", dns.TypeA, false)
|
|
_, err := dns.Exchange(msg, ns+":53")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
flag.Var(&nameserver, "n", "nameserver to query")
|
|
flag.Usage = common.Usage
|
|
flag.Parse()
|
|
|
|
var nameservers []string
|
|
pairs := make(chan Pair)
|
|
tracker := make(chan interface{})
|
|
|
|
common.Banner()
|
|
|
|
if *domain != "" {
|
|
// query domain for nameservers
|
|
nsmsg := message(*domain, dns.TypeNS, true)
|
|
in, err := dns.Exchange(nsmsg, "1.1.1.1:53")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
for _, ans := range in.Answer {
|
|
ns, ok := ans.(*dns.NS)
|
|
if ok {
|
|
nameservers = append(nameservers, ns.Ns)
|
|
}
|
|
}
|
|
|
|
fmt.Println(nameservers)
|
|
} else if len(nameserver) > 0 {
|
|
for _, ns := range nameserver {
|
|
nameservers = append(nameservers, ns)
|
|
}
|
|
} else {
|
|
// print usage
|
|
}
|
|
|
|
common.Info("aggregating nameservers...")
|
|
|
|
for i, ns := range nameservers {
|
|
if err := testns(ns); err != nil {
|
|
common.Error("nameserver " + ns + " is not responding")
|
|
nameservers = append(nameservers[:i], nameservers[i+1:]...)
|
|
}
|
|
}
|
|
|
|
common.Info(fmt.Sprintf("snooping EDR domains from %d resolvers...", len(nameservers)))
|
|
|
|
go func() {
|
|
for i := 0; i < *workers; i++ {
|
|
query(pairs, tracker)
|
|
}
|
|
}()
|
|
|
|
for _, ns := range nameservers {
|
|
for k, _ := range common.Domains {
|
|
pairs <- Pair{Nameserver: ns, Domain: k}
|
|
}
|
|
}
|
|
|
|
close(pairs)
|
|
|
|
for x := 0; x < *workers; x++ {
|
|
<-tracker
|
|
}
|
|
}
|