fixes and new modules (#62)

* compile cores.so with linux driver

* Releasing new modules

added memconfig, common.ia32cfg, common.rtclock, common.spi_fdopss, and
tools.cpu.sinkhole
This commit is contained in:
CHIPSEC
2016-08-12 16:48:02 -07:00
committed by c7zero
parent bd4a0478f3
commit 2213ff7052
6 changed files with 395 additions and 0 deletions
+2
View File
@@ -19,10 +19,12 @@ endif
chipsec64: clean
nasm -f elf64 -o amd64/cpu.o amd64/cpu.asm;
make -C $(KERNEL_SRC_DIR) SUBDIRS=`pwd` modules
make -C ../../tool/chipsec/helper/linux
chipsec32: clean
nasm -f elf32 -o i386/cpu.o i386/cpu.asm;
make -C $(KERNEL_SRC_DIR) SUBDIRS=`pwd` modules
make -C ../../tool/chipsec/helper/linux
install:
./run.sh
@@ -0,0 +1,66 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2016, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
"""
Tests that IA-32/IA-64 architectural features are configured and locked, including IA32 Model Specific Registers (MSRs)
Reference: Intel Software Developer's Manual
"""
from chipsec.module_common import *
TAGS = [MTAG_HWCONFIG]
class ia32cfg(BaseModule):
def __init__(self):
BaseModule.__init__(self)
self.res = ModuleResult.PASSED
def is_supported(self):
if self.cs.is_atom(): return False
else: return True
def check_ia32feature_control(self):
self.logger.start_test( "IA32 Feature Control Lock" )
self.logger.log( "[*] Verifying IA32_Feature_Control MSR is locked on all logical CPUs.." )
ok = True
for tid in range(self.cs.msr.get_cpu_thread_count()):
#feature_cntl = chipsec.chipset.read_register( self.cs, 'IA32_FEATURE_CONTROL', tid )
#chipsec.chipset.print_register( self.cs, 'IA32_FEATURE_CONTROL', feature_cntl )
feature_cntl_lock = chipsec.chipset.get_control( self.cs, 'Ia32FeatureControlLock' )
self.logger.log( "[*] cpu%d: IA32_Feature_Control Lock = %d" % (tid,feature_cntl_lock) )
if 0 == feature_cntl_lock: ok = False
if ok:
self.res = ModuleResult.PASSED
self.logger.log_passed_check( "IA32_FEATURE_CONTROL MSR is locked on all logical CPUs" )
else:
self.res = ModuleResult.FAILED
self.logger.log_failed_check( "IA32_FEATURE_CONTROL MSR is not locked on all logical CPUs" )
return self.res
def run(self, module_argv):
return self.check_ia32feature_control()
@@ -0,0 +1,66 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2016, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
"""
Checks for RTC memory locks. Since we do not know what RTC memory will be used for on a specific platform, we return WARNING (rather than FAILED) if the memory is not locked.
"""
from chipsec.module_common import *
TAGS = [MTAG_BIOS,MTAG_HWCONFIG]
class rtclock(BaseModule):
def __init__(self):
BaseModule.__init__(self)
self.res = ModuleResult.PASSED
def is_supported(self):
return (self.cs.get_chipset_id() in chipsec.chipset.CHIPSET_FAMILY_CORE)
def check_rtclock(self):
self.logger.start_test( "Protected RTC memory locations" )
rc_reg = chipsec.chipset.read_register( self.cs, 'RC' )
chipsec.chipset.print_register( self.cs, 'RC', rc_reg )
ll = chipsec.chipset.get_register_field( self.cs, 'RC', rc_reg, 'LL' )
ul = chipsec.chipset.get_register_field( self.cs, 'RC', rc_reg, 'UL' )
if ll == 1: self.logger.log_good( "Protected bytes (0x38-0x3F) in low 128-byte bank of RTC memory are locked" )
else: self.logger.log_bad( "Protected bytes (0x38-0x3F) in low 128-byte bank of RTC memory are not locked" )
if ul == 1: self.logger.log_good( "Protected bytes (0x38-0x3F) in high 128-byte bank of RTC memory are locked" )
else: self.logger.log_bad( "Protected bytes (0x38-0x3F) in high 128-byte bank of RTC memory are not locked" )
if ll == 1 and ul == 1:
self.res = ModuleResult.PASSED
self.logger.log_passed_check( "Protected locations in RTC memory are locked" )
else:
self.res = ModuleResult.WARNING
self.logger.log_warn_check( "Protected locations in RTC memory are accessible (BIOS may not be using them)" )
return self.res
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
return self.check_rtclock()
@@ -0,0 +1,59 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2016, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
"""
Checks for SPI Controller Flash Descriptor Security Override Pin Strap (FDOPSS). On some systems, this may be routed to a jumper on the motherboard.
"""
from chipsec.module_common import *
TAGS = [MTAG_BIOS]
class spi_fdopss(BaseModule):
def __init__(self):
BaseModule.__init__(self)
def is_supported(self):
return True
def check_fd_security_override_strap(self):
self.logger.start_test( "SPI Flash Descriptor Security Override Pin-Strap" )
if not chipsec.chipset.is_register_defined( self.cs, 'HSFS' ):
self.logger.error( "Couldn't find definition of required configuration registers (HSFS)" )
return ModuleResult.ERROR
hsfs_reg = chipsec.chipset.read_register( self.cs, 'HSFS' )
chipsec.chipset.print_register( self.cs, 'HSFS', hsfs_reg )
fdopss = chipsec.chipset.get_register_field( self.cs, 'HSFS', hsfs_reg, 'FDOPSS' )
if 0 != fdopss:
self.logger.log_passed_check( "SPI Flash Descriptor Security Override is disabled" )
return ModuleResult.PASSED
else:
self.logger.log_failed_check( "SPI Flash Descriptor Security Override is enabled" )
return ModuleResult.FAILED
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
return self.check_fd_security_override_strap()
+96
View File
@@ -0,0 +1,96 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2015, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
"""
This module verifies memory map secure configuration,
i.e. that memory map registers are correctly configured and locked down.
"""
from chipsec.module_common import *
_MODULE_NAME = 'memconfig'
TAGS = [MTAG_HWCONFIG]
memmap_registers = {
"PCI0.0.0_GGC" : 'GGCLOCK',
"PCI0.0.0_PAVPC" : 'PAVPLCK',
"PCI0.0.0_DPR" : 'LOCK',
"PCI0.0.0_MESEG_MASK" : 'MELCK',
"PCI0.0.0_REMAPBASE" : 'LOCK',
"PCI0.0.0_REMAPLIMIT" : 'LOCK',
"PCI0.0.0_TOM" : 'LOCK',
"PCI0.0.0_TOUUD" : 'LOCK',
"PCI0.0.0_BDSM" : 'LOCK',
"PCI0.0.0_BGSM" : 'LOCK',
"PCI0.0.0_TSEGMB" : 'LOCK',
"PCI0.0.0_TOLUD" : 'LOCK'
}
memmap_registers_dev0bars = [
"PCI0.0.0_PXPEPBAR",
"PCI0.0.0_MCHBAR",
"PCI0.0.0_PCIEXBAR",
"PCI0.0.0_DMIBAR",
]
class memconfig(BaseModule):
def __init__(self):
BaseModule.__init__(self)
def is_supported(self):
return self.cs.is_core()
def check_memmap_locks(self):
self.logger.start_test( "Host Bridge Memory Map Locks" )
regs = memmap_registers.keys()
regs.sort()
all_locked = True
for r in regs:
d = chipsec.chipset.get_register_def( self.cs, r )
v = chipsec.chipset.read_register( self.cs, r )
locked = chipsec.chipset.get_register_field( self.cs, r, v, memmap_registers[r] )
if locked == 1:
self.logger.log_good( "%-20s = 0x%016X - LOCKED - %s" % (r, v, d['desc']) )
else:
all_locked = False
self.logger.log_bad( "%-20s = 0x%016X - UNLOCKED - %s" % (r, v, d['desc']) )
if all_locked:
res = ModuleResult.PASSED
self.logger.log_passed_check( "All memory map registers seem to be locked down" )
else:
res = ModuleResult.FAILED
self.logger.log_failed_check( "Not all memory map registers are locked down" )
return res
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
return self.check_memmap_locks()
@@ -0,0 +1,106 @@
#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2016, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
"""
This module checks if CPU is affected by 'The SMM memory sinkhole' vulnerability by Christopher Domas
NOTE: The system may hang when running this test. In that case, the mitigation to this issue is likely working but we may not be handling the exception generated.
References:
The Memory Sinkhole `(presentation) <https://www.blackhat.com/docs/us-15/materials/us-15-Domas-The-Memory-Sinkhole-Unleashing-An-x86-Design-Flaw-Allowing-Universal-Privilege-Escalation.pdf>`_, `(whitepaper) <https://www.blackhat.com/docs/us-15/materials/us-15-Domas-The-Memory-Sinkhole-Unleashing-An-x86-Design-Flaw-Allowing-Universal-Privilege-Escalation-wp.pdf>`_ by Christopher Domas
"""
from chipsec.module_common import *
import chipsec.hal.cpu
import chipsec.helper.oshelper
TAGS = [MTAG_SMM]
class sinkhole(BaseModule):
def __init__(self):
BaseModule.__init__(self)
self._cpu = chipsec.hal.cpu.CPU( self.cs )
def is_supported(self):
# @TODO: Currently this module doesn't work properly on (U)EFI
return (self.cs.helper.is_windows() or self.cs.helper.is_linux())
def check_LAPIC_SMRR_overlap( self ):
if not chipsec.chipset.is_register_defined( self.cs, 'IA32_APIC_BASE' ) or \
not chipsec.chipset.is_register_defined( self.cs, 'IA32_SMRR_PHYSBASE' ) or \
not chipsec.chipset.is_register_defined( self.cs, 'IA32_SMRR_PHYSMASK' ):
self.logger.error( "Couldn't find definition of required configuration registers" )
return ModuleResult.ERROR
if self._cpu.check_SMRR_supported():
self.logger.log_good( "SMRR range protection is supported" )
else:
self.logger.log_skipped_check("CPU does not support SMRR range protection of SMRAM")
return ModuleResult.SKIPPED
smrr_physbase_msr = chipsec.chipset.read_register( self.cs, 'IA32_SMRR_PHYSBASE', 0 )
apic_base_msr = chipsec.chipset.read_register( self.cs, 'IA32_APIC_BASE', 0 )
chipsec.chipset.print_register( self.cs, 'IA32_APIC_BASE', apic_base_msr )
chipsec.chipset.print_register( self.cs, 'IA32_SMRR_PHYSBASE', smrr_physbase_msr )
smrrbase = chipsec.chipset.get_register_field( self.cs, 'IA32_SMRR_PHYSBASE', smrr_physbase_msr, 'PhysBase' )
smrr_base = chipsec.chipset.get_register_field( self.cs, 'IA32_SMRR_PHYSBASE', smrr_physbase_msr, 'PhysBase', True )
apicbase = chipsec.chipset.get_register_field( self.cs, 'IA32_APIC_BASE', apic_base_msr, 'APICBase' )
apic_base = chipsec.chipset.get_register_field( self.cs, 'IA32_APIC_BASE', apic_base_msr, 'APICBase', True )
self.logger.log( "[*] Local APIC Base: 0x%016X" % apic_base )
self.logger.log( "[*] SMRR Base : 0x%016X" % smrr_base )
self.logger.log( "[*] Attempting to overlap Local APIC page with SMRR region" )
self.logger.log( "NOTE: The system may hang or process may crash when running this test. In that case, the mitigation to this issue is likely working but we may not be handling the exception generated.")
self.logger.log( " writing 0x%X to IA32_APIC_BASE[APICBase].." % smrrbase )
try:
chipsec.chipset.write_register_field( self.cs, 'IA32_APIC_BASE', 'APICBase', smrrbase, preserve_field_position=False, cpu_thread=0 )
ex = False
self.logger.log_bad( "Was able to modify IA32_APIC_BASE" )
except chipsec.helper.oshelper.HWAccessViolationError:
ex = True
self.logger.log_good( "Could not modify IA32_APIC_BASE" )
apic_base_msr_new = chipsec.chipset.read_register( self.cs, 'IA32_APIC_BASE', 0 )
self.logger.log( "[*] new IA32_APIC_BASE: 0x%016X" % apic_base_msr_new )
#chipsec.chipset.print_register( self.cs, 'IA32_APIC_BASE', apic_base_msr_new )
if apic_base_msr_new == apic_base_msr and ex:
res = ModuleResult.PASSED
self.logger.log_passed_check( "CPU does not seem to have SMM memory sinkhole vulnerability" )
else:
chipsec.chipset.write_register( self.cs, 'IA32_APIC_BASE', apic_base_msr, 0 )
self.logger.log( "[*] Restored original value 0x%016X" % apic_base_msr )
res = ModuleResult.FAILED
self.logger.log_failed_check( "CPU is succeptible to SMM memory sinkhole vulnerability" )
return res
# --------------------------------------------------------------------------
# run( module_argv )
# Required function: run here all tests from this module
# --------------------------------------------------------------------------
def run( self, module_argv ):
self.logger.start_test( "x86 SMM Memory Sinkhole" )
return self.check_LAPIC_SMRR_overlap()