Skip to content

Commit

Permalink
Merge pull request #10 from JordanMilne/master
Browse files Browse the repository at this point in the history
Handle wildcard subs with round robin IPs
  • Loading branch information
TheRook committed Dec 13, 2014
2 parents 240551e + 2c55b8c commit caf3cb5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
40 changes: 27 additions & 13 deletions subbrute.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import time
import optparse
import os
import os.path
import signal
import sys
import random
Expand All @@ -25,12 +26,12 @@ def killme(signum = 0, frame = 0):

class lookup(Thread):

def __init__(self, in_q, out_q, domain, wildcard = False, resolver_list = []):
def __init__(self, in_q, out_q, domain, wildcards = False, resolver_list = []):
Thread.__init__(self)
self.in_q = in_q
self.out_q = out_q
self.domain = domain
self.wildcard = wildcard
self.wildcards = wildcards
self.resolver_list = resolver_list
self.resolver = dns.resolver.Resolver()
if len(self.resolver.nameservers):
Expand Down Expand Up @@ -95,7 +96,7 @@ def run(self):
else:
test = "%s.%s" % (sub, self.domain)
addr = self.check(test)
if addr and addr != self.wildcard:
if addr and (not self.wildcards or addr not in self.wildcards):
test = (test, str(addr))
self.out_q.put(test)

Expand Down Expand Up @@ -148,13 +149,23 @@ def check_resolvers(file_name):
pass
return ret

def run_target(target, hosts, resolve_list, thread_count, print_numeric):
def request_random_wildcard(base):
return dns.resolver.Resolver().query("would-never-be-a-fucking-domain-name-" + str(random.randint(1, 99999)) + "." + base)

def run_target(target, hosts, resolve_list, thread_count, print_numeric, wildcard_sniff_limit):
#The target might have a wildcard dns record...
wildcard = False
wildcards = False
try:

resp = dns.resolver.Resolver().query("would-never-be-a-fucking-domain-name-" + str(random.randint(1, 9999)) + "." + target)
wildcard = str(resp[0])
wildcards = bool(request_random_wildcard(target))
if wildcards:
wildcards = set()
sys.stderr.write("wildcard subdomains detected, sniffing for possible round robin IPs:\n")
for i in xrange(wildcard_sniff_limit):
sys.stderr.write(".")
sys.stderr.flush()
time.sleep(0.1)
wildcards.add(str(request_random_wildcard(target)[0]))
sys.stderr.write("\n")
except:
pass
in_q = queue.Queue()
Expand All @@ -169,7 +180,7 @@ def run_target(target, hosts, resolve_list, thread_count, print_numeric):
step_size = 1
step = 0
for i in range(thread_count):
threads.append(lookup(in_q, out_q, target, wildcard , resolve_list[step:step + step_size]))
threads.append(lookup(in_q, out_q, target, wildcards , resolve_list[step:step + step_size]))
threads[-1].start()
step = (step + step_size) % len(resolve_list)
if step >= len(resolve_list):
Expand All @@ -194,20 +205,24 @@ def run_target(target, hosts, resolve_list, thread_count, print_numeric):
break

if __name__ == "__main__":
base_path = os.path.dirname(os.path.realpath(__file__))
parser = optparse.OptionParser("usage: %prog [options] target")
parser.add_option("-c", "--thread_count", dest = "thread_count",
default = 10, type = "int",
help = "(optional) Number of lookup theads to run, more isn't always better. default=10")
parser.add_option("-s", "--subs", dest = "subs", default = "subs.txt",
parser.add_option("-s", "--subs", dest = "subs", default = os.path.join(base_path, "subs.txt"),
type = "string", help = "(optional) list of subdomains, default='subs.txt'")
parser.add_option("-r", "--resolvers", dest = "resolvers", default = "resolvers.txt",
parser.add_option("-r", "--resolvers", dest = "resolvers", default = os.path.join(base_path, "resolvers.txt"),
type = "string", help = "(optional) A list of DNS resolvers, if this list is empty it will OS's internal resolver default='resolvers.txt'")
parser.add_option("-f", "--filter_subs", dest = "filter", default = "",
type = "string", help = "(optional) A file containing unorganized domain names which will be filtered into a list of subdomains sorted by frequency. This was used to build subs.txt.")
parser.add_option("-t", "--target_file", dest = "targets", default = "",
type = "string", help = "(optional) A file containing a newline delimited list of domains to brute force.")
parser.add_option("-n", "--numeric", dest = "numeric", action = "store_true", default = False,
help = "(optional) Additionally prints numeric IP addresses for sub domains (default=off).")
parser.add_option("--wildcard_sniff_limit", dest = "wildcard_sniff_limit", type=int, default = 100,
help = "(optional) How many times to request wildcard domain IPs to add to the ignore list (default=100).")


(options, args) = parser.parse_args()

Expand All @@ -230,8 +245,7 @@ def run_target(target, hosts, resolve_list, thread_count, print_numeric):
resolve_list = check_resolvers(options.resolvers)
threads = []
signal.signal(signal.SIGINT, killme)

for target in targets:
target = target.strip()
if target:
run_target(target, hosts, resolve_list, options.thread_count, options.numeric)
run_target(target, hosts, resolve_list, options.thread_count, options.numeric, options.wildcard_sniff_limit)
5 changes: 5 additions & 0 deletions subs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ my
members
blogs
search
staging
www7a
www7b
regione
Expand Down Expand Up @@ -49,6 +50,10 @@ kk
app
admin
server
varnish
artifactory
mvn
maven
baidu
www4b
forums
Expand Down

0 comments on commit caf3cb5

Please sign in to comment.