diff --git a/sublist3r.py b/sublist3r.py index 0f418a1..1c52d8c 100755 --- a/sublist3r.py +++ b/sublist3r.py @@ -72,7 +72,15 @@ def no_color(): def banner(): - return + print("""%s + ____ _ _ _ _ _____ + / ___| _ _| |__ | (_)___| |_|___ / _ __ + \___ \| | | | '_ \| | / __| __| |_ \| '__| + ___) | |_| | |_) | | \__ \ |_ ___) | | + |____/ \__,_|_.__/|_|_|___/\__|____/|_|%s%s + + # Coded By Ahmed Aboul-Ela - @aboul3la + """ % (R, W, Y)) def parser_error(errmsg): @@ -665,55 +673,55 @@ class DNSdumpster(enumratorBaseThreaded): return links -# class Virustotal(enumratorBaseThreaded): -# def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True): -# subdomains = subdomains or [] -# base_url = 'https://www.virustotal.com/ui/domains/{domain}/subdomains' -# self.engine_name = "Virustotal" -# self.q = q -# super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) -# self.url = self.base_url.format(domain=self.domain) -# return -# -# # the main send_req need to be rewritten -# def send_req(self, url): -# try: -# resp = self.session.get(url, headers=self.headers, timeout=self.timeout) -# except Exception as e: -# self.print_(e) -# resp = None -# -# return self.get_response(resp) -# -# # once the send_req is rewritten we don't need to call this function, the stock one should be ok -# def enumerate(self): -# while self.url != '': -# resp = self.send_req(self.url) -# resp = json.loads(resp) -# if 'error' in resp: -# self.print_(R + "[!] Error: Virustotal probably now is blocking our requests" + W) -# break -# if 'links' in resp and 'next' in resp['links']: -# self.url = resp['links']['next'] -# else: -# self.url = '' -# self.extract_domains(resp) -# return self.subdomains -# -# def extract_domains(self, resp): -# #resp is already parsed as json -# try: -# for i in resp['data']: -# if i['type'] == 'domain': -# subdomain = i['id'] -# if not subdomain.endswith(self.domain): -# continue -# if subdomain not in self.subdomains and subdomain != self.domain: -# if self.verbose: -# self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain)) -# self.subdomains.append(subdomain.strip()) -# except Exception: -# pass +class Virustotal(enumratorBaseThreaded): + def __init__(self, domain, subdomains=None, q=None, silent=False, verbose=True): + subdomains = subdomains or [] + base_url = 'https://www.virustotal.com/ui/domains/{domain}/subdomains' + self.engine_name = "Virustotal" + self.q = q + super(Virustotal, self).__init__(base_url, self.engine_name, domain, subdomains, q=q, silent=silent, verbose=verbose) + self.url = self.base_url.format(domain=self.domain) + return + + # the main send_req need to be rewritten + def send_req(self, url): + try: + resp = self.session.get(url, headers=self.headers, timeout=self.timeout) + except Exception as e: + self.print_(e) + resp = None + + return self.get_response(resp) + + # once the send_req is rewritten we don't need to call this function, the stock one should be ok + def enumerate(self): + while self.url != '': + resp = self.send_req(self.url) + resp = json.loads(resp) + if 'error' in resp: + self.print_(R + "[!] Error: Virustotal probably now is blocking our requests" + W) + break + if 'links' in resp and 'next' in resp['links']: + self.url = resp['links']['next'] + else: + self.url = '' + self.extract_domains(resp) + return self.subdomains + + def extract_domains(self, resp): + #resp is already parsed as json + try: + for i in resp['data']: + if i['type'] == 'domain': + subdomain = i['id'] + if not subdomain.endswith(self.domain): + continue + if subdomain not in self.subdomains and subdomain != self.domain: + if self.verbose: + self.print_("%s%s: %s%s" % (R, self.engine_name, W, subdomain)) + self.subdomains.append(subdomain.strip()) + except Exception: + pass class ThreatCrowd(enumratorBaseThreaded): @@ -911,6 +919,7 @@ def main(domain, threads, savefile, ports, silent, verbose, enable_bruteforce, e 'ask': AskEnum, 'netcraft': NetcraftEnum, 'dnsdumpster': DNSdumpster, + 'virustotal': Virustotal, 'threatcrowd': ThreatCrowd, 'ssl': CrtSearch, 'passivedns': PassiveDNS @@ -921,7 +930,7 @@ def main(domain, threads, savefile, ports, silent, verbose, enable_bruteforce, e if engines is None: chosenEnums = [ BaiduEnum, YahooEnum, GoogleEnum, BingEnum, AskEnum, - NetcraftEnum, ThreatCrowd, + NetcraftEnum, DNSdumpster, Virustotal, ThreatCrowd, CrtSearch, PassiveDNS ] else: @@ -988,10 +997,14 @@ def interactive(): engines = args.engines if verbose or verbose is None: verbose = True + silent = args.silent if args.no_color: no_color() - banner() - res = main(domain, threads, savefile, ports, silent= True, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines) + if silent: + verbose = False + else: + banner() + res = main(domain, threads, savefile, ports, silent=silent, verbose=verbose, enable_bruteforce=enable_bruteforce, engines=engines) if __name__ == "__main__": interactive()