Ejemplo n.º 1
0
    def find_aslr(cls,
                  context: interfaces.context.ContextInterface,
                  symbol_table: str,
                  layer_name: str,
                  progress_callback: constants.ProgressCallback = None) \
            -> Tuple[int, int]:
        """Determines the offset of the actual DTB in physical space and its
        symbol offset."""
        init_task_symbol = symbol_table + constants.BANG + 'init_task'
        init_task_json_address = context.symbol_space.get_symbol(
            init_task_symbol).address
        swapper_signature = rb"swapper(\/0|\x00\x00)\x00\x00\x00\x00\x00\x00"
        module = context.module(symbol_table, layer_name, 0)
        address_mask = context.symbol_space[symbol_table].config.get(
            'symbol_mask', None)

        task_symbol = module.get_type('task_struct')
        comm_child_offset = task_symbol.relative_child_offset('comm')

        for offset in context.layers[layer_name].scan(
                scanner=scanners.RegExScanner(swapper_signature),
                context=context,
                progress_callback=progress_callback):
            init_task_address = offset - comm_child_offset
            init_task = module.object(object_type='task_struct',
                                      offset=init_task_address,
                                      absolute=True)
            if init_task.pid != 0:
                continue
            elif init_task.has_member(
                    'state') and init_task.state.cast('unsigned int') != 0:
                continue

            # This we get for free
            aslr_shift = init_task.files.cast(
                'long unsigned int') - module.get_symbol('init_files').address
            kaslr_shift = init_task_address - cls.virtual_to_physical_address(
                init_task_json_address)
            if address_mask:
                aslr_shift = aslr_shift & address_mask

            if aslr_shift & 0xfff != 0 or kaslr_shift & 0xfff != 0:
                continue
            vollog.debug(
                "Linux ASLR shift values determined: physical {:0x} virtual {:0x}"
                .format(kaslr_shift, aslr_shift))
            return kaslr_shift, aslr_shift

        # We don't throw an exception, because we may legitimately not have an ASLR shift, but we report it
        vollog.debug(
            "Scanners could not determine any ASLR shifts, using 0 for both")
        return 0, 0
Ejemplo n.º 2
0
    def _scan_generator(cls, context, layer_name, progress_callback):
        darwin_signature = rb"Darwin Kernel Version \d{1,3}\.\d{1,3}\.\d{1,3}: [^\x00]+\x00"

        for offset in context.layers[layer_name].scan(scanner = scanners.RegExScanner(darwin_signature),
                                                      context = context,
                                                      progress_callback = progress_callback):

            banner = context.layers[layer_name].read(offset, 128)

            idx = banner.find(b"\x00")
            if idx != -1:
                banner = banner[:idx]

            yield offset, banner
Ejemplo n.º 3
0
 def scan_generator(cls,
                    context,
                    layer,
                    progress_callback,
                    signature=LINUX_VERSION_REGEX):
     # borrowed this approach from the automagic mac version scanner
     for offset in layer.scan(scanner=scanners.RegExScanner(signature),
                              context=context,
                              progress_callback=progress_callback):
         banner_data = layer.read(offset, cls.MAX_KERNEL_BANNER_LEN)
         if banner_data.find(b'\n\x00') == -1:
             banner = None
         else:
             banner = banner_data[:banner_data.find(b'\n\x00')]
         yield offset, banner
Ejemplo n.º 4
0
 def locate_banners(cls, context: interfaces.context.ContextInterface,
                    layer_name: str):
     """Identifies banners from a memory image"""
     layer = context.layers[layer_name]
     for offset in layer.scan(
             context=context,
             scanner=scanners.RegExScanner(
                 rb"(Linux version|Darwin Kernel Version) [0-9]+\.[0-9]+\.[0-9]+"
             )):
         data = layer.read(offset, 0xfff)
         data_index = data.find(b'\x00')
         if data_index > 0:
             data = data[:data_index].strip()
             failed = [
                 char for char in data if char not in
                 b' #()+,;/-.0123456789:@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~'
             ]
             if not failed:
                 yield format_hints.Hex(offset), str(data,
                                                     encoding='latin-1',
                                                     errors='?')