async def run(indicators: dict) -> None: """Accept a dict containing events indicators and write out to the OUTPUT_DIR specified by chirp.common. :param indicators: A dict containing parsed registry indicator files. :type indicators: dict """ if not indicators: return logging.debug("(REGISTRY) Entered registry plugin.") report = {indicator["name"]: build_report(indicator) for indicator in indicators} for indicator in indicators: ind = indicator["indicator"] indicator_list = [(k, v) for k, v in ind.items() if k != "registry_key"] logging.log(REGISTRY, "Reading {}".format(ind["registry_key"])) async for value in enumerate_registry_values(ind["registry_key"]): if value == "ERROR": logging.log(REGISTRY, "Hit an error, exiting.") return hits, search_criteria, match = await check_matches(indicator_list, value) if hits != len(indicator_list): continue report[indicator["name"]]["_search_criteria"] = search_criteria if match: report[indicator["name"]]["matches"].append(match) [await _report_hits(k, v) for k, v in report.items()] with open(os.path.join(OUTPUT_DIR, "registry.json"), "w+") as writeout: writeout.write( json.dumps({r: report[r] for r in report if report[r]["matches"]}) )
async def run(indicators: dict) -> None: """Accept a dict containing events indicators and writes out to the OUTPUT_DIR specified by chirp.common. :param indicators: A dict containing parsed network indicator files. :type indicators: dict """ if not indicators: return hits = 0 CONSOLE("[cyan][NETWORK][/cyan] Entered network plugin.") saved_ns = parse_netstat(grab_netstat()) saved_dns = parse_dns(grab_dns()) report = { indicator["name"]: build_report(indicator) for indicator in indicators } for indicator in indicators: try: for ioc in indicator["indicator"]["ips"].splitlines(): if await hunter(saved_ns + ["\n"] + saved_dns, ioc): report[indicator["name"]]["matches"].append(ioc) hits += 1 except KeyError: ERROR("{} appears to be malformed.".format(indicator)) CONSOLE( "[cyan][NETWORK][/cyan] Read {} records, found {} IoC hits.".format( len(saved_dns) + len(saved_ns), hits)) with open(os.path.join(OUTPUT_DIR, "network.json"), "w+") as writeout: writeout.write( json.dumps({r: report[r] for r in report if report[r]["matches"]}))
async def run(indicators: dict) -> None: """Accept a dict containing yara indicators and write out to the OUTPUT_DIR specified by chirp.common. :param indicators: A NamespaceDict containing parsed yara indicator files. :type indicators: dict """ if not indicators: return CONSOLE("[cyan][YARA][/cyan] Entered yara plugin.") files = [i["indicator"]["files"] for i in indicators] files = "\\**" if "\\**" in files else ", ".join(files) if files == "\\**": blame = [ i["name"] for i in indicators if i["indicator"]["files"] == "\\**" ] CONSOLE( "[cyan][YARA][/cyan] Enumerating the entire filesystem due to {}... this is going to take a while." .format(blame)) report = { indicator["name"]: build_report(indicator) for indicator in indicators } hits = 0 run_args = [] # Normalize every path, for every path try: run_args = [(a, b, indicators) for a, b in enumerate(normalize_paths(files), 1)] async with aiomp.Pool() as pool: try: async for result in pool.map(_run, tuple(run_args)): if result: report[result["namespace"]]["matches"].append( result) hits += 1 except KeyboardInterrupt: pass except IndexError: pass count = len(run_args) CONSOLE("[cyan][YARA][/cyan] Done. Processed {} files.".format(count)) CONSOLE( "[cyan][YARA][/cyan] Found {} hit(s) for yara indicators.".format( hits)) with open(os.path.join(OUTPUT_DIR, "yara.json"), "w+") as writeout: writeout.write( json.dumps( {r: report[r] for r in report if report[r]["matches"]}))
async def run(indicators: dict) -> None: """Accept a dict containing yara indicators and write out to the OUTPUT_DIR specified by chirp.common. :param indicators: A NamespaceDict containing parsed yara indicator files. :type indicators: dict """ if not indicators: return logging.info("Entered yara plugin.") files = ( [i["indicator"]["files"] for i in indicators] if not TARGETS else TARGETS ) files = "\\**" if "\\**" in files else ", ".join(files) logging.info("Yara targets: {}".format(files)) if files == "\\**": blame = [i["name"] for i in indicators if i["indicator"]["files"] == "\\**"] logging.log( YARA, "Enumerating the entire filesystem due to {}... this is going to take a while.".format( blame ), ) report = { indicator["name"]: build_report(indicator) for indicator in indicators } hits = 0 count = 0 # Normalize every path, for every path try: with Pool(initializer=_signal_handler) as pool: for result in pool.imap_unordered( partial(_run, indicators), enumerate(normalize_paths(files), 1), chunksize=1000, ): if result: report[result["namespace"]]["matches"].append(result) hits += 1 count += 1 except IndexError: pass except KeyboardInterrupt: logging.log(YARA, "Received a keyboard interrupt. Killing workers.") logging.log(YARA, "Done. Processed {} files.".format(count)) logging.log(YARA, "Found {} hit(s) for yara indicators.".format(hits)) with open(os.path.join(OUTPUT_DIR, "yara.json"), "w+") as writeout: writeout.write( json.dumps({r: report[r] for r in report if report[r]["matches"]}) )
async def run(indicators: dict) -> None: """Accept a dict containing events indicators and writes out to the OUTPUT_DIR specified by chirp.common. :param indicators: A dict containing parsed events indicator files. :type indicators: dict """ if not indicators: return hits = 0 num_logs = 0 logging.debug("Entered events plugin.") event_types = { indicator["indicator"]["event_type"] for indicator in indicators } report = { indicator["name"]: build_report(indicator) for indicator in indicators } run_args = [(event_type, indicators, report, num_logs) for event_type in event_types] async with aiomp.Pool() as pool: try: async for i in pool.map(_run, tuple(run_args)): _rep = i[0] num_logs += i[1] for k, v in _rep.items(): try: report[k]["_search_criteria"] = v["_search_criteria"] except KeyError: pass report[k]["matches"] += v["matches"] except KeyboardInterrupt: pass hits = sum(len(v["matches"]) for _, v in report.items()) logging.log(EVENTS, "Read {} logs, found {} matches.".format(num_logs, hits)) with open(os.path.join(OUTPUT_DIR, "events.json"), "w+") as writeout: writeout.write( json.dumps({r: report[r] for r in report if report[r]["matches"]}))