def test_machine_info_empty(self): set_cwd(tempfile.mkdtemp()) rp = RunProcessing({ "id": 1, }) rp.populate_machine_info() assert rp.machine == {}
def process_results(self): """Process the analysis results and generate the enabled reports.""" logger("Starting task reporting", action="task.report", status="pending") # TODO Refactor this function as currently "cuckoo process" has a 1:1 # copy of its code. TODO Also remove "archive" files. results = RunProcessing(task=self.task).run() RunSignatures(results=results).run() RunReporting(task=self.task, results=results).run() # If the target is a file and the user enabled the option, # delete the original copy. if self.task.category == "file" and self.cfg.cuckoo.delete_original: if not os.path.exists(self.task.target): log.warning( "Original file does not exist anymore: \"%s\": " "File not found.", self.task.target) else: try: os.remove(self.task.target) except OSError as e: log.error( "Unable to delete original file at path " "\"%s\": %s", self.task.target, e) # If the target is a file and the user enabled the delete copy of # the binary option, then delete the copy. if self.task.category == "file" and self.cfg.cuckoo.delete_bin_copy: if not os.path.exists(self.binary): log.warning( "Copy of the original file does not exist anymore: \"%s\": File not found", self.binary) else: try: os.remove(self.binary) except OSError as e: log.error( "Unable to delete the copy of the original file at path \"%s\": %s", self.binary, e) # Check if the binary in the analysis directory is an invalid symlink. If it is, delete it. if os.path.islink(self.storage_binary) and not os.path.exists( self.storage_binary): try: os.remove(self.storage_binary) except OSError as e: log.error( "Unable to delete symlink to the binary copy at path \"%s\": %s", self.storage_binary, e) log.info("Task #%d: reports generation completed", self.task.id, extra={ "action": "task.report", "status": "success", }) return True
def test_machine_info_cuckoo2(self): set_cwd(tempfile.mkdtemp()) cuckoo_create() rp = RunProcessing({ "id": 1, "guest": { "manager": "VirtualBox", "name": "cuckoo2", }, }) rp.populate_machine_info() assert rp.machine == { "name": "cuckoo2", }
def test_machine_info_cuckoo1(self): set_cwd(tempfile.mkdtemp()) cuckoo_create() rp = RunProcessing({ "id": 1, "guest": { "manager": "VirtualBox", "name": "cuckoo1", }, }) rp.populate_machine_info() assert rp.machine["name"] == "cuckoo1" assert rp.machine["label"] == "cuckoo1" assert rp.machine["ip"] == "192.168.56.101"
def test_static_extracted(self): set_cwd(self.mkdtemp()) cuckoo_create(cfg={ "processing": { "analysisinfo": { "enabled": False, }, "debug": { "enabled": False, } }, }) mkdir(cwd(analysis=1)) shutil.copy("tests/files/createproc1.docm", cwd("binary", 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() class OleInsideExtractor(Extractor): def handle_yara(self, filepath, match): return ( match.category == "office" and match.yara[0].name == "OleInside" ) class X(object): @staticmethod def p(): return [Extracted, Static] with mock.patch("cuckoo.processing.plugins", new_callable=X.p) as p: ExtractManager._instances = {} ExtractManager.extractors = OleInsideExtractor, results = RunProcessing(Dictionary({ "id": 1, "category": "file", "target": "tests/files/createproc1.docm", })).run() assert len(results["extracted"]) == 1
def process(self, signatures=True, reporting=True, processing_modules=[]): """Process, run signatures and reports the results for this task""" results = RunProcessing(task=self.task_dict).run( processing_list=processing_modules) if signatures: RunSignatures(results=results).run() if reporting: RunReporting(task=self.task_dict, results=results).run() if config("cuckoo:cuckoo:delete_original"): for target in self.targets: target.delete_original() if config("cuckoo:cuckoo:delete_bin_copy"): for target in self.targets: target.delete_copy() return True
def process(target, copy_path, task): results = RunProcessing(task=task).run() RunSignatures(results=results).run() RunReporting(task=task, results=results).run() if config("cuckoo:cuckoo:delete_original"): try: if target and os.path.exists(target): os.remove(target) except OSError as e: log.error("Unable to delete original file at path \"%s\": %s", target, e) if config("cuckoo:cuckoo:delete_bin_copy"): try: if copy_path and os.path.exists(copy_path): os.remove(copy_path) except OSError as e: log.error( "Unable to delete the copy of the original file at " "path \"%s\": %s", copy_path, e)
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 test_on_yara(): set_cwd(os.path.realpath(tempfile.mkdtemp())) cuckoo_create() init_modules() shutil.copy(cwd("yara", "binaries", "vmdetect.yar"), cwd("yara", "memory", "vmdetect.yar")) init_yara() mkdir(cwd(analysis=1)) open(cwd("binary", analysis=1), "wb").write("\x0f\x3f\x07\x0b") mkdir(cwd("files", analysis=1)) open(cwd("files", "1.txt", analysis=1), "wb").write("\x56\x4d\x58\x68") mkdir(cwd("memory", analysis=1)) open(cwd("memory", "1-0.dmp", analysis=1), "wb").write( struct.pack("QIIII", 0x400000, 0x1000, 0, 0, 0) + "\x45\xc7\x00\x01") Database().connect() ExtractManager._instances = {} results = RunProcessing(task=Dictionary({ "id": 1, "category": "file", "target": __file__, })).run() assert results["target"]["file"]["yara"][0]["offsets"] == { "virtualpc": [(0, 0)], } assert results["procmemory"][0]["regions"] == [{ "addr": "0x00400000", "end": "0x00401000", "offset": 24, "protect": None, "size": 4096, "state": 0, "type": 0, }] assert results["procmemory"][0]["yara"][0]["offsets"] == { "vmcheckdll": [(24, 0)], } assert results["dropped"][0]["yara"][0]["offsets"] == { "vmware": [(0, 0)], "vmware1": [(0, 0)], } class sig1(Signature): name = "sig1" @property def matched(self): return False @matched.setter def matched(self, value): pass def init(self): pass def on_signature(self, sig): pass def on_complete(self): pass def on_extract(self, match): pass on_yara = mock.MagicMock() rs = RunSignatures(results) rs.signatures = sig1(rs), rs.run() assert sig1.on_yara.call_count == 3 sig1.on_yara.assert_any_call("sample", cwd("binary", analysis=1), mock.ANY) sig1.on_yara.assert_any_call("dropped", cwd("files", "1.txt", analysis=1), mock.ANY) sig1.on_yara.assert_any_call("procmem", cwd("memory", "1-0.dmp", analysis=1), mock.ANY) ym = sig1.on_yara.call_args_list[0][0][2] assert ym.offsets == { "virtualpc": [(0, 0)], } assert ym.string("virtualpc", 0) == "\x0f\x3f\x07\x0b"
def test_on_yara(): set_cwd(tempfile.mkdtemp()) cuckoo_create() init_modules() shutil.copy( cwd("yara", "binaries", "vmdetect.yar"), cwd("yara", "memory", "vmdetect.yar") ) init_yara(True) mkdir(cwd(analysis=1)) open(cwd("binary", analysis=1), "wb").write("\x0f\x3f\x07\x0b") mkdir(cwd("files", analysis=1)) open(cwd("files", "1.txt", analysis=1), "wb").write("\x56\x4d\x58\x68") mkdir(cwd("memory", analysis=1)) open(cwd("memory", "1-0.dmp", analysis=1), "wb").write( struct.pack("QIIII", 0x400000, 0x1000, 0, 0, 0) + "\x45\xc7\x00\x01" ) Database().connect() results = RunProcessing(task=Dictionary({ "id": 1, "category": "file", "target": __file__, })).run() assert results["target"]["file"]["yara"][0]["offsets"] == { "virtualpc": [(0, 0)], } assert results["procmemory"][0]["yara"][0]["offsets"] == { "vmcheckdll": [(24, 0)], } assert results["dropped"][0]["yara"][0]["offsets"] == { "vmware": [(0, 0)], "vmware1": [(0, 0)], } 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 on_yara = mock.MagicMock() rs = RunSignatures(results) rs.signatures = sig1(), rs.run() assert sig1.on_yara.call_count == 3 sig1.on_yara.assert_any_call( "sample", cwd("binary", analysis=1), mock.ANY ) sig1.on_yara.assert_any_call( "dropped", cwd("files", "1.txt", analysis=1), mock.ANY ) sig1.on_yara.assert_any_call( "procmem", cwd("memory", "1-0.dmp", analysis=1), mock.ANY ) assert sig1.on_yara.call_args_list[0][0][2]["offsets"] == { "virtualpc": [(0, 0)], }