Esempio n. 1
0
    def list_modules(
            cls, context: interfaces.context.ContextInterface, layer_name: str,
            vmlinux_symbols: str
    ) -> Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the modules in the primary layer.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            vmlinux_symbols: The name of the table containing the kernel symbols

        Yields:
            The modules present in the `layer_name` layer's modules list
        """
        linux.LinuxUtilities.aslr_mask_symbol_table(context, vmlinux_symbols,
                                                    layer_name)

        vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0)

        modules = vmlinux.object_from_symbol(
            symbol_name="modules").cast("list_head")

        table_name = modules.vol.type_name.split(constants.BANG)[0]

        for module in modules.to_list(table_name + constants.BANG + "module",
                                      "list"):
            yield module
Esempio n. 2
0
    def list_kernel_events(cls,
                           context: interfaces.context.ContextInterface,
                           layer_name: str,
                           darwin_symbols: str,
                           filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[Tuple[interfaces.objects.ObjectInterface,
                           interfaces.objects.ObjectInterface,
                           interfaces.objects.ObjectInterface]]:
        """
        Returns the kernel event filters registered

        Return values:
            A tuple of 3 elements:
                1) The name of the process that registered the filter
                2) The process ID of the process that registered the filter
                3) The object of the associated kernel event filter
        """
        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        list_tasks = pslist.PsList.get_list_tasks(
            pslist.PsList.pslist_methods[0])

        for task in list_tasks(context, layer_name, darwin_symbols,
                               filter_func):
            task_name = utility.array_to_string(task.p_comm)
            pid = task.p_pid

            for kn in cls._get_task_kevents(kernel, task):
                yield task_name, pid, kn
Esempio n. 3
0
    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))
Esempio n. 4
0
    def list_tasks(cls,
                   context: interfaces.context.ContextInterface,
                   layer_name: str,
                   vmlinux_symbols: str,
                   filter_func: Callable[[int], bool] = lambda _: False
                   ) -> Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the tasks in the primary layer.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            vmlinux_symbols: The name of the table containing the kernel symbols

        Yields:
            Process objects
        """
        linux.LinuxUtilities.aslr_mask_symbol_table(context, vmlinux_symbols, layer_name)

        vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0)

        init_task = vmlinux.object_from_symbol(symbol_name = "init_task")

        for task in init_task.tasks:
            if not filter_func(task):
                yield task
Esempio n. 5
0
    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)

        sysctl_list = kernel.object_from_symbol(symbol_name="sysctl__children")

        for sysctl, name, val in self._process_sysctl_list(
                kernel, sysctl_list):
            try:
                check_addr = sysctl.oid_handler
            except exceptions.InvalidAddressException:
                continue

            module_name, symbol_name = mac.MacUtilities.lookup_module_address(
                self.context, handlers, check_addr)

            yield (0, (name, sysctl.oid_number, sysctl.get_perms(),
                       format_hints.Hex(check_addr), val, module_name,
                       symbol_name))
Esempio n. 6
0
    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))
Esempio n. 7
0
    def list_tasks_pid_hash_table(cls,
                                  context: interfaces.context.ContextInterface,
                                  layer_name: str,
                                  darwin_symbols: str,
                                  filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the tasks in the primary layer using the pid hash table

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            darwin_symbols: The name of the table containing the kernel symbols
            filter_func: A function which takes a task object and returns True if the task should be ignored/filtered

        Returns:
            The list of task objects from the `layer_name` layer's `tasks` list after filtering
        """

        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        table_size = kernel.object_from_symbol(symbol_name="pidhash")

        pidhashtbl = kernel.object_from_symbol(symbol_name="pidhashtbl")

        proc_array = kernel.object(object_type="array",
                                   offset=pidhashtbl,
                                   count=table_size + 1,
                                   subtype=kernel.get_type("pidhashhead"))

        for proc_list in proc_array:
            for proc in mac.MacUtilities.walk_list_head(proc_list, "p_hash"):
                if not filter_func(proc):
                    yield proc
Esempio n. 8
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'],
                                  self.config['primary'], 0)

        modules = lsmod.Lsmod.list_modules(self.context,
                                           self.config['primary'],
                                           self.config['vmlinux'])

        handlers = linux.LinuxUtilities.generate_kernel_handler_info(
            self.context, self.config['primary'], self.config['vmlinux'],
            modules)

        try:
            knl_addr = vmlinux.object_from_symbol("keyboard_notifier_list")
        except exceptions.SymbolError:
            knl_addr = None

        if not knl_addr:
            raise TypeError(
                "This plugin requires the keyboard_notifier_list 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."
            )

        knl = vmlinux.object(object_type="atomic_notifier_head",
                             offset=knl_addr.vol.offset)

        for call_back in linux.LinuxUtilities.walk_internal_list(
                vmlinux, "notifier_block", "next", knl.head):
            call_addr = call_back.notifier_call

            module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
                self.context, handlers, call_addr)

            yield (0, [format_hints.Hex(call_addr), module_name, symbol_name])
Esempio n. 9
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'],
                                  self.config['primary'], 0)

        op_members = vmlinux.get_type('file_operations').members
        seq_members = vmlinux.get_type('seq_operations').members

        tcp = ("tcp_seq_afinfo", ["tcp6_seq_afinfo", "tcp4_seq_afinfo"])
        udp = ("udp_seq_afinfo", [
            "udplite6_seq_afinfo", "udp6_seq_afinfo", "udplite4_seq_afinfo",
            "udp4_seq_afinfo"
        ])
        protocols = [tcp, udp]

        for (struct_type, global_vars) in protocols:
            for global_var_name in global_vars:
                # this will lookup fail for the IPv6 protocols on kernels without IPv6 support
                try:
                    global_var = vmlinux.get_symbol(global_var_name)
                except exceptions.SymbolError:
                    continue

                global_var = vmlinux.object(object_type=struct_type,
                                            offset=global_var.address)

                for name, member, address in self._check_afinfo(
                        global_var_name, global_var, op_members, seq_members):
                    yield 0, (name, member, format_hints.Hex(address))
Esempio n. 10
0
    def _generator(self):
        mac.MacUtilities.aslr_mask_symbol_table(self.context,
                                                self.config['darwin'],
                                                self.config['primary'])

        kernel = contexts.Module(self._context, self.config['darwin'],
                                 self.config['primary'], 0)

        sysctl_list = kernel.object_from_symbol(symbol_name="sysctl__children")

        for sysctl, name, val in self._process_sysctl_list(
                kernel, sysctl_list):
            check_addr = sysctl.oid_handler

            if check_addr == 0:
                sym_name = "<No Handler>"
            else:
                symbols = list(
                    self.context.symbol_space.get_symbols_by_location(
                        check_addr))

                if len(symbols) > 0:
                    sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \
                        str(symbols[0])
                else:
                    sym_name = "UNKNOWN"

            yield (0, (name, sysctl.oid_number, sysctl.get_perms(),
                       format_hints.Hex(check_addr), val, sym_name))
Esempio n. 11
0
    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)

        table = kernel.object_from_symbol(symbol_name="mach_trap_table")

        for i, ent in enumerate(table):
            try:
                call_addr = ent.mach_trap_function.dereference().vol.offset
            except exceptions.InvalidAddressException:
                continue

            if not call_addr or call_addr == 0:
                continue

            module_name, symbol_name = mac.MacUtilities.lookup_module_address(
                self.context, handlers, call_addr)

            yield (0, (format_hints.Hex(table.vol.offset), "TrapTable", i,
                       format_hints.Hex(call_addr), module_name, symbol_name))
Esempio n. 12
0
    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))
Esempio n. 13
0
    def _generator(self):
        """
        Lists the registered VFS event watching processes
        Also lists which event(s) a process is registered for
        """

        kernel = contexts.Module(self.context, self.config['darwin'], self.config['primary'], 0)

        watcher_table = kernel.object_from_symbol("watcher_table")

        for watcher in watcher_table:
            if watcher == 0:
                continue

            task_name = utility.array_to_string(watcher.proc_name)
            task_pid = watcher.pid

            events = []

            try:
                event_array = kernel.object(object_type = "array",
                                            offset = watcher.event_list,
                                            count = 13,
                                            subtype = kernel.get_type("unsigned char"))

            except exceptions.InvalidAddressException:
                continue

            for i, event in enumerate(event_array):
                if event == 1:
                    events.append(self.event_types[i])

            if events != []:
                yield (0, (task_name, task_pid, ",".join(events)))
Esempio n. 14
0
    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)

        nsysent = kernel.object_from_symbol(symbol_name="nsysent")
        table = kernel.object_from_symbol(symbol_name="sysent")

        # smear help
        num_ents = min(nsysent, table.count)
        if num_ents > 1024:
            num_ents = 1024

        for (i, ent) in enumerate(table):
            try:
                call_addr = ent.sy_call.dereference().vol.offset
            except exceptions.InvalidAddressException:
                continue

            if not call_addr or call_addr == 0:
                continue

            module_name, symbol_name = mac.MacUtilities.lookup_module_address(
                self.context, handlers, call_addr)

            yield (0, (format_hints.Hex(table.vol.offset), "SysCall", i,
                       format_hints.Hex(call_addr), module_name, symbol_name))
Esempio n. 15
0
    def _generator(self):
        mac.MacUtilities.aslr_mask_symbol_table(self.context,
                                                self.config['darwin'],
                                                self.config['primary'])

        kernel = contexts.Module(self._context, self.config['darwin'],
                                 self.config['primary'], 0)

        table = kernel.object_from_symbol(symbol_name="mach_trap_table")

        for i, ent in enumerate(table):
            try:
                call_addr = ent.mach_trap_function.dereference().vol.offset
            except exceptions.InvalidPagedAddressException:
                continue

            if not call_addr or call_addr == 0:
                continue

            symbols = list(
                self.context.symbol_space.get_symbols_by_location(call_addr))

            if len(symbols) > 0:
                sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \
                    str(symbols[0])
            else:
                sym_name = "UNKNOWN"

            yield (0, (format_hints.Hex(table.vol.offset), "TrapTable", i,
                       format_hints.Hex(call_addr), sym_name))
Esempio n. 16
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)

        type_task = self.context.symbol_space.get_type(self.config['vmlinux'] + constants.BANG + "task_struct")

        if not type_task.has_member("cred"):
            raise TypeError(
                "This plugin requires the task_struct structure to have a cred member. "
                "This member 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."
            )

        creds = {}

        tasks = pslist.PsList.list_tasks(self.context, self.config['primary'], self.config['vmlinux'])

        for task in tasks:

            cred_addr = task.cred.dereference().vol.offset

            if not cred_addr in creds:
                creds[cred_addr] = []

            creds[cred_addr].append(task.pid)

        for (_, pids) in creds.items():
            if len(pids) > 1:
                pid_str = ""
                for pid in pids:
                    pid_str = pid_str + "{0:d}, ".format(pid)
                pid_str = pid_str[:-2]
                yield (0, [str(pid_str)])
Esempio n. 17
0
    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))
Esempio n. 18
0
    def _generator(self):
        linux.LinuxUtilities.aslr_mask_symbol_table(self.context,
                                                    self.config['vmlinux'],
                                                    self.config['primary'])

        vmlinux = contexts.Module(self.context, self.config['vmlinux'],
                                  self.config['primary'], 0)

        ptr_sz = vmlinux.get_type("pointer").size
        if ptr_sz == 4:
            table_name = "32bit"
        else:
            table_name = "64bit"

        try:
            table_info = self._get_table_info(vmlinux, "sys_call_table",
                                              ptr_sz)
        except exceptions.SymbolError:
            vollog.error("Unable to find the system call table. Exiting.")
            return

        tables = [(table_name, table_info)]

        # this table is only present on 64 bit systems with 32 bit emulation
        # enabled in order to support 32 bit programs and libraries
        # if the symbol isn't there then the support isn't in the kernel and so we skip it
        try:
            ia32_symbol = self.context.symbol_space.get_symbol(
                vmlinux.name + constants.BANG + "ia32_sys_call_table")
        except exceptions.SymbolError:
            ia32_symbol = None

        if ia32_symbol != None:
            ia32_info = self._get_table_info(vmlinux, "ia32_sys_call_table",
                                             ptr_sz)
            tables.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in tables:
            table = vmlinux.object(object_type="array",
                                   subtype=vmlinux.get_type("pointer"),
                                   offset=tableaddr,
                                   count=tblsz)

            for (i, call_addr) in enumerate(table):
                if not call_addr:
                    continue

                symbols = list(
                    self.context.symbol_space.get_symbols_by_location(
                        call_addr))

                if len(symbols) > 0:
                    sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \
                        str(symbols[0])
                else:
                    sym_name = "UNKNOWN"

                yield (0, (format_hints.Hex(tableaddr), table_name, i,
                           format_hints.Hex(call_addr), sym_name))
Esempio n. 19
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)

        modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux'])

        handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'],
                                                                     self.config['vmlinux'], modules)

        is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux"])

        idt_table_size = 256

        address_mask = self.context.layers[self.config['primary']].address_mask

        # hw handlers + system call
        check_idxs = list(range(0, 20)) + [128]

        if is_32bit:
            if vmlinux.has_type("gate_struct"):
                idt_type = "gate_struct"
            else:
                idt_type = "desc_struct"
        else:
            if vmlinux.has_type("gate_struct64"):
                idt_type = "gate_struct64"
            elif vmlinux.has_type("gate_struct"):
                idt_type = "gate_struct"
            else:
                idt_type = "idt_desc"

        addrs = vmlinux.object_from_symbol("idt_table")

        table = vmlinux.object(object_type = 'array', offset = addrs.vol.offset, subtype = vmlinux.get_type(idt_type),
                               count = idt_table_size)

        for i in check_idxs:
            ent = table[i]

            if not ent:
                continue

            if hasattr(ent, "Address"):
                idt_addr = ent.Address
            else:
                low = ent.offset_low
                middle = ent.offset_middle

                if hasattr(ent, "offset_high"):
                    high = ent.offset_high
                else:
                    high = 0

                idt_addr = (high << 32) | (middle << 16) | low

                idt_addr = idt_addr & address_mask

            module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, idt_addr)

            yield (0, [format_hints.Hex(i), format_hints.Hex(idt_addr), module_name, symbol_name])
Esempio n. 20
0
    def __init__(self, context, layer_name, vmlinux_symbols):
        self.context = context
        self.layer_name = layer_name
        self.vmlinux_symbols = vmlinux_symbols

        self.vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0)

        modules = lsmod.Lsmod.list_modules(context, layer_name, vmlinux_symbols)
        self.handlers = linux.LinuxUtilities.generate_kernel_handler_info(context, layer_name, vmlinux_symbols, modules)
Esempio n. 21
0
    def _generator(self, mods: Iterator[Any]):
        mac.MacUtilities.aslr_mask_symbol_table(self.context,
                                                self.config['darwin'],
                                                self.config['primary'])

        kernel = contexts.Module(self._context, self.config['darwin'],
                                 self.config['primary'], 0)

        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)

        mask = self.context.layers[self.config['primary']].address_mask
        mods_list = [(mod.name, mod.address & mask,
                      (mod.address & mask) + mod.size) for mod in mods]

        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

                found_module = None

                for mod_name_info, mod_base, mod_end in mods_list:
                    if call_addr >= mod_base and call_addr <= mod_end:
                        found_module = mod_name_info
                        break

                if found_module:
                    symbol_module = utility.array_to_string(found_module)
                else:
                    symbol_module = "UNKNOWN"

                yield (0, (check, ent_name, symbol_module,
                           format_hints.Hex(call_addr)))
Esempio n. 22
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)

        kset_modules = self.get_kset_modules(vmlinux)

        lsmod_modules = set(
            str(utility.array_to_string(modules.name))
            for modules in lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']))

        for mod_name in set(kset_modules.keys()).difference(lsmod_modules):
            yield (0, (format_hints.Hex(kset_modules[mod_name]), str(mod_name)))
Esempio n. 23
0
    def _generator(self):
        mac.MacUtilities.aslr_mask_symbol_table(self.context,
                                                self.config['darwin'],
                                                self.config['primary'])

        kernel = contexts.Module(self._context, self.config['darwin'],
                                 self.config['primary'], 0)

        real_ncpus = kernel.object_from_symbol(symbol_name="real_ncpus")

        cpu_data_ptrs_ptr = kernel.get_symbol("cpu_data_ptr").address

        cpu_data_ptrs_addr = kernel.object(
            object_type="pointer",
            offset=cpu_data_ptrs_ptr,
            subtype=kernel.get_type('long unsigned int'))

        cpu_data_ptrs = kernel.object(object_type="array",
                                      offset=cpu_data_ptrs_addr,
                                      subtype=kernel.get_type('cpu_data'),
                                      count=real_ncpus)

        for cpu_data_ptr in cpu_data_ptrs:
            try:
                queue = cpu_data_ptr.rtclock_timer.queue.head
            except exceptions.InvalidAddressException:
                break

            for timer in queue.walk_list(queue, "q_link", "call_entry"):
                try:
                    handler = timer.func
                except exceptions.InvalidAddressException:
                    continue

                symbols = list(
                    self.context.symbol_space.get_symbols_by_location(handler))

                if len(symbols) > 0:
                    sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \
                        str(symbols[0])
                else:
                    sym_name = "UNKNOWN"

                if hasattr(timer, "entry_time"):
                    entry_time = timer.entry_time
                else:
                    entry_time = -1

                yield (0, (format_hints.Hex(handler),
                           format_hints.Hex(timer.param0),
                           format_hints.Hex(timer.param1), timer.deadline,
                           entry_time, "kernel", sym_name))
Esempio n. 24
0
    def _generator(self):
        vmlinux = contexts.Module(self.context, self.config['vmlinux'],
                                  self.config['primary'], 0)

        modules = lsmod.Lsmod.list_modules(self.context,
                                           self.config['primary'],
                                           self.config['vmlinux'])

        handlers = linux.LinuxUtilities.generate_kernel_handler_info(
            self.context, self.config['primary'], self.config['vmlinux'],
            modules)

        try:
            tty_drivers = vmlinux.object_from_symbol("tty_drivers")
        except exceptions.SymbolError:
            tty_drivers = None

        if not tty_drivers:
            raise TypeError(
                "This plugin requires the tty_drivers 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."
            )

        for tty in tty_drivers.to_list(
                vmlinux.name + constants.BANG + "tty_driver", "tty_drivers"):

            try:
                ttys = utility.array_of_pointers(tty.ttys.dereference(),
                                                 count=tty.num,
                                                 subtype=vmlinux.name +
                                                 constants.BANG + "tty_struct",
                                                 context=self.context)
            except exceptions.PagedInvalidAddressException:
                continue

            for tty_dev in ttys:

                if tty_dev == 0:
                    continue

                name = utility.array_to_string(tty_dev.name)

                recv_buf = tty_dev.ldisc.ops.receive_buf

                module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
                    self.context, handlers, recv_buf)

                yield (0, (name, format_hints.Hex(recv_buf), module_name,
                           symbol_name))
Esempio n. 25
0
    def _generator(self):
        mac.MacUtilities.aslr_mask_symbol_table(self.context,
                                                self.config['darwin'],
                                                self.config['primary'])

        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)

        real_ncpus = kernel.object_from_symbol(symbol_name="real_ncpus")

        cpu_data_ptrs_ptr = kernel.get_symbol("cpu_data_ptr").address

        cpu_data_ptrs_addr = kernel.object(
            object_type="pointer",
            offset=cpu_data_ptrs_ptr,
            subtype=kernel.get_type('long unsigned int'))

        cpu_data_ptrs = kernel.object(object_type="array",
                                      offset=cpu_data_ptrs_addr,
                                      subtype=kernel.get_type('cpu_data'),
                                      count=real_ncpus)

        for cpu_data_ptr in cpu_data_ptrs:
            try:
                queue = cpu_data_ptr.rtclock_timer.queue.head
            except exceptions.InvalidAddressException:
                break

            for timer in queue.walk_list(queue, "q_link", "call_entry"):
                try:
                    handler = timer.func.dereference().vol.offset
                except exceptions.InvalidAddressException:
                    continue

                if timer.has_member("entry_time"):
                    entry_time = timer.entry_time
                else:
                    entry_time = -1

                module_name, symbol_name = mac.MacUtilities.lookup_module_address(
                    self.context, handlers, handler)

                yield (0, (format_hints.Hex(handler), format_hints.Hex(timer.param0), format_hints.Hex(timer.param1), \
                            timer.deadline, entry_time, module_name, symbol_name))
Esempio n. 26
0
    def list_tasks_pid_hash_table(cls,
                                  context: interfaces.context.ContextInterface,
                                  layer_name: str,
                                  darwin_symbols: str,
                                  filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the tasks in the primary layer using the pid hash table

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            darwin_symbols: The name of the table containing the kernel symbols
            filter_func: A function which takes a task object and returns True if the task should be ignored/filtered

        Returns:
            The list of task objects from the `layer_name` layer's `tasks` list after filtering
        """

        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        table_size = kernel.object_from_symbol(symbol_name = "pidhash")

        pidhashtbl = kernel.object_from_symbol(symbol_name = "pidhashtbl")

        proc_array = kernel.object(object_type = "array",
                                   offset = pidhashtbl,
                                   count = table_size + 1,
                                   subtype = kernel.get_type("pidhashhead"))

        for proc_list in proc_array:
            # test the validity of the current element
            # it is expected that many won't be initialized
            try:
                p = proc_list.lh_first
            except exceptions.PagedInvalidAddressException:
                continue

            seen = set()
            while p and p.vol.offset not in seen:
                seen.add(p.vol.offset)

                if p.is_readable() and not filter_func(p):
                    yield p

                try:
                    p = p.p_hash.le_next
                except exceptions.PagedInvalidAddressException:
                    break
Esempio n. 27
0
    def list_mounts(cls, context: interfaces.context.ContextInterface, layer_name: str, darwin_symbols: str):
        """Lists all the mount structures in the primary layer.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            darwin_symbols: The name of the table containing the kernel symbols

        Returns:
            A list of mount structures from the `layer_name` layer
        """
        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        list_head = kernel.object_from_symbol(symbol_name = "mountlist")

        for mount in mac.MacUtilities.walk_tailq(list_head, "mnt_list"):
            yield mount
Esempio n. 28
0
    def list_tasks(cls,
                   context: interfaces.context.ContextInterface,
                   layer_name: str,
                   darwin_symbols: str,
                   filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the processes in the primary layer.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            darwin_symbols: The name of the table containing the kernel symbols
            filter_func: A function which takes a process object and returns True if the process should be ignored/filtered

        Returns:
            The list of process objects from the processes linked list after filtering
        """

        mac.MacUtilities.aslr_mask_symbol_table(context, darwin_symbols,
                                                layer_name)

        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        kernel_as = context.layers[layer_name]

        proc = kernel.object_from_symbol(symbol_name="allproc").lh_first

        seen = {}  # type: Dict[int, int]
        while proc is not None and proc.vol.offset != 0:
            if proc.vol.offset in seen:
                vollog.log(
                    logging.INFO,
                    "Recursive process list detected (a result of non-atomic acquisition)."
                )
                break
            else:
                seen[proc.vol.offset] = 1

            if not filter_func(proc) and kernel_as.is_valid(
                    proc.vol.offset, proc.vol.size):
                yield proc

            try:
                proc = proc.p_list.le_next.dereference()
            except exceptions.InvalidAddressException:
                break
Esempio n. 29
0
    def list_tasks(cls,
                   context: interfaces.context.ContextInterface,
                   layer_name: str,
                   darwin_symbols: str,
                   filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[interfaces.objects.ObjectInterface]:
        """Lists all the tasks in the primary layer.

        Args:
            context: The context to retrieve required elements (layers, symbol tables) from
            layer_name: The name of the layer on which to operate
            darwin_symbols: The name of the table containing the kernel symbols
            filter_func: A function which takes a task object and returns True if the task should be ignored/filtered

        Returns:
            The list of task objects from the `layer_name` layer's `tasks` list after filtering
        """

        mac.MacUtilities.aslr_mask_symbol_table(context, darwin_symbols,
                                                layer_name)

        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        kernel_as = context.layers[layer_name]

        queue_entry = kernel.object_from_symbol(symbol_name="tasks")

        seen = {}  # type: Dict[int, int]
        for task in queue_entry.walk_list(queue_entry, "tasks", "task"):
            if task.vol.offset in seen:
                vollog.log(
                    logging.INFO,
                    "Recursive process list detected (a result of non-atomic acquisition)."
                )
                break
            else:
                seen[task.vol.offset] = 1

            try:
                proc = task.bsd_info.dereference().cast("proc")
            except exceptions.PagedInvalidAddressException:
                continue

            if kernel_as.is_valid(proc.vol.offset,
                                  proc.vol.size) and not filter_func(proc):
                yield proc
Esempio n. 30
0
    def list_kauth_scopes(cls,
                          context: interfaces.context.ContextInterface,
                          layer_name: str,
                          darwin_symbols: str,
                          filter_func: Callable[[int], bool] = lambda _: False) -> \
            Iterable[Tuple[interfaces.objects.ObjectInterface,
                          interfaces.objects.ObjectInterface,
                          interfaces.objects.ObjectInterface]]:
        """
        Enumerates the registered kauth scopes and yields each object
        Uses smear-safe enumeration API
        """

        kernel = contexts.Module(context, darwin_symbols, layer_name, 0)

        scopes = kernel.object_from_symbol("kauth_scopes")

        for scope in mac.MacUtilities.walk_tailq(scopes, "ks_link"):
            yield scope