示例#1
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        hook_names = ["PRE_ROUTING", "LOCAL_IN", "FORWARD", "LOCAL_OUT", "POST_ROUTING"]
        proto_names = ["", "", "IPV4", "", "", "", "", "", "", "", "" , "", "", ""]

        # struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]
        # NFPROTO_NUMPROTO = 12
        # NF_MAX_HOOKS = 7
     
        nf_hooks_addr = self.addr_space.profile.get_symbol("nf_hooks")

        if nf_hooks_addr == None:
            debug.error("Unable to analyze NetFilter. It is either disabled or compiled as a module.")

        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()
         
        list_head_size = self.addr_space.profile.get_obj_size("list_head")
        
        for outer in range(13):
            arr = nf_hooks_addr + (outer * (list_head_size * 8))
           
            for inner in range(7):
                list_head = obj.Object("list_head", offset = arr + (inner * list_head_size), vm = self.addr_space)
        
                for hook_ops in list_head.list_of_type("nf_hook_ops", "list"):
                    if self.is_known_address(hook_ops.hook.v(), modules):
                        hooked = "False"
                    else:
                        hooked = "True"

                    yield proto_names[outer], hook_names[inner], hook_ops.hook.v(), hooked
示例#2
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        hook_names = ["PRE_ROUTING", "LOCAL_IN", "FORWARD", "LOCAL_OUT", "POST_ROUTING"]
        proto_names = ["", "", "IPV4", "", "", "", "", "", "", "", "" , "", "", ""]

        # struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]
        # NFPROTO_NUMPROTO = 12
        # NF_MAX_HOOKS = 7
     
        nf_hooks_addr = self.addr_space.profile.get_symbol("nf_hooks")

        if nf_hooks_addr == None:
            debug.error("Unable to analyze NetFilter. It is either disabled or compiled as a module.")

        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()
         
        list_head_size = self.addr_space.profile.get_obj_size("list_head")
        
        for outer in range(13):
            arr = nf_hooks_addr + (outer * (list_head_size * 8))
           
            for inner in range(7):
                list_head = obj.Object("list_head", offset = arr + (inner * list_head_size), vm = self.addr_space)
        
                for hook_ops in list_head.list_of_type("nf_hook_ops", "list"):
                    if self.is_known_address(hook_ops.hook.v(), modules):
                        hooked = "False"
                    else:
                        hooked = "True"

                    yield proto_names[outer], hook_names[inner], hook_ops.hook.v(), hooked
示例#3
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        
        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()
        op_members  = self.profile.types['file_operations'].keywords["members"].keys()
        seq_members = self.profile.types['seq_operations'].keywords["members"].keys()       

        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 proto in protocols:
            
            struct_type = proto[0]

            for global_var_name in proto[1]:
                
                global_var_addr = self.addr_space.profile.get_symbol(global_var_name)

                if not global_var_addr:
                    continue

                global_var = obj.Object(struct_type, offset = global_var_addr, vm = self.addr_space)

                for (name, member, address) in self.check_afinfo(global_var_name, global_var, op_members, seq_members, modules):
                    yield (name, member, address)
示例#4
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        modules = linux_lsmod.linux_lsmod(self._config).get_modules()

        f_op_members = self.profile.types['file_operations'].keywords[
            "members"].keys()
        f_op_members.remove('owner')

        if self._config.INODE:
            inode = obj.Object("inode",
                               offset=self._config.INODE,
                               vm=self.addr_space)
            if not inode.is_valid():
                debug.error(
                    "Invalid inode address given. Please use linux_find_file to determine valid inode addresses."
                )

            for (hooked_member,
                 hook_address) in self.verify_ops(inode.i_fop, f_op_members,
                                                  modules):
                yield ("inode at {0:x}".format(inode.obj_offset),
                       hooked_member, hook_address)

        else:
            funcs = [
                self.check_open_files_fop, self.check_proc_fop,
                self.check_proc_root_fops
            ]

            for func in funcs:

                for (name, member, address) in func(f_op_members, modules):
                    yield (name, member, address)
示例#5
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        
        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()
        op_members  = self.profile.types['file_operations'].keywords["members"].keys()
        seq_members = self.profile.types['seq_operations'].keywords["members"].keys()       

        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 proto in protocols:
            
            struct_type = proto[0]

            for global_var_name in proto[1]:
                
                global_var_addr = self.addr_space.profile.get_symbol(global_var_name)

                if not global_var_addr:
                    continue

                global_var = obj.Object(struct_type, offset = global_var_addr, vm = self.addr_space)

                for (name, member, address) in self.check_afinfo(global_var_name, global_var, op_members, seq_members, modules):
                    yield (name, member, address)
示例#6
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        modules = linux_lsmod.linux_lsmod(self._config).get_modules()

        f_op_members = self.profile.types["file_operations"].keywords["members"].keys()
        f_op_members.remove("owner")

        if self._config.INODE:
            inode = obj.Object("inode", offset=self._config.INODE, vm=self.addr_space)
            if not inode.is_valid():
                debug.error(
                    "Invalid inode address given. Please use linux_find_file to determine valid inode addresses."
                )

            for (hooked_member, hook_address) in self.verify_ops(inode.i_fop, f_op_members, modules):
                yield ("inode at {0:x}".format(inode.obj_offset), hooked_member, hook_address)

        else:
            funcs = [self.check_open_files_fop, self.check_proc_fop, self.check_proc_root_fops, self.check_file_cache]

            for func in funcs:

                for (name, member, address) in func(f_op_members, modules):
                    yield (name, member, address)
示例#7
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()]

        min_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_min"), vm = addr_space)
        max_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_max"), vm = addr_space)

        min_addr = min_addr_sym & ~0xfff
        max_addr = (max_addr_sym & ~0xfff) + 0x1000
        
        scan_buf = ""
        llen = max_addr - min_addr
        
        allfs = "\xff" * 4096 
        
        memory_model = self.addr_space.profile.metadata.get('memory_model', '32bit')
        if memory_model == '32bit':
            minus_size = 4
        else:
            minus_size = 8
 
        check_bufs = []
        replace_bufs = []
        
        check_nums = [3000, 2800, 2700, 2500, 2300, 2100, 2000, 1500, 1300, 1200, 1024, 512, 256, 128, 96, 64, 48, 32, 24, 16, 12, 9]
        if minus_size == 4:
            check_nums = check_nums + [8, 6, 5]

        for num in check_nums:
            check_bufs.append("\x00" * num)        
            replace_bufs.append(("\xff" * (num-minus_size)) + "\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != "\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer("(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))", scan_buf):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset = mod_addr, vm = addr_space)

            if m.is_valid():
                yield m
示例#8
0
    def get_syscalls(self,
                     index_info=None,
                     get_hidden=False,
                     compute_name=True):
        linux_common.set_plugin_members(self)

        if get_hidden:
            hidden_mods = list(
                linux_hidden_modules.linux_hidden_modules(
                    self._config).calculate())
        else:
            hidden_mods = []

        if compute_name:
            visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()
        else:
            visible_mods = []

        if index_info == None:
            index_info = self._find_and_parse_index_file()

        table_name = self.addr_space.profile.metadata.get(
            'memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType='Array',
                               offset=tableaddr,
                               vm=self.addr_space,
                               targetType='unsigned long',
                               count=tblsz + 1)

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

                idx_name = self._index_name(table_name, index_info, i)

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1
                    sym_name = self._compute_hook_sym_name(
                        visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0
                    sym_name = self.profile.get_symbol_by_address(
                        "kernel", call_addr)

                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name,
                       hooked)
    def calculate(self):
        linux_common.set_plugin_members(self)

        kset_modules = self.get_kset_modules()
        
        lsmod_modules = set([str(module.name) for (module, params, sects) in linux_lsmod.linux_lsmod(self._config).calculate()])
            
        for mod_name in set(kset_modules.keys()).difference(lsmod_modules):
            yield kset_modules[mod_name]
def listModulesLinux():
    modules = set([
        module for (module, params,
                    sects) in linux_lsmod.linux_lsmod(config).calculate()
    ])
    for mod in modules:
        #print (list(mod.obj_vm.get_available_pages()))[-1]
        print mod.name, hex(mod.module_core), hex(mod.module_core +
                                                  mod.core_size)
示例#11
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        kset_modules = self.get_kset_modules()
        
        lsmod_modules = set([str(module.name) for (module, params, sects) in linux_lsmod.linux_lsmod(self._config).calculate()])
            
        for mod_name in set(kset_modules.keys()).difference(lsmod_modules):
            yield kset_modules[mod_name]
示例#12
0
    def calculate(self):
        linux_common.set_plugin_members(self)
       
        if not has_distorm3:
            debug.error("This plugin cannot operate without distrom installed.")

        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()       
 
        funcs = [self._check_known_functions, self._check_file_op_pointers, self._check_afinfo, self._check_inetsw]
        
        for func in funcs:
            for (sym_name, member, hook_type, sym_addr) in func(modules):
                yield (sym_name, member, hook_type, sym_addr)
    def calculate(self):
        linux_common.set_plugin_members(self)
       
        if not has_distorm3:
            debug.error("This plugin cannot operate without distrom installed.")

        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()       
 
        funcs = [self._check_known_functions, self._check_file_op_pointers, self._check_afinfo, self._check_inetsw]
        
        for func in funcs:
            for (sym_name, member, hook_type, sym_addr) in func(modules):
                yield (sym_name, member, hook_type, sym_addr)
示例#14
0
    def get_modules(cls, addr_space):    
        """Enumerate the kernel modules. 

        :param      addr_space | <addrspace.AbstractVirtualAddressSpace>
        
        :returns    <tuple>
        """

        mask = addr_space.address_mask
        config = addr_space.get_config()
        modules = linux_lsmod.linux_lsmod(config).calculate()
        mods = dict((mask(mod[0].module_core), mod[0]) for mod in modules)
        mod_addrs = sorted(mods.keys())
         
        return (mods, mod_addrs)
示例#15
0
    def get_modules(cls, addr_space):
        """Enumerate the kernel modules. 

        :param      addr_space | <addrspace.AbstractVirtualAddressSpace>
        
        :returns    <tuple>
        """

        mask = addr_space.address_mask
        config = addr_space.get_config()
        modules = linux_lsmod.linux_lsmod(config).calculate()
        mods = dict((mask(mod[0].module_core), mod[0]) for mod in modules)
        mod_addrs = sorted(mods.keys())

        return (mods, mod_addrs)
示例#16
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        modules = linux_lsmod.linux_lsmod(self._config).get_modules()
        seq_members = self.profile.types['seq_operations'].keywords[
            "members"].keys()

        if self.addr_space.profile.obj_has_member("tcp_seq_afinfo",
                                                  "seq_fops"):
            func = self._pre_4_18
        else:
            func = self._4_18_plus

        for name, member, address in func(modules, seq_members):
            yield name, member, address
示例#17
0
    def walk_modules_address_space(self, addr_space):
        mods = [
            x[0].obj_offset
            for x in linux_lsmod.linux_lsmod(self._config).calculate()
        ]

        min_addr = obj.Object(
            "unsigned long",
            offset=addr_space.profile.get_symbol("module_addr_min"),
            vm=addr_space)
        max_addr = obj.Object(
            "unsigned long",
            offset=addr_space.profile.get_symbol("module_addr_max"),
            vm=addr_space)

        for cur_addr in range(min_addr, max_addr, 8):
            m = obj.Object("module", offset=cur_addr, vm=addr_space)

            if m.state.v() not in [0, 1, 2]:
                continue

            if m.core_size < 4096 or m.core_size > 1000000:
                continue

            if m.core_text_size < 4096 or m.core_text_size > 1000000:
                continue

            s = self.addr_space.read(m.name.obj_offset, 64)
            if not s:
                continue

            idx = s.find("\x00")

            if idx < 1:
                continue

            name = s[:idx]
            for n in name:
                if not (32 < ord(n) < 127):
                    continue

            if not m.module_core.is_valid():
                continue

            if m.obj_offset not in mods:
                yield m
示例#18
0
    def get_syscalls(self, index_info = None, get_hidden = False, compute_name = True):
        linux_common.set_plugin_members(self)

        if get_hidden:
            hidden_mods = list(linux_hidden_modules.linux_hidden_modules(self._config).calculate())
        else:
            hidden_mods = []    
   
        if compute_name:
            visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()
        else:
            visible_mods = []

        if index_info == None:
            index_info = self._find_and_parse_index_file()

        table_name = self.addr_space.profile.metadata.get('memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType = 'Array', offset = tableaddr, vm = self.addr_space, targetType = 'unsigned long', count = tblsz)

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

                idx_name = self._index_name(table_name, index_info, i)

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1
                    sym_name = self._compute_hook_sym_name(visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0 
                    sym_name = self.profile.get_symbol_by_address("kernel", call_addr)

                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name, hooked)
示例#19
0
    def calculate(self):
        linux_common.set_plugin_members(self)

        modules = linux_lsmod.linux_lsmod(self._config).get_modules()

        tty_addr = self.addr_space.profile.get_symbol("tty_drivers")

        if not tty_addr:
            debug.error("Symbol tty_drivers not found in kernel")

        drivers = obj.Object("list_head", offset=tty_addr, vm=self.addr_space)

        sym_cache = {}

        for tty in drivers.list_of_type("tty_driver", "tty_drivers"):
            name = tty.name.dereference_as(
                "String", length=linux_common.MAX_STRING_LENGTH)

            ttys = obj.Object(
                "Array",
                targetType="Pointer",
                vm=self.addr_space,
                offset=tty.ttys,
                count=tty.num,
            )
            for tty_dev in ttys:
                if tty_dev == 0:
                    continue

                tty_dev = tty_dev.dereference_as("tty_struct")
                name = tty_dev.name
                recv_buf = tty_dev.ldisc.ops.receive_buf

                known = self.is_known_address(recv_buf, modules)

                if not known:
                    sym_name = "HOOKED"
                    hooked = 1
                else:
                    sym_name = self.profile.get_symbol_by_address(
                        "kernel", recv_buf)
                    hooked = 0

                sym_cache[recv_buf] = sym_name

                yield (name, recv_buf, sym_name, hooked)
示例#20
0
    def calculate(self):
        linux_common.set_plugin_members(self)
        
        modules  = linux_lsmod.linux_lsmod(self._config).get_modules()

        tty_addr = self.addr_space.profile.get_symbol("tty_drivers")
        
        if not tty_addr:
            debug.error("Symbol tty_drivers not found in kernel")
                        
        drivers = obj.Object("list_head", offset = tty_addr, vm = self.addr_space)
        
        sym_cache = {}

        for tty in drivers.list_of_type("tty_driver", "tty_drivers"):
            name = tty.name.dereference_as("String", length = linux_common.MAX_STRING_LENGTH)
            
            ttys = obj.Object("Array", targetType = "Pointer", vm = self.addr_space, offset = tty.ttys, count = tty.num)
            for tty_dev in ttys:
                if tty_dev == 0:
                    continue
                
                tty_dev = tty_dev.dereference_as("tty_struct")
                name = tty_dev.name
                recv_buf = tty_dev.ldisc.ops.receive_buf
                
                known = self.is_known_address(recv_buf, modules)

                if not known:
                    sym_name = "HOOKED"
                    hooked = 1
                else:
                    sym_name = self.profile.get_symbol_by_address("kernel", recv_buf)
                    hooked = 0
                
                sym_cache[recv_buf] = sym_name
                
                yield (name, recv_buf, sym_name, hooked)
示例#21
0
    def walk_modules_address_space(self, addr_space):
        mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()]

        min_addr = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_min"), vm = addr_space)
        max_addr = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_max"), vm = addr_space)

        for cur_addr in range(min_addr, max_addr, 8):
            m = obj.Object("module", offset = cur_addr, vm = addr_space)

            if m.state.v() not in [0, 1, 2]:
                continue
 
            if m.core_size < 4096 or m.core_size > 1000000:
                continue

            if m.core_text_size < 4096 or m.core_text_size > 1000000:
                continue
                     
            s = self.addr_space.read(m.name.obj_offset, 64)
            if not s:
                continue

            idx = s.find("\x00")

            if idx < 1:
                continue
    
            name = s[:idx]
            for n in name:
                if not (32 < ord(n) < 127):
                    continue

            if not m.module_core.is_valid():
                continue

            if m.obj_offset not in mods:
                yield m
示例#22
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [
            x[0].obj_offset
            for x in linux_lsmod.linux_lsmod(self._config).calculate()
        ]

        if addr_space.profile.get_symbol("module_addr_min"):
            min_addr_sym = obj.Object(
                "unsigned long",
                offset=addr_space.profile.get_symbol("module_addr_min"),
                vm=addr_space,
            )
            max_addr_sym = obj.Object(
                "unsigned long",
                offset=addr_space.profile.get_symbol("module_addr_max"),
                vm=addr_space,
            )

        elif addr_space.profile.get_symbol("mod_tree"):
            skip_size = addr_space.profile.get_obj_size("latch_tree_root")
            addr = addr_space.profile.get_symbol("mod_tree")
            ulong_size = addr_space.profile.get_obj_size("unsigned long")

            min_addr_sym = obj.Object("unsigned long",
                                      offset=addr + skip_size,
                                      vm=addr_space)
            max_addr_sym = obj.Object(
                "unsigned long",
                offset=addr + skip_size + ulong_size,
                vm=addr_space,
            )
        else:
            debug.error(
                "Unsupport kernel verison. Please file a bug ticket that includes your kernel version and distribution."
            )

        min_addr = min_addr_sym & ~0xFFF
        max_addr = (max_addr_sym & ~0xFFF) + 0x1000

        scan_buf = b""
        llen = max_addr - min_addr

        allfs = b"\xff" * 4096

        memory_model = self.addr_space.profile.metadata.get(
            'memory_model', '32bit')
        if memory_model == '32bit':
            minus_size = 4
        else:
            minus_size = 8

        check_bufs = []
        replace_bufs = []

        check_nums = [
            3000,
            2800,
            2700,
            2500,
            2300,
            2100,
            2000,
            1500,
            1300,
            1200,
            1024,
            512,
            256,
            128,
            96,
            64,
            48,
            32,
            24,
        ]

        for num in check_nums:
            check_bufs.append(b"\x00" * num)
            replace_bufs.append((b"\xff" * (num - minus_size)) +
                                b"\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != b"\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer(
                rb"(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))",
                scan_buf,
        ):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset=mod_addr, vm=addr_space)

            if m.is_valid():
                yield m
示例#23
0
    def modules(self):
        mods = lsmod.linux_lsmod(self._config).calculate()

        for (module, _, __) in mods:
            print "{0:24} {1:d}".format(module.name, module.init_size + module.core_size)
示例#24
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()]

        # this for is for pre-2008 kernels:
        # https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/kernel/module.c?id=3a642e99babe0617febb6f402e1e063479f489db)
        if addr_space.profile.get_symbol("module_addr_min") == None:
            return

        min_addr_sym = obj.Object(
            "unsigned long", offset=addr_space.profile.get_symbol("module_addr_min"), vm=addr_space
        )
        max_addr_sym = obj.Object(
            "unsigned long", offset=addr_space.profile.get_symbol("module_addr_max"), vm=addr_space
        )

        min_addr = min_addr_sym & ~0xFFF
        max_addr = (max_addr_sym & ~0xFFF) + 0x1000

        scan_buf = ""
        llen = max_addr - min_addr

        allfs = "\xff" * 4096

        memory_model = self.addr_space.profile.metadata.get("memory_model", "32bit")
        if memory_model == "32bit":
            minus_size = 4
        else:
            minus_size = 8

        check_bufs = []
        replace_bufs = []

        check_nums = [
            3000,
            2800,
            2700,
            2500,
            2300,
            2100,
            2000,
            1500,
            1300,
            1200,
            1024,
            512,
            256,
            128,
            96,
            64,
            48,
            32,
            24,
        ]

        for num in check_nums:
            check_bufs.append("\x00" * num)
            replace_bufs.append(("\xff" * (num - minus_size)) + "\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != "\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer("(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))", scan_buf):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset=mod_addr, vm=addr_space)

            if m.is_valid():
                yield m
示例#25
0
    def calculate(self):
        """ 
        This works by walking the system call table 
        and verifies that each is a symbol in the kernel
        """
        linux_common.set_plugin_members(self)

        if not has_distorm:
            debug.warning(
                "distorm not installed. The best method to calculate the system call table size will not be used."
            )

        if self._config.SYSCALL_INDEXES:
            if not os.path.exists(self._config.SYSCALL_INDEXES):
                debug.error("Given syscall indexes file does not exist!")

            index_names = {}

            for line in open(self._config.SYSCALL_INDEXES, "r").readlines():
                ents = line.split()
                if len(ents) == 3 and ents[0] == "#define":
                    name = ents[1].replace("__NR_", "")

                    # "(__NR_timer_create+1)"
                    index = ents[2]
                    if index[0] == "(":
                        index = self._find_index(index_names, index)
                    else:
                        index = int(index)

                    index_names[index] = name
        else:
            index_names = None

        hidden_mods = list(
            linux_hidden_modules.linux_hidden_modules(
                self._config).calculate())
        visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()

        table_name = self.addr_space.profile.metadata.get(
            'memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType='Array',
                               offset=tableaddr,
                               vm=self.addr_space,
                               targetType='unsigned long',
                               count=tblsz)

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

                if index_names:
                    idx_name = self._index_name(index_names, i)
                else:
                    idx_name = ""

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1

                    sym_name = self._compute_hook_sym_name(
                        visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0
                    sym_name = self.profile.get_symbol_by_address(
                        "kernel", call_addr)

                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name,
                       hooked)
示例#26
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()]

        # this for is for pre-2008 kernels:
        # https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/kernel/module.c?id=3a642e99babe0617febb6f402e1e063479f489db)
        if addr_space.profile.get_symbol("module_addr_min") == None:
            return

        min_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_min"), vm = addr_space)
        max_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_max"), vm = addr_space)

        min_addr = min_addr_sym & ~0xfff
        max_addr = (max_addr_sym & ~0xfff) + 0x1000
        
        scan_buf = ""
        llen = max_addr - min_addr
        
        allfs = "\xff" * 4096 
        
        memory_model = self.addr_space.profile.metadata.get('memory_model', '32bit')
        if memory_model == '32bit':
            minus_size = 4
        else:
            minus_size = 8
 
        check_bufs = []
        replace_bufs = []
        
        check_nums = [3000, 2800, 2700, 2500, 2300, 2100, 2000, 1500, 1300, 1200, 1024, 512, 256, 128, 96, 64, 48, 32, 24]

        for num in check_nums:
            check_bufs.append("\x00" * num)        
            replace_bufs.append(("\xff" * (num-minus_size)) + "\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != "\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer("(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))", scan_buf):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset = mod_addr, vm = addr_space)

            if m.is_valid():
                yield m
示例#27
0
    def calculate(self):
        """ 
        This works by walking the system call table 
        and verifies that each is a symbol in the kernel
        """
        linux_common.set_plugin_members(self)

        if not has_distorm:
            debug.warning("distorm not installed. The best method to calculate the system call table size will not be used.")
                        
        if self._config.SYSCALL_INDEXES:
            if not os.path.exists(self._config.SYSCALL_INDEXES):
                debug.error("Given syscall indexes file does not exist!")

            index_names = {}

            for line in open(self._config.SYSCALL_INDEXES, "r").readlines():
                ents = line.split()
                if len(ents) == 3 and ents[0] == "#define":
                    name  = ents[1].replace("__NR_", "")

                    # "(__NR_timer_create+1)"
                    index = ents[2] 
                    if index[0] == "(":
                        index = self._find_index(index_names, index)
                    else:
                        index = int(index)
                    
                    index_names[index] = name
        else:
            index_names = None

        hidden_mods = list(linux_hidden_modules.linux_hidden_modules(self._config).calculate())
        visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()

        table_name = self.addr_space.profile.metadata.get('memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType = 'Array', offset = tableaddr, vm = self.addr_space, targetType = 'unsigned long', count = tblsz)

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

                if index_names:
                    idx_name = self._index_name(index_names, i)
                else:
                    idx_name = ""

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1

                    sym_name = self._compute_hook_sym_name(visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0 
                    sym_name = self.profile.get_symbol_by_address("kernel", call_addr)
                
                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name, hooked)
示例#28
0
    def modules(self):
        mods = lsmod.linux_lsmod(self._config).calculate()

        for (module, _, __) in mods:
            print "{0:24} {1:d}".format(module.name, module.init_size + module.core_size)
示例#29
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()]

        if addr_space.profile.get_symbol("module_addr_min"):
            min_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_min"), vm = addr_space)
            max_addr_sym = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_max"), vm = addr_space)
        
        elif addr_space.profile.get_symbol("mod_tree"):
            skip_size    = addr_space.profile.get_obj_size("latch_tree_root")
            addr         = addr_space.profile.get_symbol("mod_tree")
            ulong_size   = addr_space.profile.get_obj_size("unsigned long")

            min_addr_sym = obj.Object("unsigned long", offset = addr + skip_size, vm = addr_space)
            max_addr_sym = obj.Object("unsigned long", offset = addr + skip_size + ulong_size, vm = addr_space)
        else:
            debug.error("Unsupport kernel verison. Please file a bug ticket that includes your kernel version and distribution.")

        min_addr = min_addr_sym & ~0xfff
        max_addr = (max_addr_sym & ~0xfff) + 0x1000
        
        scan_buf = ""
        llen = max_addr - min_addr
        
        allfs = "\xff" * 4096 
        
        memory_model = self.addr_space.profile.metadata.get('memory_model', '32bit')
        if memory_model == '32bit':
            minus_size = 4
        else:
            minus_size = 8
 
        check_bufs = []
        replace_bufs = []
        
        check_nums = [3000, 2800, 2700, 2500, 2300, 2100, 2000, 1500, 1300, 1200, 1024, 512, 256, 128, 96, 64, 48, 32, 24]

        for num in check_nums:
            check_bufs.append("\x00" * num)        
            replace_bufs.append(("\xff" * (num-minus_size)) + "\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != "\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer("(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))", scan_buf):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset = mod_addr, vm = addr_space)

            if m.is_valid():
                yield m
示例#30
0
    def get_syscalls(self, index_lines = None, get_hidden = False):
        linux_common.set_plugin_members(self)

        if get_hidden:
            hidden_mods = list(linux_hidden_modules.linux_hidden_modules(self._config).calculate())
        else:
            hidden_mods = []    
    
        visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()

        if not index_lines:
            index_lines = self._find_and_parse_index_file()

        if index_lines:
            index_names = {}
            for line in index_lines.split("\n"): 
                ents = line.split()

                if len(ents) == 3 and ents[0] == "#define":
                    name  = ents[1].replace("__NR_", "")

                    # "(__NR_timer_create+1)"
                    index = ents[2] 
                    if index[0] == "(":
                        index = self._find_index(index_names, index)
                    else:
                        index = int(index)
        
                    index_names[index] = name
        else:
            index_names = None

        table_name = self.addr_space.profile.metadata.get('memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType = 'Array', offset = tableaddr, vm = self.addr_space, targetType = 'unsigned long', count = tblsz)

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

                if index_names:
                    idx_name = self._index_name(index_names, i)
                else:
                    idx_name = ""

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1

                    sym_name = self._compute_hook_sym_name(visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0 
                    sym_name = self.profile.get_symbol_by_address("kernel", call_addr)

                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name, hooked)
示例#31
0
    def walk_modules_address_space(self, addr_space):
        list_mods = [
            x[0].obj_offset
            for x in linux_lsmod.linux_lsmod(self._config).calculate()
        ]

        min_addr_sym = obj.Object(
            "unsigned long",
            offset=addr_space.profile.get_symbol("module_addr_min"),
            vm=addr_space)
        max_addr_sym = obj.Object(
            "unsigned long",
            offset=addr_space.profile.get_symbol("module_addr_max"),
            vm=addr_space)

        min_addr = min_addr_sym & ~0xfff
        max_addr = (max_addr_sym & ~0xfff) + 0x1000

        scan_buf = ""
        llen = max_addr - min_addr

        allfs = "\xff" * 4096

        memory_model = self.addr_space.profile.metadata.get(
            'memory_model', '32bit')
        if memory_model == '32bit':
            minus_size = 4
        else:
            minus_size = 8

        check_bufs = []
        replace_bufs = []

        check_nums = [
            3000, 2800, 2700, 2500, 2300, 2100, 2000, 1500, 1300, 1200, 1024,
            512, 256, 128, 96, 64, 48, 32, 24, 16, 12, 9
        ]
        if minus_size == 4:
            check_nums = check_nums + [8, 6, 5]

        for num in check_nums:
            check_bufs.append("\x00" * num)
            replace_bufs.append(("\xff" * (num - minus_size)) +
                                "\x00" * minus_size)

        for page in range(min_addr, max_addr, 4096):
            to_append = allfs

            tmp = addr_space.read(page, 4096)
            if tmp:
                non_zero = False
                for t in tmp:
                    if t != "\x00":
                        non_zero = True
                        break

                if non_zero:
                    for i in range(len(check_nums)):
                        tmp = tmp.replace(check_bufs[i], replace_bufs[i])
                    to_append = tmp

            scan_buf = scan_buf + to_append

        for cur_addr in re.finditer(
                "(?=(\x00\x00\x00\x00|\x01\x00\x00\x00|\x02\x00\x00\x00))",
                scan_buf):
            mod_addr = min_addr + cur_addr.start()

            if mod_addr in list_mods:
                continue

            m = obj.Object("module", offset=mod_addr, vm=addr_space)

            if m.is_valid():
                yield m
示例#32
0
    def get_syscalls(self, index_lines=None, get_hidden=False):
        linux_common.set_plugin_members(self)

        if get_hidden:
            hidden_mods = list(
                linux_hidden_modules.linux_hidden_modules(
                    self._config).calculate())
        else:
            hidden_mods = []

        visible_mods = linux_lsmod.linux_lsmod(self._config).calculate()

        if not index_lines:
            index_lines = self._find_and_parse_index_file()

        if index_lines:
            index_names = {}
            for line in index_lines.split("\n"):
                ents = line.split()

                if len(ents) == 3 and ents[0] == "#define":
                    name = ents[1].replace("__NR_", "")

                    # "(__NR_timer_create+1)"
                    index = ents[2]
                    if index[0] == "(":
                        index = self._find_index(index_names, index)
                    else:
                        index = int(index)

                    index_names[index] = name
        else:
            index_names = None

        table_name = self.addr_space.profile.metadata.get(
            'memory_model', '32bit')
        sym_addrs = self.profile.get_all_addresses()
        sys_call_info = self._get_table_info("sys_call_table")
        addrs = [(table_name, sys_call_info)]

        # 64 bit systems with 32 bit emulation
        ia32 = self.addr_space.profile.get_symbol("ia32_sys_call_table")
        if ia32:
            ia32_info = self._get_table_info("ia32_sys_call_table")
            addrs.append(("32bit", ia32_info))

        for (table_name, (tableaddr, tblsz)) in addrs:
            table = obj.Object(theType='Array',
                               offset=tableaddr,
                               vm=self.addr_space,
                               targetType='unsigned long',
                               count=tblsz)

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

                if index_names:
                    idx_name = self._index_name(index_names, i)
                else:
                    idx_name = ""

                call_addr = int(call_addr)

                if not call_addr in sym_addrs:
                    hooked = 1

                    sym_name = self._compute_hook_sym_name(
                        visible_mods, hidden_mods, call_addr)
                else:
                    hooked = 0
                    sym_name = self.profile.get_symbol_by_address(
                        "kernel", call_addr)

                yield (tableaddr, table_name, i, idx_name, call_addr, sym_name,
                       hooked)