def test_typeguess(self): self.assertEqual(typeguess("44c13fc77ee90ef4040a0c99a9be999e"), "md5") self.assertEqual(typeguess("d82b0fffdda6d7120dd8c14da32208278e2a287f"), "sha1") self.assertEqual( typeguess( "fef75dbbf6297c151a7112cb5f98884e4928716f0725826c42086e6c21a9894d" ), "sha256") self.assertEqual(typeguess("10.4.4.4"), "IPv4") self.assertEqual(typeguess("fce8::1"), "IPv6") self.assertEqual(typeguess("domain.com"), "domain")
def run(self, conf, args, plugins): tg = ThreatGrid(conf['ThreatGrid']['key']) if 'subcommand' in args: if args.subcommand == "search": try: res = tg.search_samples(unbracket(args.QUERY), type=args.TYPE) except ThreatGridError: print("Invalid type") if args.json: print(json.dumps(res, sort_keys=True, indent=4)) else: if len(res['items']) == 0: print('Not found') else: already = [] for item in res['items']: if item['sample_sha256'] not in already: print("%s - %s - %s" % ( item['ts'], item['sample_sha256'], "https://panacea.threatgrid.com/mask/samples/" + item['sample'])) already.append(item['sample_sha256']) elif args.subcommand == 'hash': hash_type = {32: 'md5', 40: 'sha1', 64: 'sha256'} res = tg.get_sample(args.HASH, type=hash_type[len(args.HASH)]) if len(res['items']) > 0: item = res['items'][0] print( "Sample submitted the %s: https://panacea.threatgrid.com/mask/samples/%s" % (item['submitted_at'], item['id'])) idd = item['id'] res = tg.get_sample_threats(idd) print('\nThreats:') for t in res['bis']: print("-%s" % t) else: print('Hash not found') elif args.subcommand == 'networklist': with open(args.FILE, 'r') as f: data = f.read().split('\n') for d in data: target = unbracket(d.strip()) gtype = typeguess(target) print(target) res = tg.search_samples(target, type=gtype) if len(res['items']) > 0: already = [] for item in res['items']: if item['sample_sha256'] not in already: print( "-%s: https://panacea.threatgrid.com/mask/samples/%s %s" % (item['ts'][:10], item['sample'], item['sample_sha256'])) already.append(item['sample_sha256']) else: print('-Nothing found') print('') else: self.parser.print_help() else: self.parser.print_help()
def run(self, conf, args, plugins): otx = OTXv2(conf["AlienVaultOtx"]["key"]) if args.pulse: try: indicators = otx.get_pulse_indicators(args.pulse) except Exception: print("Pulse not found") else: if args.json: print(json.dumps(indicators, sort_keys=True, indent=4)) elif args.raw: for i in indicators: print(i["indicator"]) else: for i in indicators: if len(i["type"]) < 5: t = "\t\t\t" else: t = "\t\t" print("[+] %s %s%s%s" % ( i["created"], i["type"], t, i["indicator"] ) ) elif args.search: if args.type == "guess": t = typeguess(args.search) else: t = args.type res = otx.get_indicator_details_full( OTX_TYPES[t], args.search ) if args.json: print(json.dumps(res, sort_keys=True, indent=4)) else: if 'analysis' in res: if res['analysis']['analysis']: analysis = res["analysis"]["analysis"] print("File analysed the %s" % analysis["datetime_int"]) if "info" in analysis: print("Infos:") for r in analysis["info"]["results"]: print("\t%s : %s" % (r, analysis["info"]["results"][r])) if "exiftool" in analysis["plugins"]: print("Exiftool:") for r in analysis["plugins"]["exiftool"]["results"]: print("\t%s : %s" % (r, analysis["plugins"]["exiftool"]["results"][r])) if "yarad" in analysis["plugins"]: print("Yara detection:") for r in analysis["plugins"]["yarad"]["results"]['detection']: print("\t%s : %s" % (r["category"], r["rule_name"])) print("") else: print("No analysis on this file") else: print("No analysis on this file") if len(res["general"]["pulse_info"]["pulses"]) > 0: print("Listed in %s pulses" % len(res["general"]["pulse_info"]["pulses"])) for p in res["general"]["pulse_info"]["pulses"]: print("\t-%s" % p["name"]) print("\t\t%s" % p["description"].replace("\n", " ")) print("\t\tCreated: %s" % p["created"]) print("\t\tReferences: %s" % ", ".join(p["references"])) print("\t\tid: %s" % p["id"]) else: print("Not listed in any pulse") if 'passive_dns' in res: if len(res['passive_dns']['passive_dns']) > 0: print("Passive DNS:") for p in res['passive_dns']['passive_dns']: print("\t%s%s on IP %s [%s -> %s]" % ( p["hostname"], p["indicator_link"], p["address"], p["first"], p["last"] ) ) print("") if 'url_list' in res: if len(res['url_list']['url_list']) > 0: print("URL list:") for u in res['url_list']['url_list']: if "result" in u: if "urlworker" in u["result"]: print("\t[%s] %s on IP %s" % ( u["date"], u["url"], u["result"]["urlworker"]["ip"] ) ) else: print("\t[%s] %s" % (u["date"], u["url"])) else: print("\t[%s] %s" % (u["date"], u["url"])) print("") elif args.file: with open(args.file, "r") as f: data = f.read().split("\n") for d in data: if d.strip() != "": if args.type == "guess": t = typeguess(d.strip()) else: t = args.type print("========== %s" % d.strip()) res = otx.get_indicator_details_full( OTX_TYPES[t], d.strip() ) if len(res["general"]["pulse_info"]["pulses"]) > 0: print("Listed in %s pulses" % len(res["general"]["pulse_info"]["pulses"])) for p in res["general"]["pulse_info"]["pulses"]: print("\t-%s" % p["name"]) print("\t\t%s" % p["description"].replace("\n", " ")) print("\t\tCreated: %s" % p["created"]) print("\t\tReferences: %s" % ", ".join(p["references"])) print("\t\tid: %s" % p["id"]) else: print("Not listed in any pulse") else: self.parser.print_help()
def intel(self, type, query, data, conf): if type == "domain": print("[+] Checking OTX...") try: otx = OTXv2(conf["AlienVaultOtx"]["key"]) res = otx.get_indicator_details_full(IndicatorTypes.DOMAIN, query) for pulse in res["general"]["pulse_info"]["pulses"]: data["reports"].append({ "date": parse(pulse["created"]).astimezone(pytz.utc), "title": pulse["name"], "source": "OTX", "url": "https://otx.alienvault.com/pulse/{}".format( pulse["id"]) }) # Get Passive DNS if "passive_dns" in res: for r in res["passive_dns"]["passive_dns"]: data["passive_dns"].append({ "ip": r["hostname"], "first": parse(r["first"]).astimezone(pytz.utc), "last": parse(r["last"]).astimezone(pytz.utc), "source": "OTX", }) if "url_list" in res: for r in res["url_list"]["url_list"]: if "result" in r: data["urls"].append({ "date": parse(r["date"]).astimezone(pytz.utc), "url": r["url"], "ip": r["result"]["urlworker"]["ip"] if "ip" in r["result"]["urlworker"] else "", "source": "OTX", }) else: data["urls"].append({ "date": parse(r["date"]).astimezone(pytz.utc), "url": r["url"], "ip": "", "source": "OTX", }) # Some pulses have domains as hostnames res = otx.get_indicator_details_full(IndicatorTypes.HOSTNAME, query) for pulse in res["general"]["pulse_info"]["pulses"]: data["reports"].append({ "date": parse(pulse["created"]).astimezone(pytz.utc), "title": pulse["name"], "source": "OTX", "url": "https://otx.alienvault.com/pulse/{}".format( pulse["id"]) }) except AttributeError: print("OTX crashed ¯\_(ツ)_/¯") elif type == "ip": print("[+] Checking OTX...") try: otx = OTXv2(conf["AlienVaultOtx"]["key"]) res = otx.get_indicator_details_full(IndicatorTypes.IPv4, query) for pulse in res["general"]["pulse_info"]["pulses"]: data["reports"].append({ "date": parse(pulse["created"]).astimezone(pytz.utc), "title": pulse["name"], "source": "OTX", "url": "https://otx.alienvault.com/pulse/{}".format( pulse["id"]) }) # Get Passive DNS if "passive_dns" in res: for r in res["passive_dns"]["passive_dns"]: data["passive_dns"].append({ "domain": r["hostname"], "first": parse(r["first"]).astimezone(pytz.utc), "last": parse(r["last"]).astimezone(pytz.utc), "source": "OTX", }) if "url_list" in res: for r in res["url_list"]["url_list"]: if "result" in r: data["urls"].append({ "date": parse(r["date"]).astimezone(pytz.utc), "url": r["url"], "ip": r["result"]["urlworker"]["ip"] if "ip" in r["result"]["urlworker"] else "", "source": "OTX", }) else: data["urls"].append({ "date": parse(r["date"]).astimezone(pytz.utc), "url": r["url"], "ip": "", "source": "OTX", }) except AttributeError: print("OTX crashed ¯\_(ツ)_/¯") elif type == "hash": t = typeguess(query) print("[+] Checking OTX...") try: otx = OTXv2(conf["AlienVaultOtx"]["key"]) res = otx.get_indicator_details_full(OTX_TYPES[t], query) for pulse in res["general"]["pulse_info"]["pulses"]: data["reports"].append({ "date": parse(pulse["created"]).astimezone(pytz.utc), "title": pulse["name"], "source": "OTX", "url": "https://otx.alienvault.com/pulse/{}".format( pulse["id"]) }) if "analysis" in res: if "analysis" in res["analysis"]: if "plugins" in res["analysis"]["analysis"]: if "cuckoo" in res["analysis"]["analysis"][ "plugins"]: done = [] for d in res["analysis"]["analysis"][ "plugins"]["cuckoo"]["result"][ "network"]["domains"]: data["network"].append({ "source": "OTX", "url": "https://otx.alienvault.com/indicator/file/{}" .format(query), "host": d["domain"], "host2": d["ip"] }) done.append(d["ip"]) done.append(d["domain"]) for ip in res["analysis"]["analysis"][ "plugins"]["cuckoo"]["result"][ "network"]["hosts"]: if ip["ip"] not in done: data["network"].append({ "source": "OTX", "url": "https://otx.alienvault.com/indicator/file/{}" .format(query), "host": ip["ip"], }) except AttributeError: print("OTX crashed ¯\_(ツ)_/¯")