TheRook / subbrute

A DNS meta-query spider that enumerates DNS records, and subdomains.
GNU General Public License v3.0
3.35k stars 653 forks source link

No resolvers pass the wildcard test with `--type=ALL` #51

Open jeteon opened 7 years ago

jeteon commented 7 years ago

Whilst trying the tool on some domains that use Cloudflare for their authoritative nameserver (along with another factor which seems to vary by domain) I found that using type ANY for the queries would return HINFO(13) with nothing in the answer regardless of whether the subdomain exists or not. Thanks to @decidedlygray, I discovered that this is a change Cloudflare introduced explained here: https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/.

I found that the query type ALL seems to be a suitable alternative to ANY when playing around with dig. However, when I set the --type=ALL option, then all resolvers fail the wildcard test. The issue seems to be that an exception is raised by dnslib here: https://github.com/TheRook/subbrute/blob/c5b96610129bedcb4c322b8864f67985b3e808f8/subbrute.py#L227.

The exception that is raised is (ignore line numbers since my file has many debug output lines added):

Traceback (most recent call last):
  File "./subbrute.py", line 227, in find_wildcards
    blanktest = self.resolver.query(self.target, self.query_type)
  File "./subbrute.py", line 64, in query
    query = dnslib.DNSRecord.question(hostname, query_type.upper().strip())
  File "/home/neo/Projects/Haxr/subbrute-master/dnslib/dns.py", line 137, in question
    return DNSRecord(q=DNSQuestion(qname,getattr(QTYPE,qtype),
  File "/home/neo/Projects/Haxr/subbrute-master/dnslib/bimap.py", line 74, in __getattr__
    raise self.error("%s: Invalid reverse lookup: [%s]" % (self.name,k))
DNSError: QTYPE: Invalid reverse lookup: [ALL]

I have no idea what this actually means as yet but suspect its a shortcoming of the version of dnslib included in the repo. I'm looking further into this so I'll update and maybe PR if I come across a solution.

jeteon commented 7 years ago

Okay...so "ALL" isn't a valid DNS query type. That was silly of me. However, I'm running into a similar issue with --query-type = A as well, only with this traceback:

Traceback (most recent call last):
  File "./subbrute.py", line 251, in find_wildcards
    wildtest = self.resolver.query(testdomain, self.query_type, server)
  File "./subbrute.py", line 92, in query
    raise IOError("DNS Error - " + self.rcode + " - for:" + hostname)
IOError: DNS Error - NOERROR - for:9e28ec5e881344.kraken.com

This seems to stem from the assumption that if the answer body is empty and the reason is not an error, the only valid reason is NXDOMAIN but CloudFlare seems to respond with NOERROR for this case. I'm not sure whether everyone does this but this would suggest line 91 should be:

elif not len(ret) and self.rcode not in ("NXDOMAIN", "NOERROR"):

instead of:

elif not len(ret) and self.rcode != "NXDOMAIN":

Again, I'm not sure how generally suitable this would be though since I've only observed the behaviour with Cloudlflare in some instances.