Fixed different python3 bugs:

- wrong intendation
- mix of "print ..." and "print(...)"
- minor improvents (https, headers as static var)
This commit is contained in:
Damian Schwyrz 2018-06-30 17:29:53 +02:00
parent f41265fb54
commit 322b613e60
1 changed files with 194 additions and 198 deletions

View File

@ -26,7 +26,7 @@ import socket
from collections import Counter
# external modules
#from subbrute import subbrute
# from subbrute import subbrute
import dns.resolver
import requests
# import dnslib, which provides better features compared to dns.resolver for finding subdomains
@ -46,6 +46,7 @@ else:
# there's also an option to disable the SSL warning:
try:
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
except:
pass
@ -55,7 +56,6 @@ is_windows = sys.platform.startswith('win')
global debug
# Console Colors
if is_windows:
# Windows deserve coloring too :D
@ -65,10 +65,11 @@ if is_windows:
R = '\033[91m' # red
W = '\033[0m' # white
try:
import win_unicode_console , colorama
import win_unicode_console, colorama
win_unicode_console.enable()
colorama.init()
#Now the unicode will work ^_^
# Now the unicode will work ^_^
except:
print("[!] Error: Coloring libraries not installed ,no coloring will be used [Check the readme]")
G = Y = B = R = W = G = Y = B = R = W = ''
@ -94,6 +95,7 @@ def banner():
# Forked by Carl Pearson - github.com/fleetcaptain
""" % (R, W, Y))
def parser_error(errmsg):
banner()
print("Usage: python " + sys.argv[0] + " [Options] use -h for help")
@ -109,8 +111,10 @@ def parse_args():
parser.add_argument('-d', '--domain', help="Domain name to enumerate it's subdomains", required=True)
parser.add_argument('-b', '--bruteforce', help='Enable the subbrute bruteforce module', nargs='?', default=False)
parser.add_argument('-p', '--ports', help='Scan the found subdomains against specified tcp ports')
parser.add_argument('-v', '--verbose', help='Enable Verbosity and display results in realtime', nargs='?', default=False)
parser.add_argument('-t', '--threads', help='Number of threads to use for subbrute bruteforce', type=int, default=30)
parser.add_argument('-v', '--verbose', help='Enable Verbosity and display results in realtime', nargs='?',
default=False)
parser.add_argument('-t', '--threads', help='Number of threads to use for subbrute bruteforce', type=int,
default=30)
parser.add_argument('-e', '--engines', help='Specify a comma-separated list of search engines')
parser.add_argument('-o', '--output', help='Save just domain names to specified text file')
parser.add_argument('-a', '--analysis', help='Do analysis of the results and save to specified text file')
@ -163,6 +167,12 @@ class enumratorBase(object):
self.engine_name = engine_name
self.silent = silent
self.verbose = verbose
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.8',
'Accept-Encoding': 'gzip',
}
self.print_banner()
def print_(self, text):
@ -176,17 +186,10 @@ class enumratorBase(object):
return
def send_req(self, query, page_no=1):
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
}
url = self.base_url.format(query=query, page_no=page_no)
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout)
resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
except Exception:
resp = None
return self.get_response(resp)
@ -270,7 +273,8 @@ class enumratorBase(object):
class enumratorBaseThreaded(multiprocessing.Process, enumratorBase):
def __init__(self, base_url, engine_name, domain, subdomains=None, q=None, lock=threading.Lock(), silent=False, verbose=True):
def __init__(self, base_url, engine_name, domain, subdomains=None, q=None, lock=threading.Lock(), silent=False,
verbose=True):
subdomains = subdomains or []
enumratorBase.__init__(self, base_url, engine_name, domain, subdomains, silent=silent, verbose=verbose)
multiprocessing.Process.__init__(self)
@ -291,7 +295,8 @@ class GoogleEnum(enumratorBaseThreaded):
self.engine_name = "Google"
self.MAX_DOMAINS = 11
self.MAX_PAGES = 200
super(GoogleEnum, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(GoogleEnum, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
self.q = q
return
@ -313,7 +318,7 @@ class GoogleEnum(enumratorBaseThreaded):
return links_list
def check_response_errors(self, resp):
if 'Our systems have detected unusual traffic' in resp:
if (type(resp) is str or type(resp) is unicode) and 'Our systems have detected unusual traffic' in resp:
self.print_(R + "[!] Error: Google probably now is blocking our requests" + W)
self.print_(R + "[~] Finished now the Google Enumeration ..." + W)
return False
@ -340,7 +345,8 @@ class YahooEnum(enumratorBaseThreaded):
self.engine_name = "Yahoo"
self.MAX_DOMAINS = 10
self.MAX_PAGES = 0
super(YahooEnum, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(YahooEnum, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
self.q = q
return
@ -391,12 +397,13 @@ class AskEnum(enumratorBaseThreaded):
self.engine_name = "Ask"
self.MAX_DOMAINS = 11
self.MAX_PAGES = 0
enumratorBaseThreaded.__init__(self, base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
enumratorBaseThreaded.__init__(self, base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
self.q = q
return
def extract_domains(self, resp):
link_regx = re.compile('<p class="web-result-url">(.*?)</p>')
link_regx = re.compile('<td>(.*?)</td>', re.IGNORECASE)
try:
links_list = link_regx.findall(resp)
for link in links_list:
@ -477,7 +484,8 @@ class BaiduEnum(enumratorBaseThreaded):
self.engine_name = "Baidu"
self.MAX_DOMAINS = 2
self.MAX_PAGES = 760
enumratorBaseThreaded.__init__(self, base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
enumratorBaseThreaded.__init__(self, base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
self.querydomain = self.domain
self.q = q
return
@ -535,21 +543,16 @@ class NetcraftEnum(enumratorBaseThreaded):
self.base_url = 'https://searchdns.netcraft.com/?restriction=site+ends+with&host={domain}'
self.engine_name = "Netcraft"
self.lock = threading.Lock()
super(NetcraftEnum, self).__init__(self.base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(NetcraftEnum, self).__init__(self.base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
self.q = q
return
def req(self, url, cookies=None):
cookies = cookies or {}
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout, cookies=cookies)
resp = self.session.get(url, headers=self.headers, timeout=self.timeout, cookies=cookies)
except Exception as e:
self.print_(e)
resp = None
@ -559,7 +562,7 @@ class NetcraftEnum(enumratorBaseThreaded):
link_regx = re.compile('<A href="(.*?)"><b>Next page</b></a>')
link = link_regx.findall(resp)
link = re.sub('host=.*?%s' % self.domain, 'host=%s' % self.domain, link[0])
url = 'http://searchdns.netcraft.com' + link
url = 'https://searchdns.netcraft.com' + link
return url
def create_cookies(self, cookie):
@ -615,7 +618,8 @@ class DNSdumpster(enumratorBaseThreaded):
self.threads = 70
self.lock = threading.BoundedSemaphore(value=self.threads)
self.q = q
super(DNSdumpster, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(DNSdumpster, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
return
def check_host(self, host):
@ -637,14 +641,8 @@ class DNSdumpster(enumratorBaseThreaded):
def req(self, req_method, url, params=None):
params = params or {}
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Referer': 'https://dnsdumpster.com'
}
headers = dict(self.headers)
headers['Referer'] = 'https://dnsdumpster.com'
try:
if req_method == 'GET':
resp = self.session.get(url, headers=headers, timeout=self.timeout)
@ -698,20 +696,15 @@ class Virustotal(enumratorBaseThreaded):
self.engine_name = "Virustotal"
self.lock = threading.Lock()
self.q = q
super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
return
# the main send_req need to be rewritten
def send_req(self, url):
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout)
resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
except Exception as e:
self.print_(e)
resp = None
@ -748,19 +741,14 @@ class ThreatCrowd(enumratorBaseThreaded):
self.engine_name = "ThreatCrowd"
self.lock = threading.Lock()
self.q = q
super(ThreatCrowd, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(ThreatCrowd, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
return
def req(self, url):
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout)
resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
except Exception:
resp = None
@ -800,19 +788,14 @@ class CrtSearch(enumratorBaseThreaded):
self.engine_name = "SSL Certificates"
self.lock = threading.Lock()
self.q = q
super(CrtSearch, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(CrtSearch, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
return
def req(self, url):
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/40.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout)
resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
except Exception:
resp = None
@ -835,7 +818,7 @@ class CrtSearch(enumratorBaseThreaded):
continue
if '@' in subdomain:
subdomain = subdomain[subdomain.find('@')+1:]
subdomain = subdomain[subdomain.find('@') + 1:]
if subdomain not in self.subdomains and subdomain != self.domain:
if self.verbose:
@ -852,19 +835,32 @@ class PassiveDNS(enumratorBaseThreaded):
self.engine_name = "PassiveDNS"
self.lock = threading.Lock()
self.q = q
super(PassiveDNS, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose)
super(PassiveDNS, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent,
verbose=verbose)
return
def get_agent(self, ua=None):
agents_url = 'http://www.webuseragents.com/recent'
try:
resp = session.get(agents_url, headers=self.headers, timeout=self.timeout)
agents_list = self.get_response(resp)
agents_regex = re.compile('<a href="/ua/.*?>(.*)</a>')
agents = agents_regex.findall(agents_list)
ua = random.choice(agents)
except Exception as e:
pass
return ua
def req(self, url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-GB,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
}
try:
resp = self.session.get(url, headers=headers, timeout=self.timeout)
if self.get_agent():
self.headers['User-Agent'] = self.get_agent()
resp = self.session.get(url, headers=self.headers, timeout=self.timeout)
except Exception as e:
self.print_(e)
resp = None
@ -1002,7 +998,8 @@ def main(domain, threads, savefile, ports, silent, verbose, enable_bruteforce, e
process_count = threads
output = False
json_output = False
bruteforce_list = subbrute.print_target(parsed_domain.netloc, record_type, subs, resolvers, process_count, output, json_output, search_list, verbose)
bruteforce_list = subbrute.print_target(parsed_domain.netloc, record_type, subs, resolvers, process_count,
output, json_output, search_list, verbose)
subdomains = search_list.union(bruteforce_list)
@ -1033,9 +1030,12 @@ def main(domain, threads, savefile, ports, silent, verbose, enable_bruteforce, e
# Method code added
cnames = ['== CNAME records ==']
ahosts = ['== A records ==']
def lookup(guess, name_server):
if (debug):
print 'Trying ' + guess + ' at ' + name_server
print('Trying ' + guess + ' at ' + name_server)
use_tcp = False
response = None
failed = False
@ -1043,39 +1043,39 @@ def lookup(guess, name_server):
record_value = ""
query = dnslib.DNSRecord.question(guess)
try:
response_q = query.send(name_server, 53, use_tcp, timeout = 3)
response_q = query.send(name_server, 53, use_tcp, timeout=3)
if response_q:
if (debug):
print "response_q: " + response_q
print("response_q: " + response_q)
response = dnslib.DNSRecord.parse(response_q)
except KeyboardInterrupt:
print 'User exit'
print('User exit')
exit()
except:
# probably socket timed out
print "ERROR - possible socket timeout when trying " + guess
print("ERROR - possible socket timeout when trying " + guess)
pass
if response:
if debug:
print "Decoded response:\n" + str(response) + "\n"
print("Decoded response:\n" + str(response) + "\n")
rcode = dnslib.RCODE[response.header.rcode]
if rcode == 'NOERROR' or rcode == 'NXDOMAIN':
# success, this is a valid subdomain
if debug:
print "response.rr:\n" + str(response.rr) + "\n"
print("response.rr:\n" + str(response.rr) + "\n")
for r in response.rr:
# note that we are looping through each piece of the answer but we only return from this method once... we must pick what we return verrry carefully, see explantion below
if debug:
print "r:\n" + str(r) + "\n"
print("r:\n" + str(r) + "\n")
rtype = None
try:
rtype = str(dnslib.QTYPE[r.rtype])
except:
rtype = str(r.rtype)
#print rtype
# print rtype
if (rtype == 'CNAME'):
#print r.rdata
# print r.rdata
record_type = 'CNAME'
record_value = str(r.rdata)
'''
@ -1105,13 +1105,10 @@ def lookup(guess, name_server):
record_type = 'A'
record_value = str(r.rdata)
else:
print "ERROR - returned stats " + rcode + " when trying " + guess
print("ERROR - returned stats " + rcode + " when trying " + guess)
return record_type, record_value
#####################
# Program entry point
#####################
@ -1128,12 +1125,12 @@ if __name__ == "__main__":
analysis = args.analysis
debug = args.debug
if (debug):
print "Debugging output enabled for analysis module"
print("Debugging output enabled for analysis module")
if verbose or verbose is None:
verbose = True
banner()
res = main(domain, threads, savefile, ports, silent=False, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines)
res = main(domain, threads, savefile, ports, silent=False, verbose=verbose, enable_bruteforce=enable_bruteforce,
engines=engines)
# Code added here
if (analysis):
@ -1142,7 +1139,7 @@ if __name__ == "__main__":
server = 0
count = 0
total = str(len(res))
print ""
print("")
print(B + "[-] Beginning analysis of " + total + " subdomains..." + W)
for subdomain in res:
try:
@ -1161,7 +1158,7 @@ if __name__ == "__main__":
# update user on our progress - every 30 hosts
count = count + 1
if (count % 30) == 0:
print str(count) + '/' + total
print(str(count) + '/' + total)
except KeyboardInterrupt:
print(R + '\n[-] User exit' + W)
exit()
@ -1176,11 +1173,10 @@ if __name__ == "__main__":
# output analysis results to console
for x in range(0, len(ahosts)):
print(G + ahosts[x] + W)
print "\n"
print("\n")
for x in range(0, len(cnames)):
print(G + cnames[x] + W)
#print ""
# print ""
# save the analysis to a file. Merge the arrays into one list for easier reading
write_file(analysis, ahosts + ["\n"] + cnames)