def _generator(self, tasks): is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["darwin"]) if is_32bit: pack_format = "I" bash_json_file = "bash32" else: pack_format = "Q" bash_json_file = "bash64" bash_table_name = BashIntermedSymbols.create(self.context, self.config_path, "linux", bash_json_file) ts_offset = self.context.symbol_space.get_type( bash_table_name + constants.BANG + "hist_entry").relative_child_offset("timestamp") for task in tasks: task_name = utility.array_to_string(task.p_comm) if task_name not in ["bash", "sh", "dash"]: continue proc_layer_name = task.add_process_layer() if proc_layer_name is None: continue proc_layer = self.context.layers[proc_layer_name] bang_addrs = [] # find '#' values on the heap for address in proc_layer.scan( self.context, scanners.BytesScanner(b"#"), sections=task.get_process_memory_sections( self.context, self.config['darwin'], rw_no_file=True)): bang_addrs.append(struct.pack(pack_format, address)) history_entries = [] for address, _ in proc_layer.scan( self.context, scanners.MultiStringScanner(bang_addrs), sections=task.get_process_memory_sections( self.context, self.config['darwin'], rw_no_file=True)): hist = self.context.object(bash_table_name + constants.BANG + "hist_entry", offset=address - ts_offset, layer_name=proc_layer_name) if hist.is_valid(): history_entries.append(hist) for hist in sorted(history_entries, key=lambda x: x.get_time_as_integer()): yield (0, (int(task.p_pid), task_name, hist.get_time_object(), hist.get_command()))
def _banner_scan( self, context: interfaces.context.ContextInterface, config_path: str, requirement: interfaces.configuration. ConstructableRequirementInterface, layer_name: str, progress_callback: constants.ProgressCallback = None) -> None: """Accepts a context, config_path and SymbolTableRequirement, with a constructed layer_name and scans the layer for banners.""" # Bomb out early if there's no banners if not self.banners: return mss = scanners.MultiStringScanner( [x for x in self.banners if x is not None]) layer = context.layers[layer_name] # Check if the Stacker has already found what we're looking for if layer.config.get(self.banner_config_key, None): banner_list = [(0, bytes(layer.config[self.banner_config_key], 'latin-1'))] # type: Iterable[Any] else: # Swap to the physical layer for scanning # TODO: Fix this so it works for layers other than just Intel layer = context.layers[layer.config['memory_layer']] banner_list = layer.scan(context=context, scanner=mss, progress_callback=progress_callback) for _, banner in banner_list: vollog.debug("Identified banner: {}".format(repr(banner))) symbol_files = self.banners.get(banner, None) if symbol_files: isf_path = symbol_files[0] vollog.debug("Using symbol library: {}".format( symbol_files[0])) clazz = self.symbol_class # Set the discovered options path_join = interfaces.configuration.path_join context.config[path_join(config_path, requirement.name, "class")] = clazz context.config[path_join(config_path, requirement.name, "isf_url")] = isf_path # Construct the appropriate symbol table requirement.construct(context, config_path) break else: if symbol_files: vollog.debug("Symbol library path not found: {}".format( symbol_files[0])) # print("Kernel", banner, hex(banner_offset)) else: vollog.debug("No existing banners found")
def __init__(self, module: interfaces.context.ModuleInterface, constraint_lookup: Dict[bytes, PoolConstraint], alignment: int): super().__init__() self._module = module self._constraint_lookup = constraint_lookup self._alignment = alignment header_type = self._module.get_type('_POOL_HEADER') self._header_offset = header_type.relative_child_offset('PoolTag') self._subscanner = scanners.MultiStringScanner([c for c in constraint_lookup.keys()])
def stack(cls, context: interfaces.context.ContextInterface, layer_name: str, progress_callback: constants.ProgressCallback = None) -> Optional[interfaces.layers.DataLayerInterface]: """Attempts to identify linux within this layer.""" # Bail out by default unless we can stack properly layer = context.layers[layer_name] join = interfaces.configuration.path_join # Never stack on top of an intel layer # FIXME: Find a way to improve this check if isinstance(layer, intel.Intel): return None linux_banners = LinuxBannerCache.load_banners() # If we have no banners, don't bother scanning if not linux_banners: vollog.info("No Linux banners found - if this is a linux plugin, please check your symbol files location") return None mss = scanners.MultiStringScanner([x for x in linux_banners if x is not None]) for _, banner in layer.scan(context = context, scanner = mss, progress_callback = progress_callback): dtb = None vollog.debug("Identified banner: {}".format(repr(banner))) symbol_files = linux_banners.get(banner, None) if symbol_files: isf_path = symbol_files[0] table_name = context.symbol_space.free_table_name('LintelStacker') table = linux.LinuxKernelIntermedSymbols(context, 'temporary.' + table_name, name = table_name, isf_url = isf_path) context.symbol_space.append(table) kaslr_shift, aslr_shift = cls.find_aslr(context, table_name, layer_name, progress_callback = progress_callback) layer_class = intel.Intel # type: Type if 'init_top_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_top_pgt' elif 'init_level4_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_level4_pgt' else: dtb_symbol_name = 'swapper_pg_dir' dtb = cls.virtual_to_physical_address(table.get_symbol(dtb_symbol_name).address + kaslr_shift) # Build the new layer new_layer_name = context.layers.free_layer_name("IntelLayer") config_path = join("IntelHelper", new_layer_name) context.config[join(config_path, "memory_layer")] = layer_name context.config[join(config_path, "page_map_offset")] = dtb context.config[join(config_path, LinuxSymbolFinder.banner_config_key)] = str(banner, 'latin-1') layer = layer_class(context, config_path = config_path, name = new_layer_name, metadata = {'kaslr_value': aslr_shift}) if layer and dtb: vollog.debug("DTB was found at: 0x{:0x}".format(dtb)) return layer return None
def stack(cls, context: interfaces.context.ContextInterface, layer_name: str, progress_callback: constants.ProgressCallback = None) -> Optional[interfaces.layers.DataLayerInterface]: """Attempts to identify mac within this layer.""" # Bail out by default unless we can stack properly layer = context.layers[layer_name] new_layer = None join = interfaces.configuration.path_join # Never stack on top of an intel layer # FIXME: Find a way to improve this check if isinstance(layer, intel.Intel): return None mac_banners = MacBannerCache.load_banners() # If we have no banners, don't bother scanning if not mac_banners: vollog.info("No Mac banners found - if this is a mac plugin, please check your symbol files location") return None mss = scanners.MultiStringScanner([x for x in mac_banners if x]) for banner_offset, banner in layer.scan(context = context, scanner = mss, progress_callback = progress_callback): dtb = None vollog.debug("Identified banner: {}".format(repr(banner))) symbol_files = mac_banners.get(banner, None) if symbol_files: isf_path = symbol_files[0] table_name = context.symbol_space.free_table_name('MacintelStacker') table = mac.MacKernelIntermedSymbols(context = context, config_path = join('temporary', table_name), name = table_name, isf_url = isf_path) context.symbol_space.append(table) kaslr_shift = MacUtilities.find_aslr(context = context, symbol_table = table_name, layer_name = layer_name, compare_banner = banner, compare_banner_offset = banner_offset, progress_callback = progress_callback) if kaslr_shift == 0: vollog.debug("Invalid kalsr_shift found at offset: {}".format(banner_offset)) continue bootpml4_addr = MacUtilities.virtual_to_physical_address( table.get_symbol("BootPML4").address + kaslr_shift) new_layer_name = context.layers.free_layer_name("MacDTBTempLayer") config_path = join("automagic", "MacIntelHelper", new_layer_name) context.config[join(config_path, "memory_layer")] = layer_name context.config[join(config_path, "page_map_offset")] = bootpml4_addr layer = layers.intel.Intel32e(context, config_path = config_path, name = new_layer_name, metadata = {'os': 'Mac'}) idlepml4_ptr = table.get_symbol("IdlePML4").address + kaslr_shift idlepml4_str = layer.read(idlepml4_ptr, 4) idlepml4_addr = struct.unpack("<I", idlepml4_str)[0] dtb = idlepml4_addr # Build the new layer new_layer_name = context.layers.free_layer_name("IntelLayer") config_path = join("automagic", "MacIntelHelper", new_layer_name) context.config[join(config_path, "memory_layer")] = layer_name context.config[join(config_path, "page_map_offset")] = dtb context.config[join(config_path, MacSymbolFinder.banner_config_key)] = str(banner, 'latin-1') new_layer = intel.Intel32e(context, config_path = config_path, name = new_layer_name) if new_layer and dtb: vollog.debug("DTB was found at: 0x{:0x}".format(dtb)) return new_layer return None
def _banner_scan( self, context: interfaces.context.ContextInterface, config_path: str, requirement: interfaces.configuration. ConstructableRequirementInterface, layer_name: str, progress_callback: constants.ProgressCallback = None) -> None: """Accepts a context, config_path and SymbolTableRequirement, with a constructed layer_name and scans the layer for banners.""" # Bomb out early if there's no banners if not self.banners: return mss = scanners.MultiStringScanner( [x for x in self.banners if x is not None]) layer = context.layers[layer_name] # Check if the Stacker has already found what we're looking for if layer.config.get(self.banner_config_key, None): banner_list = [(0, bytes(layer.config[self.banner_config_key], 'latin-1'))] # type: Iterable[Any] else: # Swap to the physical layer for scanning # TODO: Fix this so it works for layers other than just Intel layer = context.layers[layer.config['memory_layer']] banner_list = layer.scan(context=context, scanner=mss, progress_callback=progress_callback) for _, banner in banner_list: vollog.debug("Identified banner: {}".format(repr(banner))) symbol_files = self.banners.get(banner, None) if symbol_files: isf_path = symbol_files[0] vollog.debug("Using symbol library: {}".format( symbol_files[0])) clazz = self.symbol_class # Set the discovered options path_join = interfaces.configuration.path_join context.config[path_join(config_path, requirement.name, "class")] = clazz context.config[path_join(config_path, requirement.name, "isf_url")] = isf_path context.config[path_join(config_path, requirement.name, "symbol_mask")] = layer.address_mask # Set a default symbol_shift when attempt to determine it, # so we can create the symbols which are used in finding the aslr_shift anyway if not context.config.get( path_join(config_path, requirement.name, "symbol_shift"), None): # Don't overwrite it if it's already been set, it will be manually refound if not present prefound_kaslr_value = context.layers[ layer_name].metadata.get('kaslr_value', 0) context.config[path_join( config_path, requirement.name, "symbol_shift")] = prefound_kaslr_value # Construct the appropriate symbol table requirement.construct(context, config_path) # Apply the ASLR masking (only if we're not already shifted) if self.find_aslr and not context.config.get( path_join(config_path, requirement.name, "symbol_shift"), None): unmasked_symbol_table_name = context.config.get( path_join(config_path, requirement.name), None) if not unmasked_symbol_table_name: raise exceptions.SymbolSpaceError( "Symbol table could not be constructed") if not isinstance(layer, layers.intel.Intel): raise TypeError("Layer name {} is not an intel space") aslr_shift = self.find_aslr(context, unmasked_symbol_table_name, layer.config['memory_layer']) context.config[path_join(config_path, requirement.name, "symbol_shift")] = aslr_shift context.symbol_space.clear_symbol_cache( unmasked_symbol_table_name) break else: if symbol_files: vollog.debug("Symbol library path not found: {}".format( symbol_files[0])) # print("Kernel", banner, hex(banner_offset)) else: vollog.debug("No existing banners found")