def _generator(self): kernel = self.context.modules[self.config['kernel']] mods = lsmod.Lsmod.list_modules(self.context, self.config['kernel']) handlers = mac.MacUtilities.generate_kernel_handler_info(self.context, kernel.layer_name, kernel, mods) members_to_check = [ "sf_unregistered", "sf_attach", "sf_detach", "sf_notify", "sf_getpeername", "sf_getsockname", "sf_data_in", "sf_data_out", "sf_connect_in", "sf_connect_out", "sf_bind", "sf_setoption", "sf_getoption", "sf_listen", "sf_ioctl" ] filter_list = kernel.object_from_symbol(symbol_name = "sock_filter_head") for filter_container in mac.MacUtilities.walk_tailq(filter_list, "sf_global_next"): current_filter = filter_container.sf_filter filter_name = utility.pointer_to_string(current_filter.sf_name, count = 128) try: filter_socket = filter_container.sf_entry_head.sfe_socket.vol.offset except exceptions.InvalidAddressException: filter_socket = 0 for member in members_to_check: check_addr = current_filter.member(attr = member) if check_addr == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address(self.context, handlers, check_addr) yield (0, (format_hints.Hex(current_filter.vol.offset), filter_name, member, \ format_hints.Hex(filter_socket), format_hints.Hex(check_addr), module_name, symbol_name))
def _generator(self): kernel = self.context.modules[self.config['kernel']] try: list_head = kernel.object_from_symbol(symbol_name="ifnet_head") except exceptions.SymbolError: list_head = kernel.object_from_symbol( symbol_name="dlil_ifnet_head") for ifnet in mac.MacUtilities.walk_tailq(list_head, "if_link"): name = utility.pointer_to_string(ifnet.if_name, 32) unit = ifnet.if_unit prom = ifnet.if_flags & 0x100 == 0x100 # IFF_PROMISC sock_addr_dl = ifnet.sockaddr_dl() if sock_addr_dl is None: mac_addr = renderers.UnreadableValue() else: mac_addr = str(sock_addr_dl) for ifaddr in mac.MacUtilities.walk_tailq(ifnet.if_addrhead, "ifa_link"): ip = ifaddr.ifa_addr.get_address() yield (0, (f"{name}{unit}", ip, mac_addr, prom))
def _generator(self): """ Enumerates the listeners for each kauth scope """ kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) for scope in kauth_scopes.Kauth_scopes.list_kauth_scopes( self.context, self.config['primary'], self.config['darwin']): scope_name = utility.pointer_to_string(scope.ks_identifier, 128) for listener in scope.get_listeners(): callback = listener.kll_callback if callback == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, callback) yield (0, (scope_name, format_hints.Hex(listener.kll_idata), format_hints.Hex(callback), module_name, symbol_name))
def _generator(self): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) try: list_head = kernel.object_from_symbol(symbol_name="ifnet_head") except exceptions.SymbolError: list_head = kernel.object_from_symbol( symbol_name="dlil_ifnet_head") for ifnet in mac.MacUtilities.walk_tailq(list_head, "if_link"): name = utility.pointer_to_string(ifnet.if_name, 32) unit = ifnet.if_unit prom = ifnet.if_flags & 0x100 == 0x100 # IFF_PROMISC sock_addr_dl = ifnet.sockaddr_dl() if sock_addr_dl is None: mac_addr = renderers.UnreadableValue() else: mac_addr = str(sock_addr_dl) for ifaddr in mac.MacUtilities.walk_tailq(ifnet.if_addrhead, "ifa_link"): ip = ifaddr.ifa_addr.get_address() yield (0, ("{0}{1}".format(name, unit), ip, mac_addr, prom))
def get_kset_modules(self, context: interfaces.context.ContextInterface, vmlinux_name: str): vmlinux = context.modules[vmlinux_name] try: module_kset = vmlinux.object_from_symbol("module_kset") except exceptions.SymbolError: module_kset = None if not module_kset: raise TypeError( "This plugin requires the module_kset structure. This structure is not present in the supplied symbol table. This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt." ) ret = {} kobj_off = vmlinux.get_type('module_kobject').relative_child_offset('kobj') for kobj in module_kset.list.to_list(vmlinux.symbol_table_name + constants.BANG + "kobject", "entry"): mod_kobj = vmlinux.object(object_type = "module_kobject", offset = kobj.vol.offset - kobj_off, absolute = True) mod = mod_kobj.mod name = utility.pointer_to_string(kobj.name, 32) if kobj.name and kobj.reference_count() > 2: ret[name] = mod return ret
def _generator(self): kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0) mods = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['darwin']) handlers = mac.MacUtilities.generate_kernel_handler_info( self.context, self.config['primary'], kernel, mods) for scope in self.list_kauth_scopes(self.context, self.config['primary'], self.config['darwin']): callback = scope.ks_callback if callback == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address( self.context, handlers, callback) identifier = utility.pointer_to_string(scope.ks_identifier, 128) yield (0, (identifier, format_hints.Hex(scope.ks_idata), len([l for l in scope.get_listeners()]), format_hints.Hex(callback), module_name, symbol_name))
def get_path(self, context, config_prefix): node = self.get_vnode(context, config_prefix) if type(node) == str and node == "sub_map": ret = node elif node: path = [] seen: Set[int] = set() while node and node.vol.offset not in seen: try: v_name = utility.pointer_to_string(node.v_name, 255) except exceptions.InvalidAddressException: break path.append(v_name) if len(path) > 1024: break seen.add(node.vol.offset) node = node.v_parent path.reverse() ret = "/" + "/".join(path) else: ret = "" return ret
def _generator(self, mods: Iterator[Any]): kernel = contexts.Module(self._context, self.config['darwin'], self.config['primary'], 0) handlers = mac.MacUtilities.generate_kernel_handler_info(self.context, self.config['primary'], kernel, mods) policy_list = kernel.object_from_symbol(symbol_name = "mac_policy_list").cast("mac_policy_list") entries = kernel.object(object_type = "array", offset = policy_list.entries.dereference().vol.offset, subtype = kernel.get_type('mac_policy_list_element'), count = policy_list.staticmax + 1) for i, ent in enumerate(entries): # I don't know how this can happen, but the kernel makes this check all over the place # the policy isn't useful without any ops so a rootkit can't abuse this try: mpc = ent.mpc.dereference() ops = mpc.mpc_ops.dereference() except exceptions.InvalidAddressException: continue try: ent_name = utility.pointer_to_string(mpc.mpc_name, 255) except exceptions.InvalidAddressException: ent_name = "N/A" for check in ops.vol.members: call_addr = getattr(ops, check) if call_addr is None or call_addr == 0: continue module_name, symbol_name = mac.MacUtilities.lookup_module_address(self.context, handlers, call_addr) yield (0, (check, ent_name, format_hints.Hex(call_addr), module_name, symbol_name))
def _vnode_name(cls, vnode: interfaces.objects.ObjectInterface) -> Optional[str]: # roots of mount points have special name handling if vnode.v_flag & 1 == 1: v_name = vnode.full_path() else: try: v_name = utility.pointer_to_string(vnode.v_name, 255) except exceptions.InvalidAddressException: v_name = None return v_name
def get_path(self, context, config_prefix): node = self.get_vnode(context, config_prefix) if type(node) == str and node == "sub_map": ret = node elif node: path = [] while node: v_name = utility.pointer_to_string(node.v_name, 255) path.append(v_name) node = node.v_parent path.reverse() ret = "/" + "/".join(path) else: ret = "" return ret
def _do_calc_path(self, ret, vnodeobj, vname): if vnodeobj is None: return if vname: ret.append(utility.pointer_to_string(vname, 255)) if int(vnodeobj.v_flag) & 0x000001 != 0 and int(vnodeobj.v_mount) != 0: if int(vnodeobj.v_mount.mnt_vnodecovered) != 0: self._do_calc_path(ret, vnodeobj.v_mount.mnt_vnodecovered, vnodeobj.v_mount.mnt_vnodecovered.v_name) else: try: parent = vnodeobj.v_parent parent_name = parent.v_name except exceptions.InvalidAddressException: return self._do_calc_path(ret, parent, parent_name)
def _process_sysctl_list(self, kernel, sysctl_list, recursive=0): if type(sysctl_list) == volatility3.framework.objects.Pointer: sysctl_list = sysctl_list.dereference().cast("sysctl_oid_list") sysctl = sysctl_list.slh_first if recursive != 0: try: sysctl = sysctl.oid_link.sle_next.dereference() except exceptions.InvalidAddressException: return while sysctl: try: name = utility.pointer_to_string(sysctl.oid_name, 128) except exceptions.InvalidAddressException: name = "" if len(name) == 0: break ctltype = sysctl.get_ctltype() try: arg1_ptr = sysctl.oid_arg1.dereference().vol.offset except exceptions.InvalidAddressException: arg1_ptr = 0 arg1 = sysctl.oid_arg1 if arg1 == 0 or arg1_ptr == 0: val = self._parse_global_variable_sysctls(kernel, name) elif ctltype == 'CTLTYPE_NODE': if sysctl.oid_handler == 0: for info in self._process_sysctl_list(kernel, sysctl.oid_arg1, recursive=1): yield info val = "Node" elif ctltype in ['CTLTYPE_INT', 'CTLTYPE_QUAD', 'CTLTYPE_OPAQUE']: try: val = str(arg1.dereference().cast("int")) except exceptions.InvalidAddressException: val = "-1" elif ctltype == 'CTLTYPE_STRING': try: val = utility.pointer_to_string(sysctl.oid_arg1, 64) except exceptions.InvalidAddressException: val = "" else: val = ctltype yield (sysctl, name, val) try: sysctl = sysctl.oid_link.sle_next except exceptions.InvalidAddressException: break