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")
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")
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
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")
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
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))
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())
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")
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)
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" )
def handle_exception(self, e, message=""): if self.options["--verbose"]: print(e) if message: ColorPrint.red(message)