예제 #1
0
    def calculate(self):
        common.set_plugin_members(self)

        # get all the members of 'mac_policy_ops' so that we can check them (they are all function ptrs)
        ops_members = self.get_members()

        # get the symbols need to check for if rootkit or not
        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        list_addr = self.get_profile_symbol("_mac_policy_list")
    
        plist = obj.Object("mac_policy_list", offset = list_addr, vm = self.addr_space)
        parray = obj.Object('Array', offset = plist.entries, vm = self.addr_space, targetType = 'mac_policy_list_element', count = plist.maxindex + 1)

        for ent in parray:
            # I don't know how this can happen, but the kernel makes this check all over the place
            # the policy is useful without any ops so a rootkit can't abuse this
            if ent.mpc == None:
                continue

            name = ent.mpc.mpc_name.dereference()

            ops = obj.Object("mac_policy_ops", offset = ent.mpc.mpc_ops, vm = self.addr_space)

            # walk each member of the struct
            for check in ops_members:
                ptr = ops.__getattr__(check)
               
                if ptr != 0:
                    # make the last parameter 1 to see the names of known modules that load policies
                    good = common.is_known_address(ptr, kernel_symbol_addresses, kmods, 0) 

                    yield (good, check, name, ptr)
예제 #2
0
    def calculate(self):
        common.set_plugin_members(self)

        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        sysctl_children_addr = self.addr_space.profile.get_symbol(
            "_sysctl__children")

        sysctl_list = obj.Object("sysctl_oid_list",
                                 offset=sysctl_children_addr,
                                 vm=self.addr_space)

        for (sysctl, name, val) in self._process_sysctl_list(sysctl_list):
            if val == "INVALID -1":
                continue

            is_known = common.is_known_address(sysctl.oid_handler,
                                               kernel_symbol_addresses, kmods)

            if is_known:
                status = "OK"
            else:
                status = "UNKNOWN"

            yield (sysctl, name, val, is_known, status)
예제 #3
0
    def calculate(self):
        common.set_plugin_members(self)

        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)
        gnotify_addr = common.get_cpp_sym("gNotifications", self.addr_space.profile)
        gnotify_ptr = obj.Object("Pointer", offset = gnotify_addr, vm = self.addr_space)
        gnotifications = gnotify_ptr.dereference_as("OSDictionary")
        ents = obj.Object('Array', offset = gnotifications.dictionary, vm = self.addr_space, targetType = 'dictEntry', count = gnotifications.count)

        # walk the current set of notifications
        for ent in ents:

            if ent == None:
                continue

            key = ent.key.dereference_as("OSString") 

            # get the value
            valset = ent.value.dereference_as("OSOrderedSet")
            notifiers_ptrs = obj.Object('Array', offset = valset.array, vm = self.addr_space, targetType = 'Pointer', count = valset.count)
            
            for ptr in notifiers_ptrs:
                notifier = ptr.dereference_as("_IOServiceNotifier") 

                if notifier == None:
                    continue

                matches = self.get_matching(notifier)

                # this is the function that handles whatever the notification is for
                # this should be only in the kernel or in one of the known IOKit drivers for the specific kernel
                handler = notifier.handler

                good = common.is_known_address(handler, kernel_symbol_addresses, kmods)
                yield (good, key, notifier, matches)
예제 #4
0
    def check_filter(self, context, fname, ptr, kernel_symbol_addresses, kmods):
        if ptr == None:
            return

        # change the last paramter to 1 to get messages about which good modules hooks were found in
        good = common.is_known_address(ptr, kernel_symbol_addresses, kmods) 

        return (good, context, fname, ptr)
예제 #5
0
    def calculate(self):
        common.set_plugin_members(self)
            
        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)
    
        sysctl_children_addr = self.get_profile_symbol("_sysctl__children")

        sysctl_list = obj.Object("sysctl_oid_list", offset = sysctl_children_addr, vm = self.addr_space)

        for (sysctl, name, val) in self._process_sysctl_list(sysctl_list):
            is_known = common.is_known_address(sysctl.oid_handler, kernel_symbol_addresses, kmods)
            yield (sysctl, name, val, is_known)
예제 #6
0
    def calculate(self):
        common.set_plugin_members(self)

        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)
        gnotify_addr = common.get_cpp_sym("gNotifications",
                                          self.addr_space.profile)
        p = obj.Object("Pointer", offset=gnotify_addr, vm=self.addr_space)
        gnotifications = p.dereference_as(
            self._struct_or_class("OSDictionary"))

        ents = obj.Object('Array',
                          offset=gnotifications.dictionary,
                          vm=self.addr_space,
                          targetType=self._struct_or_class("dictEntry"),
                          count=gnotifications.count)

        # walk the current set of notifications
        for ent in ents:

            if ent == None:
                continue

            key = str(ent.key.dereference_as(
                self._struct_or_class("OSString")))

            # get the value
            valset = ent.value.dereference_as(
                self._struct_or_class("OSOrderedSet"))

            notifiers_ptrs = obj.Object('Array',
                                        offset=valset.array,
                                        vm=self.addr_space,
                                        targetType='Pointer',
                                        count=valset.count)

            for ptr in notifiers_ptrs:
                notifier = ptr.dereference_as(
                    self._struct_or_class("_IOServiceNotifier"))

                if notifier == None:
                    continue

                matches = self.get_matching(notifier)

                # this is the function that handles whatever the notification is for
                # this should be only in the kernel or in one of the known IOKit
                # drivers for the specific kernel
                handler = notifier.handler

                good = common.is_known_address(handler,
                                               kernel_symbol_addresses, kmods)
                yield (good, key, notifier, matches)
예제 #7
0
    def calculate(self):
        common.set_plugin_members(self)

        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        sysctl_children_addr = self.get_profile_symbol("_sysctl__children")

        sysctl_list = obj.Object("sysctl_oid_list",
                                 offset=sysctl_children_addr,
                                 vm=self.addr_space)

        for (sysctl, name, val) in self._process_sysctl_list(sysctl_list):
            is_known = common.is_known_address(sysctl.oid_handler,
                                               kernel_symbol_addresses, kmods)
            yield (sysctl, name, val, is_known)
예제 #8
0
    def calculate(self):
        common.set_plugin_members(self)

        # get all the members of 'mac_policy_ops' so that we can check them (they are all function ptrs)
        ops_members = self.get_members()

        # get the symbols need to check for if rootkit or not
        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        list_addr = self.get_profile_symbol("_mac_policy_list")

        plist = obj.Object("mac_policy_list",
                           offset=list_addr,
                           vm=self.addr_space)
        parray = obj.Object('Array',
                            offset=plist.entries,
                            vm=self.addr_space,
                            targetType='mac_policy_list_element',
                            count=plist.maxindex + 1)

        for ent in parray:
            # I don't know how this can happen, but the kernel makes this check all over the place
            # the policy is useful without any ops so a rootkit can't abuse this
            if ent.mpc == None:
                continue

            name = ent.mpc.mpc_name.dereference()

            ops = obj.Object("mac_policy_ops",
                             offset=ent.mpc.mpc_ops,
                             vm=self.addr_space)

            # walk each member of the struct
            for check in ops_members:
                ptr = ops.__getattr__(check)

                if ptr != 0:
                    # make the last parameter 1 to see the names of known modules that load policies
                    good = common.is_known_address(ptr,
                                                   kernel_symbol_addresses,
                                                   kmods, 0)

                    yield (good, check, name, ptr)
예제 #9
0
    def calculate(self):
        common.set_plugin_members(self)

        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        sysctl_children_addr = self.addr_space.profile.get_symbol("_sysctl__children")

        sysctl_list = obj.Object("sysctl_oid_list", offset=sysctl_children_addr, vm=self.addr_space)

        for (sysctl, name, val) in self._process_sysctl_list(sysctl_list):
            if val == "INVALID -1":
                continue

            is_known = common.is_known_address(sysctl.oid_handler, kernel_symbol_addresses, kmods)

            if is_known:
                status = "OK"
            else:
                status = "UNKNOWN"

            yield (sysctl, name, val, is_known, status)