def init_modules(): """Initialize plugins.""" log.debug("Imported modules...") categories = ( "auxiliary", "machinery", "processing", "signatures", "reporting", ) # Call the init_once() static method of each plugin/module. If an exception # is thrown in that initialization call, then a hard error is appropriate. for category in categories: for module in cuckoo.plugins[category]: module.init_once() for category in categories: log.debug("Imported \"%s\" modules:", category) entries = cuckoo.plugins[category] for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__) # Initialize the RunSignatures module with all available Signatures and # the ExtractManager with all available Extractors. RunSignatures.init_once() ExtractManager.init_once()
def init_modules(): """Initializes plugins.""" log.debug("Imported modules...") categories = ( "auxiliary", "machinery", "processing", "signatures", "reporting", ) # Call the init_once() static method of each plugin/module. If an exception # is thrown in that initialization call, then a hard error is appropriate. for category in categories: for module in cuckoo.plugins[category]: module.init_once() for category in categories: log.debug("Imported \"%s\" modules:", category) entries = cuckoo.plugins[category] for entry in entries: if entry == entries[-1]: log.debug("\t `-- %s", entry.__name__) else: log.debug("\t |-- %s", entry.__name__) # Initialize the RunSignatures module with all available Signatures and # the ExtractManager with all available Extractors. RunSignatures.init_once() ExtractManager.init_once()
def run(self): """Run analysis. @return: structured results. """ self.key = "procmemory" results = [] if os.path.exists(self.pmemory_path): for dmp in os.listdir(self.pmemory_path): if not dmp.endswith(".dmp"): continue dump_path = os.path.join(self.pmemory_path, dmp) dump_file = File(dump_path) pid, num = map(int, re.findall("(\\d+)", dmp)) regions = [] for region in roach.procmem(dump_path).regions: regions.append(region.to_json()) proc = dict( file=dump_path, pid=pid, num=num, yara=dump_file.get_yara("memory"), urls=list(dump_file.get_urls()), regions=regions, ) ExtractManager.for_task(self.task["id"]).peek_procmem(proc) if self.options.get("idapro"): self.create_idapy(proc) if self.options.get("extract_img"): proc["extracted"] = list( self.dump_images(proc, self.options.get("extract_dll"))) proc["extracted"] += list(self.dump_dex(proc)) if self.options.get("dump_delete"): try: os.remove(dump_path) except OSError: log.error( "Unable to delete memory dump file at path \"%s\"", dump_path) results.append(proc) results.sort(key=lambda x: (x["pid"], x["num"])) return results
def test_ident_shellcode(p): set_cwd(tempfile.mkdtemp()) cuckoo_create() mkdir(cwd("yara", "scripts")) open(cwd("yara", "scripts", "1.yar"), "wb").write(""" rule Shellcode1 { strings: $Shellcode = /=\s*((0x)?[0-9A-F]{2}\s*[,;]\s*)+/ nocase condition: all of them } """) # No Yara has been installed. if not init_yara(True): return class Shellcode1(Extractor): yara_rules = "Shellcode1" def handle_yara(self, filepath, match): sc = match.string("Shellcode", 0) self.push_shellcode( "".join(chr(int(x, 16)) for x in sc[2:-1].split(",")) ) p.return_value = Shellcode1, sc = shikata(open("tests/files/shellcode/shikata/1.bin", "rb").read()) sc = ",".join("0x%02x" % ord(ch) for ch in sc) scr = Scripting() ps1 = ("[Byte[]]$s = %s;" % sc).encode("utf-16le") cmd = scr.parse_command( "powershell -e %s" % ps1.encode("base64").replace("\n", "") ) mkdir(cwd(analysis=1)) em = ExtractManager(1) em.push_script({ "pid": 1, "first_seen": 2, }, cmd) assert len(em.items) == 2 filepath = cwd("extracted", "0.ps1", analysis=1) assert open(filepath, "rb").read().startswith("[Byte[]]$s = 0xfc") buf = open(cwd("extracted", "1.bin.txt", analysis=1), "rb").read() assert "call 0x88" in buf assert "0x00c1: push 0xc69f8957" in buf assert ".db 'www.service.chrome-up.date',0" in buf
def run(self): """Run analysis. @return: structured results. """ self.key = "procmemory" results = [] if os.path.exists(self.pmemory_path): for dmp in os.listdir(self.pmemory_path): if not dmp.endswith(".dmp"): continue dump_path = os.path.join(self.pmemory_path, dmp) dump_file = File(dump_path) pid, num = map(int, re.findall("(\\d+)", dmp)) regions = [] for region in roach.procmem(dump_path).regions: regions.append(region.to_json()) proc = dict( file=dump_path, pid=pid, num=num, yara=dump_file.get_yara("memory"), urls=list(dump_file.get_urls()), regions=regions, ) ExtractManager.for_task(self.task["id"]).peek_procmem(proc) if self.options.get("idapro"): self.create_idapy(proc) if self.options.get("extract_img"): proc["extracted"] = list(self.dump_images( proc, self.options.get("extract_dll") )) if self.options.get("dump_delete"): try: os.remove(dump_path) except OSError: log.error( "Unable to delete memory dump file at path \"%s\"", dump_path ) results.append(proc) results.sort(key=lambda x: (x["pid"], x["num"])) return results
def test_basics(): set_cwd(tempfile.mkdtemp()) cuckoo_create() mkdir(cwd(analysis=1)) init_yara() em = ExtractManager(1) em.write_extracted("foo", "bar") filepath = cwd("extracted", "0.foo", analysis=1) assert open(filepath, "rb").read() == "bar" scr = Scripting() cmd = scr.parse_command("powershell -e %s" % "foobar".encode("utf-16le").encode("base64")) em.push_script({ "pid": 1, "first_seen": 2, }, cmd) filepath = cwd("extracted", "0.ps1", analysis=1) assert open(filepath, "rb").read() == "foobar" em.push_command_line("powershell -e %s" % "world!".encode("utf-16le").encode("base64")) filepath = cwd("extracted", "1.ps1", analysis=1) assert open(filepath, "rb").read() == "world!"
def test_ident_shellcode(p): set_cwd(tempfile.mkdtemp()) cuckoo_create() mkdir(cwd("yara", "scripts")) open(cwd("yara", "scripts", "1.yar"), "wb").write(""" rule Shellcode1 { strings: $Shellcode = /=\s*((0x)?[0-9A-F]{2}\s*[,;]\s*)+/ nocase condition: all of them } """) # No Yara has been installed. if not init_yara(True): return class Shellcode1(Extractor): yara_rules = "Shellcode1" def handle_yara(self, filepath, match): sc = match.string("Shellcode", 0) self.push_shellcode("".join( chr(int(x, 16)) for x in sc[2:-1].split(","))) p.return_value = Shellcode1, sc = shikata(open("tests/files/shellcode/shikata/1.bin", "rb").read()) sc = ",".join("0x%02x" % ord(ch) for ch in sc) scr = Scripting() ps1 = ("[Byte[]]$s = %s;" % sc).encode("utf-16le") cmd = scr.parse_command("powershell -e %s" % ps1.encode("base64").replace("\n", "")) mkdir(cwd(analysis=1)) em = ExtractManager(1) em.push_script({ "pid": 1, "first_seen": 2, }, cmd) assert len(em.items) == 2 filepath = cwd("extracted", "0.ps1", analysis=1) assert open(filepath, "rb").read().startswith("[Byte[]]$s = 0xfc") buf = open(cwd("extracted", "1.bin.txt", analysis=1), "rb").read() assert "call 0x88" in buf assert "0x00c1: push 0xc69f8957" in buf assert ".db 'www.service.chrome-up.date',0" in buf
def process_extracted(self): task_id = self.results.get("info", {}).get("id") if not task_id: return for item in ExtractManager.for_task(task_id).results(): for sig in self.signatures: self.call_signature(sig, sig.on_extract, ExtractedMatch(item))
def test_basics(): set_cwd(tempfile.mkdtemp()) cuckoo_create() mkdir(cwd(analysis=1)) init_yara() em = ExtractManager(1) em.write_extracted("foo", "bar") filepath = cwd("extracted", "0.foo", analysis=1) assert open(filepath, "rb").read() == "bar" scr = Scripting() cmd = scr.parse_command( "powershell -e %s" % "foobar".encode("utf-16le").encode("base64") ) em.push_script({ "pid": 1, "first_seen": 2, }, cmd) filepath = cwd("extracted", "0.ps1", analysis=1) assert open(filepath, "rb").read() == "foobar" em.push_command_line( "powershell -e %s" % "world!".encode("utf-16le").encode("base64") ) filepath = cwd("extracted", "1.ps1", analysis=1) assert open(filepath, "rb").read() == "world!"
def init(package, *filename): id_ = task_id() init_analysis(id_, package, *filename) init_yara() s = Static() s.set_task({ "id": id_, "category": "file", "package": package, "target": filename[-1], }) s.file_path = cwd("binary", analysis=id_) e = ExtractManager.for_task(id_) return s.run(), e.results()
def test_cfgextr(): set_cwd(tempfile.mkdtemp()) cuckoo_create() class Trigger1(Extractor): yara_rules = "Trigger1" def handle_yara(self, filepath, match): self.push_config({ "family": "barfoo", "version": "baz", }) ExtractManager.init_once() mkdir(cwd(analysis=1)) em = ExtractManager(1) em.handle_yara( None, YaraMatch({ "name": "Trigger1", "meta": None, "offsets": None, "strings": [], })) assert len(em.items) == 1 results = { "extracted": em.results(), "metadata": {}, "info": {}, } RunSignatures(results).run() assert results == { "info": { "score": 10.0, }, "metadata": { "cfgextr": [{ "family": "barfoo", "version": "baz", }], }, "extracted": mock.ANY, "signatures": [], }
def test_push_script_recursive(): set_cwd(tempfile.mkdtemp()) cuckoo_create() mkdir(cwd(analysis=1)) open(cwd("yara", "office", "ole.yar"), "wb").write(""" rule OleInside { strings: $s1 = "Win32_Process" condition: filename matches /word\/vbaProject.bin/ and $s1 } """) init_yara() s = Static() s.file_path = "tests/files/createproc1.docm" s.set_task({ "id": 1, "category": "file", "target": s.file_path, "package": "doc", }) s.run() assert ExtractManager.for_task(1).results()[0]["yara"] == [{ "name": "OleInside", "meta": { "description": "(no description)", }, "offsets": { "s1": [ (3933, 0), ], }, "strings": [ "Win32_Process".encode("base64").strip(), ], }]
def test_cfgextr(): set_cwd(tempfile.mkdtemp()) cuckoo_create() class Trigger1(Extractor): yara_rules = "Trigger1" def handle_yara(self, filepath, match): self.push_config({ "family": "barfoo", "version": "baz", }) ExtractManager.init_once() mkdir(cwd(analysis=1)) em = ExtractManager(1) em.handle_yara(None, YaraMatch({ "name": "Trigger1", "meta": None, "offsets": None, "strings": [], })) assert len(em.items) == 1 results = { "extracted": em.results(), "metadata": {}, "info": {}, } RunSignatures(results).run() assert results == { "info": { "score": 10.0, }, "metadata": { "cfgextr": [{ "family": "barfoo", "version": "baz", }], }, "extracted": mock.ANY, "signatures": [], }
def __init__(self, filepath, task_id): self.filepath = filepath self.files = {} self.ex = ExtractManager.for_task(task_id)
def run(self): return ExtractManager.for_task(self.task.id).results()
def __init__(self, *args, **kwargs): super(ExtractScripts, self).__init__(*args, **kwargs) self.ex = ExtractManager.for_task(self.analysis.task["id"])
def test_on_extract(): set_cwd(tempfile.mkdtemp()) cuckoo_create() init_modules() Database().connect() mkdir(cwd(analysis=2)) cmd = Scripting().parse_command("cmd.exe /c ping 1.2.3.4") ex = ExtractManager.for_task(2) ex.push_script({ "pid": 1, "first_seen": 2, }, cmd) results = RunProcessing(task=Dictionary({ "id": 2, "category": "file", "target": __file__, })).run() assert results["extracted"] == [{ "category": "script", "pid": 1, "first_seen": 2, "program": "cmd", "raw": cwd("extracted", "0.bat", analysis=2), "yara": [], "info": {}, }] class sig1(object): name = "sig1" @property def matched(self): return False @matched.setter def matched(self, value): pass def init(self): pass def on_signature(self): pass def on_complete(self): pass def on_yara(self): pass on_extract = mock.MagicMock() rs = RunSignatures(results) rs.signatures = sig1(), rs.run() sig1.on_extract.assert_called_once() em = sig1.on_extract.call_args_list[0][0][0] assert em.category == "script"
def setup_module(): set_cwd(tempfile.mktemp()) shutil.copytree(os.path.expanduser("~/.cuckoo"), cwd()) reload_signatures() ExtractManager._instances = {} ExtractManager.init_once()
def __init__(self, *args, **kwargs): super(ExtractScripts, self).__init__(*args, **kwargs) self.scr = Scripting() self.ex = ExtractManager.for_task(self.analysis.task["id"])
def test_on_extract(): set_cwd(tempfile.mkdtemp()) cuckoo_create() init_modules() Database().connect() mkdir(cwd(analysis=2)) cmd = Scripting().parse_command("cmd.exe /c ping 1.2.3.4") ex = ExtractManager.for_task(2) ex.push_script({ "pid": 1, "first_seen": 2, }, cmd) results = RunProcessing(task=Dictionary({ "id": 2, "category": "file", "target": __file__, })).run() assert results["extracted"] == [{ "category": "script", "pid": 1, "first_seen": 2, "program": "cmd", "script": cwd("extracted", "0.bat", analysis=2), "yara": [], }] class sig1(object): name = "sig1" @property def matched(self): return False @matched.setter def matched(self, value): pass def init(self): pass def on_signature(self): pass def on_complete(self): pass def on_yara(self): pass on_extract = mock.MagicMock() rs = RunSignatures(results) rs.signatures = sig1(), rs.run() sig1.on_extract.assert_called_once() em = sig1.on_extract.call_args_list[0][0][0] assert em.category == "script"