示例#1
0
    def dns_zonetransfer(self):
        print("Testing for zone transfers")
        zonetransfers = []
        resolver = dns.resolver.Resolver()
        try:
            answers = resolver.query(self.options["TARGET"], 'NS')
        except Exception as e:
            self.handle_exception(e, "Error checking for Zone Transfers")
            return

        resolved_ips = []
        for ns in answers:
            ns = str(ns).rstrip('.')
            resolved_ips.append(socket.gethostbyname(ns))

        for ip in resolved_ips:
            try:
                zone = dns.zone.from_xfr(
                    dns.query.xfr(ip, self.options["TARGET"]))
                for name, node in zone.nodes.items():
                    name = str(name)
                    if name not in ["@", "*"]:
                        zonetransfers.append(name + '.' +
                                             self.options["TARGET"])
            except:
                pass

        if zonetransfers:
            print("\tZone transfers possible:")
            for zone in zonetransfers:
                ColorPrint.red(zone)
        else:
            print("\tNo zone transfers possible")
示例#2
0
    def init(self):
        if self.options["FILE"]:
            full_path = os.path.join(os.getcwd(), self.options["FILE"])
            with open(full_path) as file:
                self.options["TARGET"] = list(
                    filter(None,
                           file.read().split('\n')))
        else:
            self.options["TARGET"] = list(
                filter(None, self.options["TARGET"].split(",")))
        # Clean up targets
        for i in range(len(self.options["TARGET"])):
            url = self.options["TARGET"][i]
            # Inject protocol if not there
            if not re.match(r'http(s?):', url):
                url = 'http://' + url

            parsed = urlsplit(url)
            host = parsed.netloc

            self.options["TARGET"][i] = host

            try:
                domain_str = socket.gethostbyname(host)
                ColorPrint.green(
                    f"Searching for subdomains for {domain_str} ({host})")
            except Exception as e:
                self.handle_exception(
                    e,
                    "Error connecting to target! Make sure you spelled it correctly and it is a resolvable address"
                )
                raise e
示例#3
0
def search_virustotal(self, target):
    print("Searching VirusTotal")
    headers = {
        'dnt': '1',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-US,en;q=0.9,it;q=0.8',
        'user-agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
        'accept':
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'authority': 'www.virustotal.com',
        'cookie': 'VT_PREFERRED_LANGUAGE=en',
    }
    res = requests.get('https://www.virustotal.com/en/domain/' + target +
                       '/information/',
                       headers=headers)
    if res.status_code == 403:
        ColorPrint.red(
            "VirusTotal is currently ratelimiting this IP - go to https://www.virustotal.com/en/domain/"
            + target + "/information/ and complete the captcha to continue.")
        return
    scraped = res.text
    try:
        trim_to_subdomain = scraped[scraped.find("observed-subdomains"):scraped
                                    .rfind("<script>")].split('\n')
        for domain in trim_to_subdomain:
            if domain.strip().endswith("." + target):
                if domain.strip() not in self.domains and domain.endswith(
                        target):
                    self.domains.append(domain.strip())
                    if self.options["--verbose"]:
                        print("VirustTotal Found Domain:", domain.strip())
    except Exception as e:
        self.handle_exception(e, "Error parsing virustotal")
        pass
示例#4
0
    def search_shodan(self):
        print("Scanning Shodan.io")
        try:
            from anubis.API import SHODAN_KEY
        except ImportError:
            ColorPrint.red(
                "Unable to import API keys - make sure API.py exists!")
            return

        if not SHODAN_KEY:
            print(
                "To run with additional information, you must set http://shodan.io's API key. You can either set it manually here, or set it within anubis/API.py\nKey: ",
                end='')
            key = input()
            api = shodan.Shodan(key)
        else:
            api = shodan.Shodan(SHODAN_KEY)

        if self.ip != "":
            try:
                results = api.host(self.ip)
                if self.options["--verbose"]:
                    print(dumps(results, indent=2, sort_keys=True))

                print('Server Location:',
                      results['city'] + ", " + results['country_code'], '-',
                      results['postal_code'])
                print("ISP: %s" % results['isp'])
                if results['os'] is not None:
                    print("Possible OS: %s" % results['os'])
            except Exception as e:
                self.handle_exception(e, "Error retrieving additional info")
示例#5
0
def search_shodan(self):
    print("Searching Shodan.io for additional information")
    try:
        from anubis.API import SHODAN_KEY
    except ImportError:
        ColorPrint.red("Unable to import API keys - make sure API.py exists!")
        return

    api = shodan.Shodan(SHODAN_KEY)
    for i in range(len(self.options["TARGET"])):
        try:
            results = api.host(socket.gethostbyname(self.options["TARGET"][i]))

            if self.options["--verbose"]:
                print(dumps(results, indent=2, sort_keys=True))

            print('Server Location: ' + str(results['city']) + ", " +
                  str(results['country_code']) + ' - ' +
                  str(results['postal_code']))

            print("ISP  or Hosting Company: %s" % str(results['isp']))

            if results['os'] is not None:
                print("Possible OS: %s" % str(results['os']))
        except Exception as e:
            self.handle_exception(e, "Error retrieving additional info")
示例#6
0
def search_virustotal(self, target):
    print("Searching VirusTotal")
    headers = {
        'dnt': '1',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-US,en;q=0.9,it;q=0.8',
        'user-agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
        'accept':
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'authority': 'www.virustotal.com',
        'cookie': 'VT_PREFERRED_LANGUAGE=en',
    }
    res = requests.get('https://www.virustotal.com/ui/domains/' + target +
                       '/subdomains?relationships=resolutions',
                       headers=headers)
    # VirusTotal rate limits aggressively to prevent botting - the user must
    # manually visit a URL and complete a captcha to continue
    if res.status_code == 403:
        ColorPrint.red(
            "VirusTotal is currently ratelimiting this IP - go to https://www.virustotal.com/en/domain/"
            + target + "/information/ and complete the captcha to continue.")
        return

    try:
        data = res.json()
        for entry in data['data']:
            domain = entry['id']
            if domain.strip() not in self.domains and domain.endswith(target):
                self.domains.append(domain.strip())
                if self.options["--verbose"]:
                    print("VirustTotal Found Domain:", domain.strip())
    except Exception as e:
        self.handle_exception(e, "Error parsing virustotal")
        pass
示例#7
0
    def init(self):
        self.options["TARGET"] = self.options["TARGET"].split(",")
        for i in range(len(self.options["TARGET"])):
            url = self.options["TARGET"][i]

            if not re.match(r'http(s?):', url):
                url = 'http://' + url

            parsed = urlsplit(url)
            host = parsed.netloc

            if host.startswith('www.'):
                host = host[4:]

            self.options["TARGET"][i] = host

            try:
                ColorPrint.green(
                    "Searching for subdomains for " +
                    socket.gethostbyname(self.options["TARGET"][i]) + " (" +
                    self.options["TARGET"][i] + ")")
            except Exception as e:
                self.handle_exception(
                    e,
                    "Error connecting to target! Make sure you spelled it correctly and it is a resolvable address"
                )
                raise e
        print("")
示例#8
0
def send_to_anubisdb(self, target):
    print("Sending to AnubisDB")
    data = {'subdomains': dumps(self.domains)}
    res = requests.post("https://jonlu.ca/anubis/subdomains/" + target,
                        data=data)
    if res.status_code != 200:
        ColorPrint.red("Error sending results to AnubisDB - Status Code: " +
                       str(res.status_code))
示例#9
0
 def test_color_print(self):
     ColorPrint.red("red")
     self.assertIn("91m", sys.stdout.getvalue())
     ColorPrint.green("green")
     self.assertIn("92m", sys.stdout.getvalue())
     ColorPrint.light_purple("light_purple")
     self.assertIn("94m", sys.stdout.getvalue())
     ColorPrint.purple("purple")
     self.assertIn("95m", sys.stdout.getvalue())
     ColorPrint.yellow("yellow")
     self.assertIn("93m", sys.stdout.getvalue())
示例#10
0
def send_to_anubisdb(self, target):
  if len(target) == 1:
    print("Sending to AnubisDB")
    data = {'subdomains': dumps(self.domains)}
    # Sends found subdomains to Anubis (max 10,000/post)
    res = requests.post("https://jonlu.ca/anubis/subdomains/" + target[0],
                        data=data)
    if res.status_code != 200:
      ColorPrint.red("Error sending results to AnubisDB - Status Code: " + str(
        res.status_code))
  else:
    print("Cannot send multiple domains to AnubisDB")
示例#11
0
 def resolve_ips(self):
     unique_ips = set()
     for domain in self.dedupe:
         try:
             resolved_ip = socket.gethostbyname(domain)
             # TODO - Align domains and ips in stdout
             ColorPrint.green(domain + ": " + resolved_ip)
             unique_ips.add(resolved_ip)
         except Exception as e:
             self.handle_exception(e)
     print("Found %s unique IPs" % len(unique_ips))
     for ip in unique_ips:
         ColorPrint.green(ip)
示例#12
0
def search_censys(self, target):
  print("Searching Censys")
  try:
    from anubis.API import CENSYS_ID, CENSYS_SECRET
  except ImportError:
    ColorPrint.red(
      "To run a Censys scan, you must add your API keys to anubis/API.py")
    return
  if not CENSYS_SECRET or not CENSYS_ID:
    ColorPrint.red(
      "To run a Censys scan, you must add your API keys to anubis/API.py")
    return
  c = censys.certificates.CensysCertificates(CENSYS_ID, CENSYS_SECRET)
  for cert in c.search("." + target):
    print(cert)
示例#13
0
文件: dnssec.py 项目: shc5/Anubis
def dnssecc_subdomain_enum(self, target):
    if os.getuid() == 0:
        print("Starting DNSSEC Enum")
        nm = nmap.PortScanner()
        arguments = '-sSU -p 53 --script dns-nsec-enum --script-args dns-nsec-enum.domains=' + target

        nm.scan(hosts=self.ip, arguments=arguments)
        for host in nm.all_hosts():
            try:
                print(nm[host]['udp'][53]['script']['dns-nsec-enum'])
            except:
                pass
    else:
        ColorPrint.red(
            "To run a DNSSEC subdomain enumeration, Anubis must be run as root"
        )
示例#14
0
 def resolve_ips(self):
     unique_ips = set()
     for domain in self.dedupe:
         try:
             # Attempt to get IP
             resolved_ip = socket.gethostbyname(domain)
         except Exception as e:
             self.handle_exception(e)
             # If getting IP fails, fallback to empty string
             resolved_ip = ""
         # TODO - Align domains and ips in stdout
         ColorPrint.green(domain + ": " + resolved_ip)
         unique_ips.add(resolved_ip)
     print("Found %s unique IPs" % len(unique_ips))
     for ip in unique_ips:
         # String truthiness ignores empty strings
         if ip:
             ColorPrint.green(ip)
示例#15
0
    def resolve_ips(self):
        unique_ips = set()
        for domain in self.dedupe:
            try:
                # Attempt to get IP
                resolved_ip = socket.gethostbyname(domain)
            except Exception as e:
                self.handle_exception(e)
                # If getting IP fails, fallback to empty string
                resolved_ip = ""
            # TODO - Align domains and ips in stdout
            ColorPrint.green(domain + ": " + resolved_ip)
            if self.options['--silent']:
                sys.stdout.write(domain + '\n', override=True)

            if resolved_ip:
                unique_ips.add(resolved_ip)
        print("Found %s unique IPs" % len(unique_ips))
        for ip in unique_ips:
            # Ignore empty strings, final sanity check
            if ip:
                ColorPrint.green(ip)
示例#16
0
    def run(self):
        # Retrieve IP of target and run initial configurations
        self.init()
        # If multiple targets, create scans for each
        for i in range(len(self.options["TARGET"])):
            # Default scans that run every time
            target = self.options["TARGET"][i]
            ColorPrint.green(f"Working on target: {target}")
            threads = [
                threading.Thread(target=dns_zonetransfer, args=(self, target)),
                threading.Thread(target=subdomain_hackertarget,
                                 args=(self, target)),
                threading.Thread(target=search_subject_alt_name,
                                 args=(self, target)),
                threading.Thread(target=search_netcraft, args=(self, target)),
                threading.Thread(target=search_crtsh, args=(self, target)),
                threading.Thread(target=search_dnsdumpster,
                                 args=(self, target)),
                threading.Thread(target=search_anubisdb, args=(self, target))
            ]

            # Additional options - shodan.io scan
            if self.options["--additional-info"]:
                threads.append(
                    threading.Thread(target=search_shodan, args=(self, )))

            # Additional options - nmap scan of dnssec script and a host/port scan
            if self.options["--with-nmap"]:
                threads.append(
                    threading.Thread(target=dnssecc_subdomain_enum,
                                     args=(self, target)))
                threads.append(
                    threading.Thread(target=scan_host, args=(self, )))

            # Start all threads and wait for them to finish
            for x in threads:
                x.start()

            for x in threads:
                x.join()

            # Run a recursive search on each subdomain - rarely useful, but nice to have
            # just in case
            if self.options["--recursive"]:
                recursive_search(self)

            # remove duplicates and clean up
            self.domains = self.clean_domains(self.domains)
            self.dedupe = set(self.domains)

            print("Found", len(self.dedupe), "subdomains")
            print("----------------")

            if self.options["--ip"]:
                self.resolve_ips()
            else:
                for domain in self.dedupe:
                    cleaned_domain = domain.strip()
                    ColorPrint.green(cleaned_domain)
                    if self.options['--silent']:
                        sys.stdout.write(cleaned_domain, override=True)

            if self.options["--send-to-anubis-db"]:
                send_to_anubisdb(self, [target])
            # reset per domain
            self.domains = list()
示例#17
0
    def run(self):
        # Retrieve IP of target and run initial configurations
        self.init()
        ColorPrint.green("Searching for subdomains for " + self.ip + " (" +
                         self.options["TARGET"] + ")\n")

        # Multithreaded scans
        threads = [
            Thread(target=self.scan_subject_alt_name()),
            Thread(target=self.dns_zonetransfer()),
            Thread(target=self.subdomain_hackertarget()),
            Thread(target=self.search_virustotal()),
            Thread(target=self.search_pkey()),
            Thread(target=self.search_netcraft()),
            Thread(target=self.search_dnsdumpster())
        ]

        # Default scans that run every time

        # If they want to send and receive results from Anubis DB
        if not self.options["--no-anubis-db"]:
            threads.append(Thread(target=self.scan_anubisdb()))

        # Additional options - ssl cert scan
        if self.options["--ssl"]:
            threads.append(Thread(target=self.ssl_scan()))

        # Additional options - shodan.io scan
        if self.options["--additional-info"]:
            threads.append(Thread(target=self.search_shodan()))

        # Additional options - nmap scan of dnssec script and a host/port scan
        if self.options["--with-nmap"]:
            threads.append(Thread(target=self.dnssecc_subdomain_enum()))
            threads.append(Thread(target=self.scan_host()))

        # Additional options - brute force common subdomains
        if self.options["--brute-force"]:
            threads.append(Thread(target=self.brute_force()))

        # Not sure what data we can get from censys yet, but might be useful in the future
        # self.search_censys()

        # Start all threads
        for x in threads:
            x.start()

        # Wait for all of them to finish
        for x in threads:
            x.join()

        # remove duplicates and clean up

        self.domains = self.clean_domains()
        self.dedupe = set(self.domains)

        print("Found", len(self.dedupe), "domains")
        print("----------------")
        if self.options["--ip"]:
            self.resolve_ips()
        else:
            for domain in self.dedupe:
                ColorPrint.green(domain.strip())

        if not self.options["--no-anubis-db"]:
            self.send_to_anubisdb()
示例#18
0
 def handle_exception(self, e, message=""):
     if self.options["--verbose"]:
         print(e)
     if message:
         ColorPrint.red(message)
示例#19
0
    def run(self):
        # Retrieve IP of target and run initial configurations
        self.init()
        # If multiple targets, create scans for each
        for i in range(len(self.options["TARGET"])):
            # Default scans that run every time
            target = self.options["TARGET"][i]
            threads = [
                threading.Thread(target=dns_zonetransfer, args=(self, target)),
                threading.Thread(target=subdomain_hackertarget,
                                 args=(self, target)),
                threading.Thread(target=search_subject_alt_name,
                                 args=(self, target)),
                threading.Thread(target=search_virustotal,
                                 args=(self, target)),
                # threading.Thread(target=search_pkey, args=(self, target)),
                # Removed pkey as of June 18 2018 due to issues on their end (not connecting)
                threading.Thread(target=search_netcraft, args=(self, target)),
                threading.Thread(target=search_crtsh, args=(self, target)),
                threading.Thread(target=search_dnsdumpster,
                                 args=(self, target)),
                threading.Thread(target=search_anubisdb, args=(self, target))
            ]

            # Additional options - shodan.io scan
            if self.options["--additional-info"]:
                threads.append(
                    threading.Thread(target=search_shodan, args=(self, )))

            # Additional options - ssl
            if self.options["--ssl"]:
                threads.append(
                    threading.Thread(target=ssl_scan, args=(self, target)))

            # Additional options - nmap scan of dnssec script and a host/port scan
            if self.options["--with-nmap"]:
                threads.append(
                    threading.Thread(target=dnssecc_subdomain_enum,
                                     args=(self, target)))
                threads.append(
                    threading.Thread(target=scan_host, args=(self, )))

        # Start all threads and wait for them to finish
        for x in threads:
            x.start()

        for x in threads:
            x.join()

        # Run a recursive search on each subdomain - rarely useful, but nice to have
        # just in case
        if self.options["--recursive"]:
            recursive_search(self)

        # remove duplicates and clean up
        self.domains = self.clean_domains(self.domains)
        self.dedupe = set(self.domains)

        print("Found", len(self.dedupe), "subdomains")
        print("----------------")

        if self.options["--ip"]:
            self.resolve_ips()
        else:
            for domain in self.dedupe:
                ColorPrint.green(domain.strip())

        if self.options["--send-to-anubis-db"]:
            send_to_anubisdb(self, self.options["TARGET"])
示例#20
0
    def run(self):
        # Retrieve IP of target and run initial configurations
        self.init()
        for i in range(len(self.options["TARGET"])):
            # Default scans that run every time
            target = self.options["TARGET"][i]
            threads = [
                threading.Thread(target=dns_zonetransfer, args=(self, target)),
                threading.Thread(target=search_subject_alt_name,
                                 args=(self, target)),
                threading.Thread(target=subdomain_hackertarget,
                                 args=(self, target)),
                threading.Thread(target=search_virustotal,
                                 args=(self, target)),
                threading.Thread(target=search_pkey, args=(self, target)),
                threading.Thread(target=search_netcraft, args=(self, target)),
                threading.Thread(target=search_crtsh, args=(self, target)),
                threading.Thread(target=search_dnsdumpster,
                                 args=(self, target)),
                threading.Thread(target=search_anubisdb, args=(self, target))
            ]
            print('test')
            # Additional options - ssl cert scan
            if self.options["--ssl"]:
                threads.append(
                    threading.Thread(target=ssl_scan, args=(self, target)))

            # Additional options - shodan.io scan
            if self.options["--additional-info"]:
                threads.append(
                    threading.Thread(target=search_shodan, args=(self, )))

            # Additional options - nmap scan of dnssec script and a host/port scan
            if self.options["--with-nmap"]:
                threads.append(
                    threading.Thread(target=dnssecc_subdomain_enum,
                                     args=(self, target)))
                threads.append(
                    threading.Thread(target=scan_host, args=(self, )))

            # Additional options - brute force common subdomains
            if self.options["--brute-force"]:
                threads.append(
                    threading.Thread(target=brute_force, args=(self, target)))

            # Start all threads
        for x in threads:
            x.start()

        # Wait for all of them to finish
        for x in threads:
            x.join()

        # remove duplicates and clean up

        if self.options["--recursive"]:
            recursive_search(self)

        self.domains = self.clean_domains(self.domains)
        self.dedupe = set(self.domains)

        print("Found", len(self.dedupe), "subdomains")
        print("----------------")

        if self.options["--ip"]:
            self.resolve_ips()
        else:
            for domain in self.dedupe:
                ColorPrint.green(domain.strip())

        if self.options["--send-to-anubis-db"]:
            send_to_anubisdb(self, self.options["TARGET"])
示例#21
0
    def run(self):
        # Retrieve IP of target and run initial configurations
        self.init()

        ColorPrint.green("Searching for subdomains for " + self.ip + " (" +
                         self.options["TARGET"] + ")\n")

        # Default scans that run every time
        threads = [
            Thread(target=dns_zonetransfer(self, self.options["TARGET"])),
            Thread(
                target=search_subject_alt_name(self, self.options["TARGET"])),
            Thread(
                target=subdomain_hackertarget(self, self.options["TARGET"])),
            Thread(target=search_virustotal(self, self.options["TARGET"])),
            Thread(target=search_pkey(self, self.options["TARGET"])),
            Thread(target=search_netcraft(self, self.options["TARGET"])),
            Thread(target=search_crtsh(self, self.options["TARGET"])),
            Thread(target=search_dnsdumpster(self, self.options["TARGET"])),
            Thread(target=search_anubisdb(self, self.options["TARGET"]))
        ]
        # Additional options - ssl cert scan
        if self.options["--ssl"]:
            threads.append(
                Thread(target=ssl_scan(self, self.options["TARGET"])))

        # Additional options - shodan.io scan
        if self.options["--additional-info"]:
            threads.append(Thread(target=search_shodan(self)))

        # Additional options - nmap scan of dnssec script and a host/port scan
        if self.options["--with-nmap"]:
            threads.append(
                Thread(target=dnssecc_subdomain_enum(self,
                                                     self.options["TARGET"])))
            threads.append(Thread(target=scan_host(self)))

        # Additional options - brute force common subdomains
        if self.options["--brute-force"]:
            threads.append(
                Thread(target=brute_force(self, self.options["TARGET"])))

        # Start all threads
        for x in threads:
            x.start()

        # Wait for all of them to finish
        for x in threads:
            x.join()

        # remove duplicates and clean up

        if self.options["--recursive"]:
            self.recursive_search()

        self.domains = self.clean_domains(self.domains)
        self.dedupe = set(self.domains)

        print("Found", len(self.dedupe), "subdomains")
        print("----------------")

        if self.options["--ip"]:
            self.resolve_ips()
        else:
            for domain in self.dedupe:
                ColorPrint.green(domain.strip())

        if not self.options["--no-anubis-db"]:
            send_to_anubisdb(self, self.options["TARGET"])