141 lines
3.8 KiB
Go
141 lines
3.8 KiB
Go
|
package common
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
|
||
|
"github.com/miekg/dns"
|
||
|
)
|
||
|
|
||
|
type Query struct {
|
||
|
Nameserver string
|
||
|
Vendor string
|
||
|
DomainPair Pair
|
||
|
}
|
||
|
|
||
|
type Nameserver struct {
|
||
|
Nameserver string
|
||
|
NonRA bool
|
||
|
Recursive bool
|
||
|
}
|
||
|
|
||
|
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{
|
||
|
Name: dns.Fqdn(domain),
|
||
|
Qtype: reqtype,
|
||
|
Qclass: dns.ClassINET,
|
||
|
}
|
||
|
return msg
|
||
|
}
|
||
|
|
||
|
func ParseNS(nameservers []string) []Nameserver {
|
||
|
var valid []Nameserver
|
||
|
msg := message("cloudflare.com", dns.TypeA, false)
|
||
|
for _, ns := range nameservers {
|
||
|
nonra, ra := false, false
|
||
|
in, err := dns.Exchange(msg, ns+":53")
|
||
|
if err != nil {
|
||
|
Error(fmt.Sprintf("nameserver %s%s%s is not responding to the trial query", ColorGray, ns[0:len(ns)-1], ColorReset))
|
||
|
continue
|
||
|
}
|
||
|
if in.Rcode == dns.RcodeRefused {
|
||
|
Warn(fmt.Sprintf("nameserver %s%s%s refused the trial non-recursive query", ColorGray, ns[0:len(ns)-1], ColorReset))
|
||
|
} else {
|
||
|
Success(fmt.Sprintf("nameserver %s%s%s allows non-recursive queries", ColorGray, ns[0:len(ns)-1], ColorReset))
|
||
|
nonra = true
|
||
|
}
|
||
|
if in.RecursionAvailable {
|
||
|
Success(fmt.Sprintf("nameserver %s%s%s allows recursion", ColorGray, ns[0:len(ns)-1], ColorReset))
|
||
|
ra = true
|
||
|
} else {
|
||
|
Warn(fmt.Sprintf("nameserver %s%s%s does not allow recursion", ColorGray, ns[0:len(ns)-1], ColorReset))
|
||
|
}
|
||
|
|
||
|
valid = append(valid, Nameserver{Nameserver: ns, NonRA: nonra, Recursive: ra})
|
||
|
}
|
||
|
return valid
|
||
|
}
|
||
|
|
||
|
func NeutralReq() bool {
|
||
|
msg := message("supernets.org", dns.TypeA, true)
|
||
|
in, err := dns.Exchange(msg, "1.1.1.1:53")
|
||
|
if err != nil {
|
||
|
return false
|
||
|
}
|
||
|
if len(in.Answer) > 0 {
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func PullNS(d string) []string {
|
||
|
nsmsg := message(d, dns.TypeNS, true)
|
||
|
in, err := dns.Exchange(nsmsg, "1.1.1.1:53")
|
||
|
if err != nil {
|
||
|
Fatal("unable to retrieve nameservers for " + d)
|
||
|
}
|
||
|
|
||
|
nameservers := []string{}
|
||
|
|
||
|
for _, ans := range in.Answer {
|
||
|
ns, ok := ans.(*dns.NS)
|
||
|
if ok {
|
||
|
nameservers = append(nameservers, ns.Ns)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nameservers
|
||
|
}
|
||
|
|
||
|
func RunQuery(q <-chan Query, tracker chan<- interface{}, delay int) {
|
||
|
for qdata := range q {
|
||
|
if Params.Verbose {
|
||
|
Info(fmt.Sprintf("querying %s on %s", qdata.DomainPair.Domain, qdata.Nameserver[0:len(qdata.Nameserver)-1]))
|
||
|
}
|
||
|
msg := message(qdata.DomainPair.Domain, dns.TypeA, false)
|
||
|
in, err := dns.Exchange(msg, qdata.Nameserver+":53")
|
||
|
if err != nil {
|
||
|
Error(err.Error())
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if len(in.Answer) > 0 {
|
||
|
Success(fmt.Sprintf("[%s] associated domain %s%s%s found on %s%s%s",
|
||
|
qdata.Vendor, ColorRed, qdata.DomainPair.Domain, ColorReset, ColorRed, qdata.Nameserver[0:len(qdata.Nameserver)-1], ColorReset))
|
||
|
}
|
||
|
time.Sleep(time.Duration(delay) * time.Millisecond)
|
||
|
}
|
||
|
tracker <- 1337
|
||
|
}
|
||
|
|
||
|
func RunQueryRA(q <-chan Query, tracker chan<- interface{}, delay int) {
|
||
|
for qdata := range q {
|
||
|
if Params.Verbose {
|
||
|
Info(fmt.Sprintf("recursively querying %s on %s", qdata.DomainPair.Domain, qdata.Nameserver[0:len(qdata.Nameserver)-1]))
|
||
|
}
|
||
|
for x := 0; x < 2; x++ {
|
||
|
msg := message(qdata.DomainPair.Domain, dns.TypeA, true)
|
||
|
in, err := dns.Exchange(msg, qdata.Nameserver+":53")
|
||
|
if err != nil {
|
||
|
Error("hiccup on " + qdata.Nameserver[0:len(qdata.Nameserver)-1] + " while querying " + qdata.DomainPair.Domain)
|
||
|
time.Sleep(2 * time.Second)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if len(in.Answer) > 0 {
|
||
|
if in.Answer[0].Header().Ttl <= qdata.DomainPair.TTL-4 {
|
||
|
Success(fmt.Sprintf("[%s] associated domain %s%s%s found on %s%s%s with decremented TTL of %s%d%s",
|
||
|
qdata.Vendor, ColorRed, qdata.DomainPair.Domain, ColorReset, ColorRed, qdata.Nameserver[0:len(qdata.Nameserver)-1], ColorReset, ColorGreen, in.Answer[0].Header().Ttl, ColorReset))
|
||
|
}
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
time.Sleep(time.Duration(delay) * time.Millisecond)
|
||
|
}
|
||
|
tracker <- 1337
|
||
|
}
|