Beispiel #1
0
    def var_find(self):
        _vars = self._uefi.list_EFI_variables()
        if _vars is None:
            self.logger.log_warning( 'Could not enumerate UEFI variables (non-UEFI OS?)' )
            return
        is_guid = 0
        try:
            _input_var = str(uuid.UUID(self.name_guid))
            is_guid = 1
        except ValueError:
            _input_var = self.name_guid

        if is_guid:
            self.logger.log( "[*] Searching for UEFI variable with GUID {{{}}}..".format(_input_var) )
            for name in _vars:
                n = 0
                for (off, buf, hdr, data, guid, attrs) in _vars[name]:
                    if _input_var == guid:
                        var_fname = '{}_{}_{}_{:d}.bin'.format(name, guid, get_attr_string(attrs).strip(), n)
                        self.logger.log_good( "Found UEFI variable {}:{}. Dumped to '{}'".format(guid, name, var_fname) )
                        write_file( var_fname, data )
                    n += 1
        else:
            self.logger.log( "[*] Searching for UEFI variable with name {}..".format(_input_var) )
            name = _input_var
            if name in list(_vars.keys()):
                n = 0
                for (off, buf, hdr, data, guid, attrs) in _vars[name]:
                    var_fname = '{}_{}_{}_{:d}.bin'.format(name, guid, get_attr_string(attrs).strip(), n)
                    self.logger.log_good( "Found UEFI variable {}:{}. Dumped to '{}'".format(guid, name, var_fname) )
                    write_file( var_fname, data )
                    n += 1
Beispiel #2
0
    def check_vars(self, do_modify):
        res = ModuleResult.PASSED
        vars = self._uefi.list_EFI_variables()
        if vars is None:
            self.logger.log_warning(
                'Could not enumerate UEFI Variables from runtime.')
            self.logger.log_important(
                "Note that UEFI variables may still exist, OS just did not expose runtime UEFI Variable API to read them.\nYou can extract variables directly from ROM file via 'chipsec_util.py uefi nvram bios.bin' command and verify their attributes manually."
            )
            return ModuleResult.SKIPPED

        uefispec_concern = []
        ro_concern = []
        rw_variables = []

        self.logger.log('[*] Testing UEFI variables ..')
        for name in vars.keys():
            if name is None: pass
            if vars[name] is None:
                pass

            if len(vars[name]) > 1:
                self.logger.log_important(
                    'Found two instances of the variable {}.'.format(name))
            for (off, buf, hdr, data, guid, attrs) in vars[name]:
                self.logger.log('[*] Variable {} ({})'.format(
                    name, get_attr_string(attrs)))
                perms = self.uefispec_vars.get(name)
                if perms is not None:
                    if perms != attrs:
                        attr_diffs = (perms ^ attrs)
                        extra_attr = attr_diffs & attrs
                        missing_attr = attr_diffs & ~extra_attr
                        uefispec_concern.append(name)
                        if extra_attr != 0:
                            self.logger.log_important(
                                '  Extra attributes:' +
                                get_attr_string(extra_attr))
                            if (extra_attr & ~(
                                    EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
                                    EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
                                    | EFI_VARIABLE_APPEND_WRITE) != 0):
                                res = ModuleResult.FAILED
                        if missing_attr != 0:
                            self.logger.log_important(
                                '  Missing attributes:' +
                                get_attr_string(missing_attr))
                        if res != ModuleResult.FAILED:
                            res = ModuleResult.WARNING

                if do_modify:
                    self.logger.log(
                        "[*] Testing modification of {} ..".format(name))
                    if name in self.uefispec_ro_vars:
                        if self.can_modify(name, guid, data):
                            ro_concern.append(name)
                            self.logger.log_bad(
                                "Variable {} should be read only.".format(
                                    name))
                            res = ModuleResult.FAILED
                    else:
                        if self.can_modify(name, guid, data):
                            rw_variables.append(name)

        if uefispec_concern:
            self.logger.log('')
            self.logger.log_bad(
                'Variables with attributes that differ from UEFI spec:')
            for name in uefispec_concern:
                self.logger.log('    {}'.format(name))

        if do_modify:
            if ro_concern:
                self.logger.log('')
                self.logger.log_bad(
                    'Variables that should have been read-only and were not:')
                for name in ro_concern:
                    self.logger.log('    {}'.format(name))

            if rw_variables:
                self.logger.log('')
                self.logger.log_unknown(
                    'Variables that are read-write (manual investigation is required):'
                )
                for name in rw_variables:
                    self.logger.log('    {}'.format(name))

        self.logger.log('')

        if ModuleResult.PASSED == res:
            self.logger.log_passed(
                'All checked EFI variables are protected according to spec.')
        elif ModuleResult.FAILED == res:
            self.logger.log_failed(
                'Some EFI variables were not protected according to spec.')
        return res