def _generator(self): rules = yarascan.YaraScan.process_yara_options(dict(self.config)) filter_func = pslist.PsList.create_pid_filter( self.config.get('pid', None)) for task in pslist.PsList.list_processes( context=self.context, layer_name=self.config['primary'], symbol_table=self.config['nt_symbols'], filter_func=filter_func): layer_name = task.add_process_layer() layer = self.context.layers[layer_name] for offset, rule_name, name, value in layer.scan( context=self.context, scanner=yarascan.YaraScanner(rules=rules), sections=self.get_vad_maps(task)): yield 0, (format_hints.Hex(offset), task.UniqueProcessId, rule_name, name, value)
def _generator(self): if not has_yara: log.error("You must install yara") return config = dict() if self.config.get('yara_file', None) is not None: RULES = yara.compile(file=resources.ResourceAccessor().open( self.config['yara_file'], "rb")) else: # https://github.com/Yara-Rules/rules/blob/master/malware/MALW_Pony.yar SIGS = { 'pony': ''' rule pony { meta: author = "Brian Wallace @botnet_hunter" author_email = "*****@*****.**" date = "2014-08-16" description = "Identify Pony" strings: $ = "YUIPWDFILE0YUIPKDFILE0YUICRYPTED0YUI1.0" condition: all of them } ''' } RULES = yara.compile(sources=SIGS) #filter_func = pslist.PsList.create_pid_filter([self.config.get('pid', None)]) filter_func = pslist.PsList.create_pid_filter( [self.config.get('pid', None)]) for task in pslist.PsList.list_processes( context=self.context, layer_name=self.config['primary'], symbol_table=self.config['nt_symbols'], filter_func=filter_func): try: proc_layer_name = task.add_process_layer() except exceptions.InvalidAddressException: continue proc_layer = self.context.layers[proc_layer_name] for offset, rule_name, name, value in proc_layer.scan( context=self.context, scanner=yarascan.YaraScanner(rules=RULES), sections=vadyarascan.VadYaraScan.get_vad_maps(task)): log.debug("Got a Yara match!") vad, vad_start, vad_end = self.get_vad(task, offset) if vad is None: log.debug("VAD not found") return full_pe = io.BytesIO() chunk_size = 1024 * 1024 * 10 #vadinfo.VadInfo.vad_dump(self.context, task, vad, full_pe) offset = vad_start while offset < vad_end: to_read = min(chunk_size, vad_end - offset) data = proc_layer.read(offset, to_read, pad=True) if not data: break full_pe.write(data) offset += to_read if not full_pe: continue config = self.get_config(full_pe.getvalue()) if not config: log.debug("Config extraction failed") continue yield (0, (format_hints.Hex(offset), task.UniqueProcessId, str(config)))
def _generator(self): layer = self.context.layers[self.config['primary']] # Yara Rule to scan for MFT Header Signatures rules = yarascan.YaraScan.process_yara_options( {'yara_rules': '/FILE0|FILE\*|BAAD/'}) # Read in the Symbol File symbol_table = intermed.IntermediateSymbolTable.create( context=self.context, config_path=self.config_path, sub_path="windows", filename="mft", class_types={ 'FILE_NAME_ENTRY': mft.MFTFileName, 'MFT_ENTRY': mft.MFTEntry }) # get each of the individual Field Sets mft_object = symbol_table + constants.BANG + "MFT_ENTRY" attribute_object = symbol_table + constants.BANG + "ATTRIBUTE" header_object = symbol_table + constants.BANG + "ATTR_HEADER" si_object = symbol_table + constants.BANG + "STANDARD_INFORMATION_ENTRY" fn_object = symbol_table + constants.BANG + "FILE_NAME_ENTRY" # Scan the layer for Raw MFT records and parse the fields for offset, _rule_name, _name, _value in layer.scan( context=self.context, scanner=yarascan.YaraScanner(rules=rules)): try: mft_record = self.context.object(mft_object, offset=offset, layer_name=layer.name) # We will update this on each pass in the next loop and use it as the new offset. attr_base_offset = mft_record.FirstAttrOffset attr_header = self.context.object(header_object, offset=offset + attr_base_offset, layer_name=layer.name) # There is no field that has a count of Attributes # Keep Attempting to read attributes until we get an invalid attr_header.AttrType while attr_header.AttrType.is_valid_choice: vollog.debug(f"Attr Type: {attr_header.AttrType.lookup()}") # Offset past the headers to the attribute data attr_data_offset = offset + attr_base_offset + self.context.symbol_space.get_type( attribute_object).relative_child_offset("Attr_Data") # MFT Flags determine the file type or dir # If we don't have a valid enum, coerce to hex so we can keep the record try: mft_flag = mft_record.Flags.lookup() except ValueError: mft_flag = hex(mft_record.Flags) # Standard Information Attribute if attr_header.AttrType.lookup() == 'STANDARD_INFORMATION': attr_data = self.context.object( si_object, offset=attr_data_offset, layer_name=layer.name) yield 0, ( format_hints.Hex(attr_data_offset), mft_record.get_signature(), mft_record.RecordNumber, mft_record.LinkCount, mft_flag, renderers.NotApplicableValue(), attr_header.AttrType.lookup(), conversion.wintime_to_datetime( attr_data.CreationTime), conversion.wintime_to_datetime( attr_data.ModifiedTime), conversion.wintime_to_datetime( attr_data.UpdatedTime), conversion.wintime_to_datetime( attr_data.AccessedTime), renderers.NotApplicableValue(), ) # File Name Attribute if attr_header.AttrType.lookup() == 'FILE_NAME': attr_data = self.context.object( fn_object, offset=attr_data_offset, layer_name=layer.name) file_name = attr_data.get_full_name() # If we don't have a valid enum, coerce to hex so we can keep the record try: permissions = attr_data.Flags.lookup() except ValueError: permissions = hex(attr_data.Flags) yield 1, (format_hints.Hex(attr_data_offset), mft_record.get_signature(), mft_record.RecordNumber, mft_record.LinkCount, mft_flag, permissions, attr_header.AttrType.lookup(), conversion.wintime_to_datetime( attr_data.CreationTime), conversion.wintime_to_datetime( attr_data.ModifiedTime), conversion.wintime_to_datetime( attr_data.UpdatedTime), conversion.wintime_to_datetime( attr_data.AccessedTime), file_name) # If there's no advancement the loop will never end, so break it now if attr_header.Length == 0: break # Update the base offset to point to the next attribute attr_base_offset += attr_header.Length # Get the next attribute attr_header = self.context.object(header_object, offset=offset + attr_base_offset, layer_name=layer.name) except exceptions.PagedInvalidAddressException: pass