def _run(self, scanObject, result, depth, args): moduleResult = [] with tempfile.NamedTemporaryFile(dir=self.TEMP_DIR) as temp_file: temp_file_name = temp_file.name temp_file.write(scanObject.buffer) temp_file.flush() # rtfobj v 0.02 has two objects in the rtf iter if rtfobj.__version__ == str(0.02): for index, obj_data in rtfobj.rtf_iter_objects(temp_file_name): name = 'index_' + str(index) try: moduleResult.append(ModuleObject(buffer=obj_data, externalVars=ExternalVars(filename='e_rtf_%s' % name))) except: scanObject.addFlag('explode_rtf:err:explode_%s_failed' % name) pass # rtfobj v 0.03 has three objects in the rtf iter elif rtfobj.__version__ == str(0.03): for index, obj_len, obj_data in rtfobj.rtf_iter_objects(temp_file_name): name = 'index_' + str(index) try: moduleResult.append(ModuleObject(buffer=obj_data, externalVars=ExternalVars(filename='e_rtf_%s' % name))) except: scanObject.addFlag('explode_rtf:err:explode_%s_failed' % name) pass return moduleResult
def _run(self, scanObject, result, depth, args): moduleResult = [] for index, obj_len, obj_data in rtfobj.rtf_iter_objects( scanObject.filename): # index location of the RTF object becomes the file name name = 'index_' + str(index) moduleResult.append( ModuleObject(buffer=obj_data, externalVars=ExternalVars(filename='e_rtf_%s' % name))) return moduleResult
def each_with_type(self, target, file_type): self.results = dict() content = open(target, 'rb').read() rtfdata = content.decode('UTF-8') replace_content = rtfdata.replace('datastore', 'objdata') open(target, 'wb').write(str.encode(replace_content)) self.results['objects'] = list() for index, orig_len, data in rtfobj.rtf_iter_objects(target): object_dict = dict() object_dict['sha256'] = hashlib.sha256(data).hexdigest() object_dict['code'] = data.decode(errors='replace') self.results['objects'].append(object_dict) if len(self.results['objects']) > 0: return True else: return False
def EXTRACT_RTF_OBJ(s, buff): PARENT_RTF_OBJS = {} counter = 0 tmpfd, tmpfile = mkstemp(suffix='.rtf') tmpf = os.fdopen(tmpfd, 'wb') try: tmpf.write(buff) tmpf.close() objs = rtfobj.rtf_iter_objects(tmpfile) for index, orig_len, data in objs: CHILD_OBJ = {'Index': index, 'Buffer': data} PARENT_RTF_OBJS['Object_%s' % counter] = CHILD_OBJ counter += 1 finally: os.remove(tmpfile) return PARENT_RTF_OBJS
def EXTRACT_RTF_OBJ(s, buff): PARENT_RTF_OBJS = {} counter = 0 tmpfd, tmpfile = mkstemp(suffix='.rtf') tmpf = os.fdopen(tmpfd, 'wb') try: tmpf.write(buff) tmpf.close() objs = rtfobj.rtf_iter_objects(tmpfile) for index, data in objs: CHILD_OBJ = {'Index' : index, 'Buffer' : data } PARENT_RTF_OBJS['Object_%s' % counter] = CHILD_OBJ counter += 1 finally: os.remove(tmpfile) return PARENT_RTF_OBJS
from oletools import rtfobj for index, data in rtfobj.rtf_iter_objects("sample.rtf"): print "haha" print 'found object size %d at index %08X' % (len(data), index)
def extract_streams(self, file_name, file_contents): oles = {} try: streams_res = ResultSection(score=SCORE.INFO, title_text="Embedded document stream(s)") is_zip = False is_ole = False # Get the OLEs if zipfile.is_zipfile(file_name): is_zip = True z = zipfile.ZipFile(file_name) for f in z.namelist(): if f in oles: continue bin_data = z.open(f).read() bin_fname = os.path.join(self.working_directory, "{}.tmp".format(hashlib.sha256(bin_data).hexdigest())) with open(bin_fname, 'w') as bin_fh: bin_fh.write(bin_data) if olefile.isOleFile(bin_fname): oles[f] = olefile.OleFileIO(bin_fname) elif olefile2.isOleFile(bin_fname): oles[f] = olefile2.OleFileIO(bin_fname) z.close() if olefile.isOleFile(file_name): is_ole = True oles[file_name] = olefile.OleFileIO(file_name) elif olefile2.isOleFile(file_name): is_ole = True oles[file_name] = olefile2.OleFileIO(file_name) if is_zip and is_ole: streams_res.report_heuristics(Oletools.AL_Oletools_002) decompressed_macros = False for ole_filename in oles.iterkeys(): try: decompressed_macros |= self.process_ole_stream(oles[ole_filename], streams_res) except Exception: continue if decompressed_macros: streams_res.score = SCORE.HIGH for _, offset, rtfobject in rtf_iter_objects(file_contents): rtfobject_name = hex(offset) + '.rtfobj' extracted_obj = os.path.join(self.working_directory, rtfobject_name) with open(extracted_obj, 'wb') as fh: fh.write(rtfobject) self.request.add_extracted(extracted_obj, 'Embedded RTF Object at offset %s' % hex(offset), rtfobject_name) if len(streams_res.body) > 0: self.ole_result.add_section(streams_res) except Exception: self.log.debug("Error extracting streams: {}".format(traceback.format_exc(limit=2))) finally: for fd in oles.itervalues(): try: fd.close() except: pass
def run(self, task, param=None): """ Initialize variables """ task_data = collections.OrderedDict() _object = collections.OrderedDict() output = [] file_buffer = "" file_buffer_stripped = "" handler = None """ Scan the file content """ task_data["file_sig"] = "" with open(self.file, 'rb') as file_content: file_buffer = file_content.read() task_data["file_sig"] = task.scanner["yara"].scan_buffer( file_buffer) # Scan stripped file content if previous match was not found if not task_data["file_sig"]: try: file_buffer_stripped = self._strip_keycodes( file_buffer.decode("utf8")) task_data["file_sig"] = task.scanner["yara"].scan_buffer( file_buffer_stripped) except UnicodeDecodeError: logger.warning( f"UnicodeDecodeError: Failed to decode -> {self.file}") """ Get the right handler by file_sig """ handler = self._get_handler(task_data["file_sig"]) if handler: if file_buffer_stripped: handler(self, file_buffer_stripped, task_data) else: handler(self, file_buffer, task_data) """ Get info about all objects available """ _objects = list(rtfobj.rtf_iter_objects(self.file)) task_data["obj_count"] = len(_objects) task_data["body_ioc_strings"] = task.scanner["regex"].ioc_scan( file_buffer.decode("utf8")) """ Update Task's IOCs """ task.update_ioc(task_data["body_ioc_strings"]) task_data["body_text"] = self._striprtf(file_buffer.decode("utf8")) if _objects: for offset, orig_len, data in _objects: _object["obj_offset"] = '0x%08X' % offset try: _oleobj = oleobj.OleObject() _oleobj.parse(data) _object["ole_type"] = str(_oleobj.class_name) _object["ole_size"] = _oleobj.data_size except Exception: _object["ole_type"] = "" _object["ole_size"] = "" _object["obj_size"] = len(data) _object["obj_sig"] = str(data[:self.obj_sig_len]) try: unique_strings = "" data_str = data.decode(errors='ignore') unique_strings = "\r".join( list( set( re.findall("[^\x00-\x1F\x7F-\xFF]{3,}", data_str)))) except Exception: unique_strings = "" _object["ole_strings"] = unique_strings """ Scan the data object content """ ole_yarasig = "" ole_yarasig = task.scanner["yara"].scan_buffer(data) _object["ole_yara_sig"] = ole_yarasig matched_strings = "" matched_strings = task.scanner["regex"].ioc_scan( unique_strings) _object["ole_regex_strings"] = matched_strings """ Update Task's IOCs """ task.update_ioc(_object["ole_regex_strings"]) output.append(_object.copy()) _object.clear() else: logger.warning(f"No objects found. File: {self.file}") """ Properly close the task before returning from the function""" task_data["objects"] = output self.end(task, task_data)