コード例 #1
0
    def _generator(self):
        kernel = self.context.modules[self.config['kernel']]
        filter_func = pslist.PsList.create_pid_filter(
            self.config.get('pid', None))

        # Collect all the values as we will want to group them later
        sessions = {}

        for proc in pslist.PsList.list_processes(self.context,
                                                 kernel.layer_name,
                                                 kernel.symbol_table_name,
                                                 filter_func=filter_func):

            session_id = proc.get_session_id()

            # Detect RDP, Console or set default value
            session_type = renderers.NotAvailableValue()

            # Construct Username from Process Env
            user_domain = ''
            user_name = ''

            for var, val in proc.environment_variables():
                if var.lower() == 'username':
                    user_name = val
                elif var.lower() == 'userdomain':
                    user_domain = val
                if var.lower() == 'sessionname':
                    session_type = val

            # Concat Domain and User
            full_user = f'{user_domain}/{user_name}'
            if full_user == '/':
                full_user = renderers.NotAvailableValue()

            # Collect all the values in to a row we can yield after sorting.
            row = {
                "session_id": session_id,
                "process_id": proc.UniqueProcessId,
                "process_name": utility.array_to_string(proc.ImageFileName),
                "user_name": full_user,
                "process_start": proc.get_create_time(),
                "session_type": session_type
            }

            # Add row to correct session so we can sort it later
            if session_id in sessions:
                sessions[session_id].append(row)
            else:
                sessions[session_id] = [row]

        # Group and yield each row
        for rows in sessions.values():
            for row in rows:
                yield 0, (row.get('session_id'), row.get('session_type'),
                          row.get('process_id'), row.get('process_name'),
                          row.get('user_name'), row.get('process_start'))
コード例 #2
0
ファイル: hashdump.py プロジェクト: japhlange/volatility3
    def _generator(self, syshive: registry.RegistryHive, samhive: registry.RegistryHive):
        if syshive is None:
            vollog.debug("SYSTEM address is None: Did you use the correct profile?")
            yield (0, (renderers.NotAvailableValue(), renderers.NotAvailableValue(), renderers.NotAvailableValue(),
                       renderers.NotAvailableValue()))
        if samhive is None:
            vollog.debug("SAM address is None: Did you use the correct profile?")
            yield (0, (renderers.NotAvailableValue(), renderers.NotAvailableValue(), renderers.NotAvailableValue(),
                       renderers.NotAvailableValue()))
        bootkey = self.get_bootkey(syshive)
        hbootkey = self.get_hbootkey(samhive, bootkey)
        if hbootkey:
            for user in self.get_user_keys(samhive):
                ret = self.get_user_hashes(user, samhive, hbootkey)
                if ret:
                    lmhash, nthash = ret

                    ## temporary fix to prevent UnicodeDecodeError backtraces
                    ## however this can cause truncated user names as a result
                    name = self.get_user_name(user, samhive)
                    if name is None:
                        name = renderers.NotAvailableValue()
                    else:
                        name = str(name, 'utf-16-le', errors = 'ignore')

                    lmout = str(binascii.hexlify(lmhash or self.empty_lm), 'latin-1')
                    ntout = str(binascii.hexlify(nthash or self.empty_nt), 'latin-1')
                    rid = int(str(user.get_name()), 16)
                    yield (0, (name, rid, lmout, ntout))
        else:
            vollog.warning("Hbootkey is not valid")
コード例 #3
0
 def parse_data(self, data: bytes) -> Tuple[str, bytes]:
     name = renderers.NotAvailableValue()
     certificate_data = renderers.NotAvailableValue()
     while len(data) > 12:
         ctype, clength = struct.unpack("<QI", data[0:12])
         cvalue, data = data[12:12 + clength], data[12 + clength:]
         if ctype == 0x10000000b:
             name = str(cvalue, 'utf-16').strip("\x00")
         elif ctype == 0x100000020:
             certificate_data = cvalue
     return (name, certificate_data)
コード例 #4
0
    def _generator(self):

        kernel = self.context.modules[self.config['kernel']]

        callback_table_name = self.create_callback_table(
            self.context, kernel.symbol_table_name, self.config_path)

        collection = ssdt.SSDT.build_module_collection(
            self.context, kernel.layer_name, kernel.symbol_table_name)

        callback_methods = (self.list_notify_routines,
                            self.list_bugcheck_callbacks,
                            self.list_bugcheck_reason_callbacks,
                            self.list_registry_callbacks)

        for callback_method in callback_methods:
            for callback_type, callback_address, callback_detail in callback_method(
                    self.context, kernel.layer_name, kernel.symbol_table_name,
                    callback_table_name):

                if callback_detail is None:
                    detail = renderers.NotApplicableValue()
                else:
                    detail = callback_detail

                module_symbols = list(
                    collection.get_module_symbols_by_absolute_location(
                        callback_address))

                if module_symbols:
                    for module_name, symbol_generator in module_symbols:
                        symbols_found = False

                        # we might have multiple symbols pointing to the same location
                        for symbol in symbol_generator:
                            symbols_found = True
                            yield (0,
                                   (callback_type,
                                    format_hints.Hex(callback_address),
                                    module_name,
                                    symbol.split(constants.BANG)[1], detail))

                        # no symbols, but we at least can report the module name
                        if not symbols_found:
                            yield (0, (callback_type,
                                       format_hints.Hex(callback_address),
                                       module_name,
                                       renderers.NotAvailableValue(), detail))
                else:
                    # no module was found at the absolute location
                    yield (0, (callback_type,
                               format_hints.Hex(callback_address),
                               renderers.NotAvailableValue(),
                               renderers.NotAvailableValue(), detail))
コード例 #5
0
def find_sid_re(
        sid_string,
        sid_re_list) -> Union[str, interfaces.renderers.BaseAbsentValue]:
    for reg, name in sid_re_list:
        if reg.search(sid_string):
            return name
    return renderers.NotAvailableValue()
コード例 #6
0
    def _generator(self):
        kernel = self.context.modules[self.config['kernel']]

        collection = ssdt.SSDT.build_module_collection(self.context, kernel.layer_name, kernel.symbol_table_name)

        for driver in driverscan.DriverScan.scan_drivers(self.context, kernel.layer_name, kernel.symbol_table_name):

            try:
                driver_name = driver.get_driver_name()
            except (ValueError, exceptions.InvalidAddressException):
                driver_name = renderers.NotApplicableValue()

            for i, address in enumerate(driver.MajorFunction):
                module_symbols = collection.get_module_symbols_by_absolute_location(address)

                for module_name, symbol_generator in module_symbols:
                    symbols_found = False

                    for symbol in symbol_generator:
                        symbols_found = True
                        yield (0, (format_hints.Hex(driver.vol.offset), driver_name, MAJOR_FUNCTIONS[i],
                                   format_hints.Hex(address), module_name, symbol.split(constants.BANG)[1]))

                    if not symbols_found:
                        yield (0, (format_hints.Hex(driver.vol.offset), driver_name, MAJOR_FUNCTIONS[i],
                                   format_hints.Hex(address), module_name, renderers.NotAvailableValue()))
コード例 #7
0
ファイル: isfinfo.py プロジェクト: japhlange/volatility3
 def _get_banner(self, clazz: Type[symbol_cache.SymbolBannerCache],
                 data: Any) -> str:
     """Gets a banner from an ISF file"""
     banner_symbol = data.get('symbols',
                              {}).get(clazz.symbol_name,
                                      {}).get('constant_data',
                                              renderers.NotAvailableValue())
     if not isinstance(banner_symbol, interfaces.renderers.BaseAbsentValue):
         banner_symbol = str(base64.b64decode(banner_symbol),
                             encoding='latin-1')
     return banner_symbol
コード例 #8
0
ファイル: isfinfo.py プロジェクト: japhlange/volatility3
    def _generator(self):
        if self.config.get('isf', None) is not None:
            file_list = [self.config['isf']]
        else:
            file_list = list(self.list_all_isf_files())

        # Filter the files
        filtered_list = []
        if not len(self.config['filter']):
            filtered_list = file_list
        else:
            for isf_file in file_list:
                for filter_item in self.config['filter']:
                    if filter_item in isf_file:
                        filtered_list.append(isf_file)

        try:
            import jsonschema
            if not self.config['validate']:
                raise ImportError  # Act as if we couldn't import if validation is turned off

            def check_valid(data):
                return "True" if schemas.validate(data, True) else "False"
        except ImportError:

            def check_valid(data):
                return "Unknown"

        # Process the filtered list
        for entry in filtered_list:
            num_types = num_enums = num_bases = num_symbols = 0
            windows_info = linux_banner = mac_banner = renderers.NotAvailableValue(
            )
            valid = "Unknown"
            with resources.ResourceAccessor().open(url=entry) as fp:
                try:
                    data = json.load(fp)
                    num_symbols = len(data.get('symbols', []))
                    num_types = len(data.get('user_types', []))
                    num_enums = len(data.get('enums', []))
                    num_bases = len(data.get('base_types', []))

                    linux_banner = self._get_banner(linux.LinuxBannerCache,
                                                    data)
                    mac_banner = self._get_banner(mac.MacBannerCache, data)
                    if not linux_banner and not mac_banner:
                        windows_info = os.path.splitext(
                            os.path.basename(entry))[0]
                    valid = check_valid(data)
                except (UnicodeDecodeError, json.decoder.JSONDecodeError):
                    vollog.warning("Invalid ISF: {}".format(entry))
            yield (0, (entry, valid, num_bases, num_types, num_symbols,
                       num_enums, windows_info, linux_banner, mac_banner))
コード例 #9
0
ファイル: ssdt.py プロジェクト: japhlange/volatility3
    def _generator(self) -> Iterator[Tuple[int, Tuple[int, int, Any, Any]]]:

        layer_name = self.config['primary']
        collection = self.build_module_collection(self.context, self.config["primary"], self.config["nt_symbols"])

        kvo = self.context.layers[layer_name].config['kernel_virtual_offset']
        ntkrnlmp = self.context.module(self.config["nt_symbols"], layer_name = layer_name, offset = kvo)

        # this is just one way to enumerate the native (NT) service table.
        # to do the same thing for the Win32K service table, we would need Win32K.sys symbol support
        ## we could also find nt!KeServiceDescriptorTable (NT) and KeServiceDescriptorTableShadow (NT, Win32K)
        service_table_address = ntkrnlmp.get_symbol("KiServiceTable").address
        service_limit_address = ntkrnlmp.get_symbol("KiServiceLimit").address
        service_limit = ntkrnlmp.object(object_type = "int", offset = service_limit_address)

        # on 32-bit systems the table indexes are 32-bits and contain pointers (unsigned)
        # on 64-bit systems the indexes are also 32-bits but they're offsets from the
        # base address of the table and can be negative, so we need a signed data type
        is_kernel_64 = symbols.symbol_table_is_64bit(self.context, self.config["nt_symbols"])
        if is_kernel_64:
            array_subtype = "long"

            def kvo_calulator(func: int) -> int:
                return kvo + service_table_address + (func >> 4)

            find_address = kvo_calulator
        else:
            array_subtype = "unsigned long"

            def passthrough(func: int) -> int:
                return func

            find_address = passthrough

        functions = ntkrnlmp.object(object_type = "array",
                                    offset = service_table_address,
                                    subtype = ntkrnlmp.get_type(array_subtype),
                                    count = service_limit)

        for idx, function_obj in enumerate(functions):

            function = find_address(function_obj)
            module_symbols = collection.get_module_symbols_by_absolute_location(function)

            for module_name, symbol_generator in module_symbols:
                symbols_found = False

                for symbol in symbol_generator:
                    symbols_found = True
                    yield (0, (idx, format_hints.Hex(function), module_name, symbol.split(constants.BANG)[1]))

                if not symbols_found:
                    yield (0, (idx, format_hints.Hex(function), module_name, renderers.NotAvailableValue()))
コード例 #10
0
    def _generator(self, procs):
        pe_table_name = intermed.IntermediateSymbolTable.create(
            self.context,
            self.config_path,
            "windows",
            "pe",
            class_types=pe.class_types)

        kernel = self.context.modules[self.config['kernel']]

        kuser = info.Info.get_kuser_structure(self.context, kernel.layer_name,
                                              kernel.symbol_table_name)
        nt_major_version = int(kuser.NtMajorVersion)
        nt_minor_version = int(kuser.NtMinorVersion)
        # LoadTime only applies to versions higher or equal to Window 7 (6.1 and higher)
        dll_load_time_field = (nt_major_version > 6) or (
            nt_major_version == 6 and nt_minor_version >= 1)
        for proc in procs:

            proc_id = proc.UniqueProcessId
            proc_layer_name = proc.add_process_layer()

            for entry in proc.load_order_modules():

                BaseDllName = FullDllName = renderers.UnreadableValue()
                try:
                    BaseDllName = entry.BaseDllName.get_string()
                    # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName
                    FullDllName = entry.FullDllName.get_string()
                except exceptions.InvalidAddressException:
                    pass

                if dll_load_time_field:
                    # Versions prior to 6.1 won't have the LoadTime attribute
                    # and 32bit version shouldn't have the Quadpart according to MSDN
                    try:
                        DllLoadTime = conversion.wintime_to_datetime(
                            entry.LoadTime.QuadPart)
                    except exceptions.InvalidAddressException:
                        DllLoadTime = renderers.UnreadableValue()
                else:
                    DllLoadTime = renderers.NotApplicableValue()

                file_output = "Disabled"
                if self.config['dump']:
                    file_handle = self.dump_pe(self.context,
                                               pe_table_name,
                                               entry,
                                               self.open,
                                               proc_layer_name,
                                               prefix=f"pid.{proc_id}.")
                    file_output = "Error outputting file"
                    if file_handle:
                        file_handle.close()
                        file_output = file_handle.preferred_filename

                try:
                    dllbase = format_hints.Hex(entry.DllBase)
                except exceptions.InvalidAddressException:
                    dllbase = renderers.NotAvailableValue()

                try:
                    size_of_image = format_hints.Hex(entry.SizeOfImage)
                except exceptions.InvalidAddressException:
                    size_of_image = renderers.NotAvailableValue()

                yield (0, (proc.UniqueProcessId,
                           proc.ImageFileName.cast(
                               "string",
                               max_length=proc.ImageFileName.vol.count,
                               errors='replace'), dllbase, size_of_image,
                           BaseDllName, FullDllName, DllLoadTime, file_output))