mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
291632c0ee
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
163 lines
5.4 KiB
Python
163 lines
5.4 KiB
Python
# CHIPSEC: Platform Security Assessment Framework
|
|
# Copyright (c) 2010-2020, 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
|
|
#
|
|
|
|
|
|
"""
|
|
Simple CPU Module Specific Register (MSR) VMM emulation fuzzer
|
|
|
|
Usage:
|
|
``chipsec_main -m tools.vmm.msr_fuzz [-a random]``
|
|
|
|
- ``-a`` : random = use random values (default = sequential numbering)
|
|
|
|
Where:
|
|
- ``[]``: optional line
|
|
|
|
Examples:
|
|
>>> chipsec_main.py -i -m tools.vmm.msr_fuzz
|
|
>>> chipsec_main.py -i -m tools.vmm.msr_fuzz -a random
|
|
|
|
Additional options set within the module:
|
|
- ``_NO_ITERATIONS_TO_FUZZ`` : Number of iterations to fuzz randomly
|
|
- ``_READ_MSR`` : Specify to read MSR when fuzzing it
|
|
- ``_FLUSH_LOG_EACH_MSR`` : Flush log file before each MSR
|
|
- ``_FUZZ_VALUE_0_all1s`` : Try all 0 & all 1 values to be written to each MSR
|
|
- ``_FUZZ_VALUE_5A`` : Try 0x5A values to be written to each MSR
|
|
- ``_FUZZ_VALUE_RND`` : Try random values to be written to each MSR
|
|
- ``_EXCLUDE_MSR`` : MSR values to exclude (list)
|
|
|
|
.. note::
|
|
- Returns a Warning by default
|
|
- System may be in an unknown state, further evaluation may be needed
|
|
|
|
.. important::
|
|
- This module is designed to run in a VM environment
|
|
- Behavior on physical HW is undefined
|
|
|
|
"""
|
|
|
|
import random
|
|
|
|
from chipsec.module_common import BaseModule, ModuleResult
|
|
|
|
_MODULE_NAME = 'msr_fuzz'
|
|
|
|
# Number of iterations to fuzz randomly
|
|
_NO_ITERATIONS_TO_FUZZ = 100000
|
|
|
|
# Read MSR?
|
|
_READ_MSR = False
|
|
|
|
# Flush log file before each MSR
|
|
_FLUSH_LOG_EACH_MSR = False
|
|
|
|
# Control values to be written to each MSR
|
|
_FUZZ_VALUE_0_all1s = True
|
|
_FUZZ_VALUE_5A = False
|
|
_FUZZ_VALUE_RND = True
|
|
|
|
# Exclude MSRs which cause VM hang/crash
|
|
_EXCLUDE_MSR = []
|
|
|
|
|
|
class msr_fuzz (BaseModule):
|
|
|
|
def fuzz_MSRs(self, msr_addr_start, random_order=False):
|
|
msr_addr_range = 0x10000
|
|
msr_addr_end = msr_addr_start + msr_addr_range
|
|
self.logger.log("[*] Fuzzing MSRs in range 0x{:08X}:0x{:08X}..".format(msr_addr_start, msr_addr_end))
|
|
it = 0
|
|
if random_order:
|
|
it_max = _NO_ITERATIONS_TO_FUZZ
|
|
else:
|
|
it_max = msr_addr_range
|
|
|
|
while it < it_max:
|
|
if random_order:
|
|
msr_addr = random.randint(msr_addr_start, msr_addr_end)
|
|
else:
|
|
msr_addr = msr_addr_start + it
|
|
|
|
if _FLUSH_LOG_EACH_MSR:
|
|
self.logger.flush()
|
|
|
|
if msr_addr not in _EXCLUDE_MSR:
|
|
if _READ_MSR:
|
|
self.logger.log("[*] rdmsr 0x{:08X}".format(msr_addr))
|
|
try:
|
|
(_, _) = self.cs.msr.read_msr(0, msr_addr)
|
|
except:
|
|
pass
|
|
|
|
self.logger.log("[*] wrmsr 0x{:08X}".format(msr_addr))
|
|
|
|
if _FUZZ_VALUE_0_all1s:
|
|
try:
|
|
self.cs.msr.write_msr(0, msr_addr, 0, 0)
|
|
except:
|
|
pass
|
|
try:
|
|
self.cs.msr.write_msr(0, msr_addr, 0xFFFFFFFF, 0xFFFFFFFF)
|
|
except:
|
|
pass
|
|
|
|
if _FUZZ_VALUE_5A:
|
|
try:
|
|
self.cs.msr.write_msr(0, msr_addr, 0x5A5A5A5A, 0x5A5A5A5A)
|
|
except:
|
|
pass
|
|
|
|
if _FUZZ_VALUE_RND:
|
|
val_hi = random.randint(0, 0xFFFFFFFF)
|
|
val_lo = random.randint(0, 0xFFFFFFFF)
|
|
try:
|
|
self.cs.msr.write_msr(0, msr_addr, val_hi, val_lo)
|
|
except:
|
|
pass
|
|
it += 1
|
|
return True
|
|
|
|
def run(self, module_argv):
|
|
self.logger.start_test("Fuzzing CPU Model Specific Registers (MSR)")
|
|
|
|
_random_order = False
|
|
if (len(module_argv) > 0) and ('random' == module_argv[0].lower()):
|
|
_random_order = True
|
|
|
|
global _NO_ITERATIONS_TO_FUZZ
|
|
_NO_ITERATIONS_TO_FUZZ = 100000
|
|
|
|
self.logger.log("[*] Configuration:")
|
|
self.logger.log(" Mode: {}".format('random' if _random_order else 'sequential'))
|
|
if _random_order:
|
|
self.logger.log(" Number of iterations: {:d}".format(_NO_ITERATIONS_TO_FUZZ))
|
|
|
|
self.logger.log("\n[*] Fuzzing Low MSR range...")
|
|
self.fuzz_MSRs(0x0, _random_order)
|
|
self.logger.log("\n[*] Fuzzing High MSR range...")
|
|
self.fuzz_MSRs(0xC0000000, _random_order)
|
|
self.logger.log("\n[*] Fuzzing VMM synthetic MSR range...")
|
|
self.fuzz_MSRs(0x40000000, _random_order)
|
|
|
|
self.logger.log_information('Module completed')
|
|
self.logger.log_warning('System may be in an unknown state, further evaluation may be needed.')
|
|
self.res = ModuleResult.WARNING
|
|
return self.res
|