65 lines
1.2 KiB
Go
65 lines
1.2 KiB
Go
|
package dns
|
||
|
|
||
|
import (
|
||
|
"math/rand"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/miekg/dns"
|
||
|
)
|
||
|
|
||
|
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
|
||
|
// Generate a random string
|
||
|
// https://stackoverflow.com/a/31832326
|
||
|
func generate(length int) string {
|
||
|
// Create byte array with length
|
||
|
word := make([]byte, length)
|
||
|
|
||
|
// Go through word
|
||
|
for index := range word {
|
||
|
// Set index to random letter
|
||
|
word[index] = letterBytes[rand.Intn(len(letterBytes))]
|
||
|
}
|
||
|
|
||
|
return string(word)
|
||
|
}
|
||
|
|
||
|
// Query wildcard
|
||
|
func Wildcard(client *dns.Client, resolvers []string, domain string) bool {
|
||
|
for {
|
||
|
// Generate subdomain
|
||
|
subdomain := generate(10) + "." + domain
|
||
|
|
||
|
// Create message
|
||
|
message := new(dns.Msg)
|
||
|
|
||
|
// Set question
|
||
|
message.SetQuestion(dns.Fqdn(subdomain), dns.TypeA)
|
||
|
|
||
|
// Choose random resolver
|
||
|
resolver := resolvers[rand.Intn(len(resolvers))]
|
||
|
|
||
|
// Query response
|
||
|
response, _, err := client.Exchange(message, resolver)
|
||
|
if err != nil {
|
||
|
// Ratelimited
|
||
|
if strings.ContainsAny(err.Error(), "i/o timeout") {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// Store status
|
||
|
var status bool
|
||
|
|
||
|
// Go through answers
|
||
|
for _, answer := range response.Answer {
|
||
|
// Map record
|
||
|
_, status = answer.(*dns.A)
|
||
|
}
|
||
|
|
||
|
return status
|
||
|
}
|
||
|
}
|