def searchURL(self): self.url = "http://www.virustotal.com/vtapi/v2/url/report" parameters = {"resource": self.ioc, "apikey": self.key} while True: req = post(self.url, headers=self.config["user_agent"], proxies=self.config["proxy_host"], timeout=self.config["requests_timeout"], data=parameters) try: json_content = json.loads(req.text) break except: mod.display( self.module_name, self.ioc, "WARNING", "Virustotal json decode fail. Blacklisted/Bad API key? (Sleep 10sec)." ) sleep(randint(5, 10)) pass try: if json_content["positives"]: mod.display( self.module_name, self.ioc, "FOUND", "Score: %s/%s | %s" % (json_content["positives"], json_content["total"], json_content["permalink"])) except: pass
def vxstream_api(self): """ VXstream API Connection """ if self.type in ["MD5", "SHA1", "SHA256"]: server = "https://www.hybrid-analysis.com/api/scan/" if self.type in ["IPv4", "IPv6"]: server = "https://www.hybrid-analysis.com/api/search?query=host:" if self.type in ["domain"]: server = "https://www.hybrid-analysis.com/api/search?query=domain:" respond = requests.get(server + self.ioc, headers={'User-agent': 'VxApi Connector'}, verify=True, auth=HTTPBasicAuth( self.config["vxstream_api_keys"], self.config["vxstream_secret"])) if respond.status_code == 200: respond_json = respond.json() if respond_json["response_code"] == 0: return respond_json else: if respond_json["response_code"] == -1 and ( "error" in respond_json["response"]): mod.display(self.module_name, message_type="ERROR", string="%s" % respond_json["response"]["error"]) return None else: mod.display(self.module_name, message_type="ERROR", string="VXstream API connection status %d" % respond.status_code) return None
def checkType(self, argument): """ Identify observable type """ if len(argument.strip()) == 0: return None elif argument[0] is '#': return None elif validators.url(argument): return "URL" elif validators.md5(argument): return "MD5" elif validators.sha1(argument): return "SHA1" elif validators.sha256(argument): return "SHA256" elif validators.sha512(argument): return "SHA512" elif validators.ipv4(argument): return "IPv4" elif validators.ipv6(argument): return "IPv6" elif validators.domain(argument): return "domain" else: mod.display("MAIN", argument, "ERROR", "Unable to retrieve observable type") return None
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] if "malekal_local" in self.config and "malekal_remote" in self.config: if self.config[ "malekal_local"] and not self.config["malekal_remote"]: self.types = ["MD5"] else: self.types = [ "MD5", "SHA1", "SHA256", "SHA512", "URL", "IPv4", "IPv6", "domain" ] else: mod.display( self.module_name, message_type="ERROR", string=("Check if you have malekal_local and malekal_remote" "fields in config.ini ")) self.search_method = "Online" self.description = "Search IOC in malekal database" self.author = "Conix" self.creation_date = "13-09-2016" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.search() else: mod.display(self.module_name, "", "INFO", "Malekal module not activated")
def searchURL(self): self.url = "http://www.virustotal.com/vtapi/v2/url/report" parameters = {"resource": self.ioc, "apikey": self.key} data = urllib.urlencode(parameters) req = urllib2.Request(self.url, data) while True: try: response = urllib2.urlopen(req).read() json_content = loads(response) break except: mod.display( self.module_name, self.ioc, "INFO", "Virustotal json decode fail. Blacklisted/Bad API key? (Sleep 10sec)." ) sleep(randint(5, 10)) pass try: if json_content["positives"]: mod.display( self.module_name, self.ioc, "FOUND", "Score: %s/%s | %s" % (json_content["positives"], json_content["total"], json_content["permalink"])) except: pass
def loginRequest(self, s): if ("misp_crawler_url" in self.config and "user_agent" in self.config and "misp_crawler_verifycert" in self.config): response = s.get("%s/users/login" % self.config["misp_crawler_url"], headers=self.config["user_agent"], verify=self.config["misp_crawler_verifycert"]) token_key, token_fields = self.getTokens(response.text) data = { '_method': 'POST', 'data[_Token][key]': token_key, 'data[User][email]': self.config["misp_crawler_login"], 'data[User][password]': self.config["misp_crawler_password"], 'data[_Token][fields]': token_fields, 'data[_Token][unlocked]': '' } response = s.post("%s/users/login" % self.config["misp_crawler_url"], data=data, headers=self.config["user_agent"], verify=self.config["misp_crawler_verifycert"]) else: mod.display( self.module_name, message_type="ERROR", string=( "Please check if you have misp_crawler_url, user_agent and" "misp_crawler_verifycert fields in config.ini"))
def Search(self): mod.display(self.module_name, "", "INFO", "Search in VXstream ...") try: if "vxstream_api_keys" and "vxstream_secret" in self.config: if self.type in self.types: result_json = self.vxstream_api() else: mod.display( self.module_name, message_type=":", string= "Please check if you have vxstream field in config.ini") except Exception as e: mod.display(self.module_name, self.ioc, "ERROR", e) return try: if result_json["response"]: if self.type in ["MD5", "SHA1", "SHA256"]: result = result_json["response"][0] if "classification_tags" in result and result[ "classification_tags"]: tags = ",".join(result["classification_tags"]) else: tags = "Na" if "verdict" in result: verdict = result["verdict"] else: verdict = "Na" if "threatscore" in result: threatscore = "Threatscore: %d/100" % result[ "threatscore"] else: threatscore = "Threatscore: Na" if "sha256" in result: url = 'https://www.hybrid-analysis.com/sample/%s' % result[ "sha256"] else: url = "" mod.display( self.module_name, self.ioc, "FOUND", "Tags: %s | %s | %s | %s" % (tags, verdict, threatscore, url)) if self.type in ["domain", "IPv4", "IPv6"]: result = result_json["response"]["result"] nb_result = len(result) if nb_result > 0: if self.type in ["IPv4", "IPv6"]: url = "https://www.hybrid-analysis.com/advanced-search-results?terms[host_with_port]=%s" % self.ioc if self.type in ["domain"]: url = "https://www.hybrid-analysis.com/advanced-search-results?terms[domain]=%s" % self.ioc mod.display(self.module_name, self.ioc, "FOUND", "Results: %d | %s" % (nb_result, url)) except: pass
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") if "malekal_local" in self.config: if self.config["malekal_local"]: self.localSearch() if "malekal_remote" in self.config: if self.config["malekal_remote"] and mod.allowedToSearch( self.search_method): self.remoteSearch()
def cleanups_lock_cache(real_path): for file in listdir(real_path): file_path = "%s%s/"%(real_path, file) if file.endswith(".lock"): mod.display("MAIN", message_type="DEBUG", string="Delete locked cache file: %s"%file_path[:-1]) remove(file_path[:-1]) else: if path.isdir(file_path): cleanups_lock_cache(file_path)
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") request = get("https://iris-h.services/api/search?hash=%s" % self.ioc, headers=self.config["user_agent"], proxies=self.config["proxy_host"], timeout=self.config["requests_timeout"]) json_content = json.loads(request.text) if not "No report exists for %s hash" % self.ioc in json_content: mod.display(self.module_name, self.ioc, "FOUND", "URL: https://iris-h.services/report/%s" % (self.ioc))
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://mirror1.malwaredomains.com/files/" paths = ["immortal_domains.txt"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if line == self.ioc: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path))
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "https://www.malwaredomainlist.com/hostslist/" paths = ["hosts.txt"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if "127.0.0.1" in line: if self.ioc == line.split(" ")[1].strip(): mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path))
def module_worker(self, module, argument, type): """ Load modules in python instance """ mod.display(string="Load: %s/%s.py"%(config["modules_folder"], module)) obj = importlib.import_module("modules."+module) for c in dir(obj): if module+"_enabled" in config: if module == c.lower() and config[module+"_enabled"]: getattr(obj, c)(argument, type, config) else: mod.display(module, "", "INFO", "Module not configured")
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://vxvault.net/" paths = ["URL_List.php"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if self.ioc in line: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path)) return
def search(self): try: mod.display(self.module_name, "", "INFO", "Searching...") data_page = self.serach_ioc() extract_info = self.extract_information(data_page) if self.check_ioc(data_page, extract_info): mod.display( self.module_name, self.ioc, "FOUND", "Score: %d | %s" % (len(extract_info['DETECTIONS'].split("\n")) - 1, "https://virusshare.com/")) except: pass
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://cybercrime-tracker.net/" paths = ["all.php"] if self.type == "URL": self.ioc = self.ioc.split("//")[1] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if self.ioc in line: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path))
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://torstatus.blutmagie.de/" paths = [ "ip_list_all.php/Tor_ip_list_ALL.csv", "query_export.php/Tor_query_EXPORT.csv", "ip_list_exit.php/Tor_ip_list_EXIT.csv" ] for path in paths: if self.ioc in Cache(self.module_name, url, path, self.search_method).content: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path))
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "https://sslbl.abuse.ch/blacklist/" paths = ["sslblacklist.csv"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if self.ioc in line: infos = line.split(',') mod.display(self.module_name, self.ioc, "FOUND", "%s | %s%s" % (infos[2], url, path)) return
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://www.nothink.org/blacklist/" paths = [ "blacklist_snmp_year.txt", "blacklist_ssh_year.txt", "blacklist_telnet_year.txt" ] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): if self.ioc in line: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path))
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] self.types = ["MD5", "SHA256", "SHA1"] self.search_method = "Online" self.description = "Search IOC in Malshare database" self.author = "Conix" self.creation_date = "12-04-2017" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.search() else: mod.display(self.module_name, "", "INFO", "Malshare module not activated")
def search(self): mod.display(self.module_name, "", "INFO", "Search in VirusTotal ...") if "proxy_host" in self.config: if len(self.config["proxy_host"]["https"]) > 0: proxy = urllib2.ProxyHandler( {'https': self.config["proxy_host"]["https"]}) opener = urllib2.build_opener(proxy) else: opener = urllib2.build_opener() else: mod.display( self.module_name, message_type="ERROR", string="Please check if you have proxy_host field in config.ini" ) urllib2.install_opener(opener) try: if "virustotal_api_keys" in self.config: self.key = choice(self.config["virustotal_api_keys"]) else: mod.display( self.module_name, message_type="ERROR", string= "Check if you have virustotal_api_keys field in config.ini" ) except: mod.display(self.module_name, self.ioc, "ERROR", "Please provide your authkey.") return if self.type in ["URL", "domain", "IPv4"]: self.searchURL() else: self.searchReport()
def remoteSearch(self): """ Search IOC with HTTP request """ mod.display("%s_remote" % self.module_name, self.ioc, "INFO", string="Browsing in remote http") url = "http://malwaredb.malekal.com/index.php?" if self.type in ["MD5", "SHA1", "SHA256", "SHA512"]: base = "hash=" elif self.type in ["URL", "domain"]: base = "url=" elif self.type in ["IPv4", "IPv6"]: base = "domaine=" try: if ("user_agent" in self.config and "proxy_host" in self.config and "requests_timeout" in self.config): page = get("%s%s%s" % (url, base, self.ioc), headers=self.config["user_agent"], proxies=self.config["proxy_host"], timeout=self.config["requests_timeout"]).text if len(findall("hash=([a-z0-9]{32})\"", page)) > 1: mod.display("%s_remote" % self.module_name, self.ioc, "FOUND", "%s%s%s" % (url, base, self.ioc)) else: mod.display( self.module_name, message_type="ERROR", string=("Check if you have user_agent, proxy_host and" "requests_timeout fields in config.ini ")) except: mod.display("%s_remote" % self.module_name, self.ioc, "INFO", "MalekalTimeout")
def run(self, argument, modules): """ Main observable module requests """ type = self.checkType(argument) mod.display(ioc=argument, string="Observable type: %s"%type) if type is None: sys.exit() workers = [] for module in modules: worker = multiprocessing.Process(target=self.module_worker, args=(module, argument, type,)) workers.append(worker) worker.start()
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "https://openphish.com/" paths = ["feed.txt"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): try: midle = line.split("//")[-1].split("/")[0] except: midle = None if self.type == "URL": if self.ioc in line: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path)) return elif self.type == "IPv4" and validators.ipv4(midle): if self.ioc == midle: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path)) return elif self.type == "domain" and validators.domain(midle): if midle == self.ioc: mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path)) return
def Search(self): mod.display(self.module_name, "", "INFO", "Search in misp crawler...") with requests.Session() as s: try: self.loginRequest(s) allEvents = self.searchAttribute(s) for event in allEvents: if "misp_crawler_url" in self.config: mod.display( self.module_name, self.ioc, "FOUND", "Event: %s/events/view/%s" % (self.config["misp_crawler_url"], event)) else: mod.display( self.module_name, message_type="ERROR", string= "Check if you have misp_crawler_url in config.ini") except: mod.display( self.module_name, message_type="ERROR", string= "Could not perform the request, checkout config.ini at [%s]" % (self.module_name))
def search(self): mod.display(self.module_name, "", "INFO", "Searching...") url = "http://hosts-file.malwareteks.com/" paths = ["hosts.txt"] for path in paths: content = Cache(self.module_name, url, path, self.search_method).content for line in content.split("\n"): try: if self.ioc == line.split("127.0.0.1")[1].strip(): mod.display(self.module_name, self.ioc, "FOUND", "%s%s" % (url, path)) except: pass
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] self.types = ["domain"] self.search_method = "Online" self.description = "Search domain in Lehigh feeds" self.author = "Conix" self.creation_date = "15-09-2016" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.search() else: mod.display(self.module_name, "", "INFO", "Lehigh module not activated")
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] self.types = ["MD5", "SHA1", "domain", "IPv4", "IPv6", "URL", "SHA256"] self.search_method = "Online" self.description = "Search IOC in Alienvault database" self.author = "Hicham Megherbi" self.creation_date = "13-04-2016" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.Search() else: mod.display(self.module_name, "", "INFO", "Alienvault OTX module not activated")
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] self.types = ["MD5", "SHA1", "SHA256", "URL", "IPv4", "domain"] self.search_method = "Online" self.description = "Search IOC in VirusTotal database" self.author = "Conix" self.creation_date = "13-09-2016" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.search() else: mod.display(self.module_name, "", "INFO", "VirusTotal module not activated")
def __init__(self, ioc, type, config): self.config = config self.module_name = __name__.split(".")[1] self.types = ["IPv4", "IPv6"] self.search_method = "Online" self.description = "Search IP in SpamHaus feeds" self.author = "Robin Marsollier" self.creation_date = "20-03-2017" self.type = type self.ioc = ioc if type in self.types and mod.allowedToSearch(self.search_method): self.search() else: mod.display(self.module_name, "", "INFO", "Spamhaus module not activated")