Esempio n. 1
0
    def calculate(self):
        common.set_plugin_members(self)

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

        list_addrs = [
            self.addr_space.profile.get_symbol("_ipv4_filters"),
            self.addr_space.profile.get_symbol("_ipv6_filters")
        ]

        for list_addr in list_addrs:
            plist = obj.Object("ipfilter_list",
                               offset=list_addr,
                               vm=self.addr_space)

            # type 'ipfilter'
            cur = plist.tqh_first

            while cur:
                filter = cur.ipf_filter
                name = filter.name.dereference()

                yield self.check_filter("INPUT", name, filter.ipf_input,
                                        kernel_symbol_addresses, kmods)
                yield self.check_filter("OUTPUT", name, filter.ipf_output,
                                        kernel_symbol_addresses, kmods)
                yield self.check_filter("DETACH", name, filter.ipf_detach,
                                        kernel_symbol_addresses, kmods)

                cur = cur.ipf_link.tqe_next
Esempio n. 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)
Esempio n. 3
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.addr_space.profile.get_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.staticmax + 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 isn't 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.v() != 0 and ptr.is_valid():
                    (good, module) = common.is_known_address_name(ptr, kernel_symbol_addresses, kmods) 

                    yield (good, check, module, name, ptr)
Esempio n. 4
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)
Esempio n. 5
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 or not ent.is_valid():
                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.v()

                ch = notifier.compatHandler.v()

                if ch:
                    handler = ch

                (good, module) = common.is_known_address_name(
                    handler, kernel_symbol_addresses, kmods)
                yield (good, module, key, notifier, matches, handler)
Esempio n. 6
0
    def calculate(self):
        common.set_plugin_members(self)

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

        members = [
            "sf_unregistered",
            "sf_attach",
            "sf_detach",
            "sf_notify",
            "sf_getpeername",
            "sf_getsockname",
        ]
        members = members + [
            "sf_data_in",
            "sf_data_out",
            "sf_connect_in",
            "sf_connect_out",
            "sf_bind",
            "sf_setoption",
        ]
        members = members + ["sf_getoption", "sf_listen", "sf_ioctl"]

        sock_filter_head_addr = self.addr_space.profile.get_symbol(
            "_sock_filter_head")

        sock_filter_list = obj.Object(
            "socket_filter_list",
            offset=sock_filter_head_addr,
            vm=self.addr_space,
        )

        cur = sock_filter_list.tqh_first

        while cur:
            filter = cur.sf_filter
            filter_name = self.addr_space.read(filter.sf_name, 256)
            idx = filter_name.index("\x00")
            if idx != -1:
                filter_name = filter_name[:idx]

            filter_socket = cur.sf_entry_head.sfe_socket.obj_offset

            for member in members:
                ptr = filter.m(member)

                if not ptr:
                    continue

                (good, module) = common.is_known_address_name(
                    ptr.v(), kernel_symbol_addresses, kmods)

                yield good, filter, filter_name, filter_socket, member, ptr, module

            cur = cur.sf_global_next.tqe_next
Esempio n. 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)
Esempio n. 8
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)
Esempio n. 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)
Esempio n. 10
0
    def calculate(self):
        common.set_plugin_members(self)
        
        # get the symbols need to check for if rootkit or not
        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        list_addrs = [self.addr_space.profile.get_symbol("_ipv4_filters"), self.addr_space.profile.get_symbol("_ipv6_filters")]
    
        for list_addr in list_addrs:
            plist = obj.Object("ipfilter_list", offset = list_addr, vm = self.addr_space)

            # type 'ipfilter'
            cur = plist.tqh_first

            while cur:
                filter = cur.ipf_filter
                name = filter.name.dereference()
                   
                yield self.check_filter("INPUT", name, filter.ipf_input, kernel_symbol_addresses, kmods)
                yield self.check_filter("OUTPUT", name, filter.ipf_output, kernel_symbol_addresses, kmods)
                yield self.check_filter("DETACH", name, filter.ipf_detach, kernel_symbol_addresses, kmods)
           
                cur = cur.ipf_link.tqe_next
Esempio n. 11
0
    def calculate(self):
        common.set_plugin_members(self)
        
        # get the symbols need to check for if rootkit or not
        (kernel_symbol_addresses, kmods) = common.get_kernel_addrs(self)

        members = ["sf_unregistered", "sf_attach", "sf_detach", "sf_notify", "sf_getpeername", "sf_getsockname"]
        members = members + ["sf_data_in", "sf_data_out", "sf_connect_in", "sf_connect_out", "sf_bind", "sf_setoption"]
        members = members + ["sf_getoption", "sf_listen", "sf_ioctl"]

        sock_filter_head_addr = self.addr_space.profile.get_symbol("_sock_filter_head")
    
        sock_filter_list = obj.Object("socket_filter_list", offset = sock_filter_head_addr, vm = self.addr_space)

        cur = sock_filter_list.tqh_first

        while cur:
            filter = cur.sf_filter
            filter_name = self.addr_space.read(filter.sf_name, 256)
            idx = filter_name.index("\x00")
            if idx != -1:
                filter_name = filter_name[:idx]
               
            filter_socket = cur.sf_entry_head.sfe_socket.obj_offset

            for member in members:
                ptr = filter.m(member)
                
                if not ptr:
                    continue   
 
                (good, module) = common.is_known_address_name(ptr.v(), kernel_symbol_addresses, kmods) 
    
                yield good, filter, filter_name, filter_socket, member, ptr, module
       
            cur = cur.sf_global_next.tqe_next