class Module(ToolTemplate): name = "Sublist3r" binary_name = 'sublist3r' def __init__(self, db): self.db = db self.BaseDomain = BaseDomainRepository(db, self.name) self.Domain = DomainRepository(db, self.name) def set_options(self): super(Module, self).set_options() self.options.add_argument('-d', '--domain', help="Domain to brute force") self.options.add_argument('-f', '--file', help="Import domains from file") self.options.add_argument('-i', '--import_database', help="Import domains from database", action="store_true") self.options.add_argument( '-s', '--rescan', help="Rescan domains that have already been scanned", action="store_true") def get_targets(self, args): targets = [] if args.domain: created, domain = self.BaseDomain.find_or_create( domain=args.domain) targets.append(domain.domain) elif args.file: domains = open(args.file).read().split('\n') for d in domains: if d: created, domain = self.BaseDomain.find_or_create( domain=args.domain) targets.append(domain.domain) elif args.import_database: if args.rescan: domains = self.BaseDomain.all(scope_type="passive") else: domains = self.BaseDomain.all(tool=self.name, scope_type="passive") for d in domains: targets.append(d.domain) res = [] if args.output_path[0] == "/": output_path = os.path.join( self.base_config['PROJECT']['base_path'], args.output_path[1:]) else: output_path = os.path.join( self.base_config['PROJECT']['base_path'], args.output_path) if not os.path.exists(output_path): os.makedirs(output_path) for t in targets: output = os.path.join(output_path, "%s-sublist3r.txt" % t) res.append({'target': t, 'output': output}) return res def build_cmd(self, args): cmd = self.binary + " -o {output} -d {target} " if args.tool_args: cmd += args.tool_args return cmd def process_output(self, cmds): for cmd in cmds: output_path = cmd['output'] data = open(output_path).read().split('\n') for d in data: new_domain = d.split(':')[0].lower() if new_domain: created, subdomain = self.Domain.find_or_create( domain=new_domain) self.Domain.commit()
class Report(ReportTemplate): ''' This report displays data related to discovered user accounts. ''' name = "UserReport" def __init__(self, db): self.BaseDomain = BaseDomainRepository(db) self.User = UserRepository(db) self.Cred = CredRepository(db) def set_options(self): super(Report, self).set_options() self.options.add_argument('-u1', '--usernames_passwords', help="Prints out username/password pairs", action="store_true") self.options.add_argument('-u2', '--emails_passwords', help="Prints out email/password pairs", action="store_true") self.options.add_argument('-u3', '--emails', help="Prints out e-mail addresses", action="store_true") self.options.add_argument('-u4', '--accounts', help="Prints out user accounts", action="store_true") self.options.add_argument('-u5', '--full', help="Prints out full user data", action="store_true") def run(self, args): results = [] domains = self.BaseDomain.all() for d in domains: for user in d.users: if args.emails: results.append(user.email) elif args.accounts: results.append(user.email.split('@')[0]) elif args.full: results.append('{}|{}|{}|{}'.format( user.first_name, user.last_name, user.email, user.job_title)) else: for cred in user.creds: if cred.password and cred.password != "None": if args.emails_passwords: txt = "%s:%s" % (user.email, cred.password) elif args.usernames_passwords: txt = "%s:%s" % (user.email.split('@')[0], cred.password) if txt not in results: results.append(txt) self.process_output(results, args)
class Module(ToolTemplate): name = "Aquatone Takeover" binary_name = "aquatone-takeover" def __init__(self, db): self.db = db self.Domain = DomainRepository(db, self.name) self.BaseDomain = BaseDomainRepository(db, self.name) def set_options(self): super(Module, self).set_options() self.options.add_argument('-i', '--import_database', help="Import domains from database", action="store_true") self.options.add_argument( '-r', '--rescan', help="Run aquatone on hosts that have already been processed.", action="store_true") self.options.set_defaults(timeout=None) def get_targets(self, args): ''' This module is used to build out a target list and output file list, depending on the arguments. Should return a list in the format [(target, output), (target, output), etc, etc] ''' targets = [] if args.import_database: if args.rescan: all_domains = self.BaseDomain.all(scope_type="passive") else: all_domains = self.BaseDomain.all(tool=self.name, scope_type="passive") for d in all_domains: # We need to find all of the http/https ports and create the json file. output_path = os.path.join( self.base_config['PROJECT']['base_path'], 'aquatone', d.domain) if not os.path.exists(output_path): os.makedirs(output_path) hosts_j = {} hosts = [] open_ports = [] urls = [] targets.append(d.domain) for s in d.subdomains: name = s.domain for ip in s.ip_addresses: hosts_j[name] = ip.ip_address port_list = [] for p in ip.ports: if 'http' in p.service_name: hosts.append("{}.{}".format( name, ip.ip_address)) port_list.append(p.port_number) urls.append('{}://{}:{}/'.format( p.service_name, name, p.port_number)) urls.append('{}://{}:{}/'.format( p.service_name, ip.ip_address, p.port_number)) if port_list: open_ports.append('{},{}'.format( ip.ip_address, ','.join([str(o) for o in port_list]))) open(os.path.join(output_path, 'hosts.txt'), 'w').write('\n'.join(list(set(hosts)))) open(os.path.join(output_path, 'urls.txt'), 'w').write('\n'.join(list(set(urls)))) open(os.path.join(output_path, 'open_ports.txt'), 'w').write('\n'.join(list(set(open_ports)))) open(os.path.join(output_path, 'hosts.json'), 'w').write(json.dumps(hosts_j)) else: display_error("You need to supply domain(s).") res = [] for t in targets: res.append({'target': t}) return res def build_cmd(self, args): ''' Create the actual command that will be executed. Use {target} and {output} as placeholders. ''' cmd = self.binary + " -d {target} " if args.tool_args: cmd += args.tool_args return cmd def pre_run(self, args): output_path = self.base_config['PROJECT']['base_path'] self.orig_home = os.environ['HOME'] os.environ['HOME'] = output_path def process_output(self, cmds): ''' Process the output generated by the earlier commands. ''' def post_run(self, args): display("Potential takeovers are stored in {}".format( os.environ['HOME'])) os.environ['HOME'] = self.orig_home
class Module(ToolTemplate): name = "Subfinder" binary_name = "subfinder" def __init__(self, db): self.db = db self.BaseDomains = BaseDomainRepository(db, self.name) self.Domains = DomainRepository(db, self.name) self.IPs = IPRepository(db, self.name) def set_options(self): super(Module, self).set_options() self.options.add_argument( "-a", "--bruteforce-all", help="Brute-force subdomains." ) self.options.add_argument( "-d", "--domain", help="Domain to run subfinder against." ) self.options.add_argument( "-dL", "--domain-list", help="Read in a list of domains within the given file.", ) self.options.add_argument( "-i", "--db_domains", help="Import the domains from the database.", action="store_true", ) self.options.add_argument( "-r", "--resolvers", help="A list of resolvers(comma-separated) or a file containing a list of resolvers.", ) self.options.add_argument( "--rescan", help="Overwrite files without asking", action="store_true" ) self.options.add_argument( "-w", "--wordlist", help="The wordlist for when bruteforcing is selected." ) def get_targets(self, args): targets = [] outpath = "" if args.output_path: if not os.path.exists(args.output_path): os.makedirs(args.output_path) outpath = args.output_path if args.domain or args.db_domains: self.db_domain_file = self.__get_tempfile(args.domain, args) out_file = "database_domains.subfinder" if args.domain: created, domain = self.BaseDomains.find_or_create(domain=args.domain) out_file = os.path.join(outpath, "{}.subfinder".format(args.domain)) if not self.db_domain_file: return targets targets.append({"target": self.db_domain_file, "output": out_file}) elif args.domain_list: domains = io.open(args.domain_list, encoding="utf-8").read().split("\n") for d in domains: if d: created, domain = self.BaseDomains.find_or_create(domain=d) targets.append( { "target": args.domain_list, "output": os.path.join( outpath, "{}.subfinder".format(args.domain_list) ), } ) return targets def build_cmd(self, args): if args.binary: cmd = "{} ".format(args.binary) else: cmd = "{} ".format(self.binary_name) cmd = "{} -o {} -dL {}".format(cmd, "{output}", "{target}") return cmd def process_output(self, targets): for target in targets: with io.open(target["output"], encoding="utf-8") as fd: for line in fd: domain = line.strip() ips = get_domain_ip.run(domain) ip_obj = None _, dom = self.Domains.find_or_create(domain=domain) if ips: for ip in ips: _, ip_obj = self.IPs.find_or_create(ip_address=ip) if ip_obj: dom.ip_addresses.append(ip_obj) dom.save() self.BaseDomains.commit() self.IPs.commit() def post_run(self, args): # Remove the temporary db file if it was created. if getattr(self, "db_domain_file", None): try: os.unlink(self.db_domain_file) except IOError as e: print("Failed to remove the Subfinder db temp file: '{}'.".format(e)) def __get_tempfile(self, domain=None, args=None): # Create a temporary file and place all of the current database domains within the file. from tempfile import NamedTemporaryFile with NamedTemporaryFile(delete=False) as fd: if domain: fd.write("{}\n".format(domain).encode("utf-8")) else: # Go through the database and grab the domains adding them to the file. if args.rescan: domains = self.BaseDomains.all(passive_scope=True) else: domains = self.BaseDomains.all(tool=self.name, passive_scope=True) if domains: for domain in domains: fd.write("{}\n".format(domain.domain).encode("utf-8")) else: return None return fd.name