一般信息
内容
SP605 板卡配置
软件配置
示例
使用 Python API
实用 DMA 攻击
Option ROM 攻击
故障排除
从源代码构建项目
本仓库包含一组与 PCI-E 总线及 DMA 攻击相关的工具和概念验证。其中包含一个 HDL 设计,可为搭载 Spartan-6 FPGA 的 Xilinx SP605 评估套件实现软件可控的 PCI-E gen 1.1 端点设备。与流行的 USB3380EVB 相比,该设计允许操作 PCI-E 总线的原始事务层数据包(TLP),并执行完整的 64 位内存读/写操作。为演示该设计的实际用例,有一个工具可对基于 UEFI 的机器执行引导前 DMA 攻击,允许在平台初始化期间执行任意 UEFI DXE 驱动程序。
有一个程序演示了如何利用引导前 DMA 攻击,将 Hyper-V VM exit handler 后门注入到启用了基于虚拟化的安全性且在启用了 UEFI Secure Boot 的平台上运行的 Windows 10 和 11 中。所提供的 Hyper-V Backdoor PoC 可能对逆向工程和漏洞利用开发有用,它提供了一个接口,用于从客户机分区检查虚拟机监控程序状态(VMCS、物理/虚拟内存、寄存器等),并执行从客户机到宿主的 VM 逃逸攻击。
另一个程序演示了如何利用引导前 DMA 攻击,通过使用 Boot Backdoor 劫持 Windows 的引导过程,将任意用户态或内核态代码注入到 Windows 操作系统中。该程序还可以与 DMA Shell 配合使用——它是 Boot Backdoor 的载荷,允许通过恶意 PCI-E 设备执行控制台命令、传输文件,并在运行时将第三方可执行文件加载到目标操作系统中。
💾 本项目的 Hyper-V Backdoor 部分拥有本文档所述之外的许多其他功能和部署选项,您可以将其与 DMA 攻击工具分开使用,甚至无需任何特殊硬件:查看其文档
💾 本项目的 Boot Backdoor 部分拥有本文档所述之外的许多其他功能和部署选项,您可以将其与 DMA 攻击工具分开使用,甚至无需任何特殊硬件:查看其文档
💾 本项目中的 Python 工具以及面向 SP605、ZC706 和 PicoEVB 板卡的 FPGA 设计,也可用于通过引导前 DMA 攻击部署 SMM Backdoor Next Gen。更多技术细节请查看其文档。
🛠️ 本项目中的 Python 工具和载荷(包括 Hyper-V Backdoor 和 Boot Backdoor)也可用于基于 Xilinx Zynq-7000 SoC 的板卡。有一个针对 Xilinx ZC706 评估套件的 DMA 攻击设计独立项目。
🛠️ 本项目中的 Python 工具和载荷(包括 Hyper-V Backdoor 和 Boot Backdoor)也可用于 PicoEVB 开发板。还有一个独立的 Pico DMA 项目 − 面向 M.2 插槽的全自主引导前 DMA 攻击硬件植入物,可将任意 UEFI DXE 驱动程序作为载荷运行。
s6_pcie_microblaze.xise − Xilinx ISE 项目文件。
microblaze/pcores/axis_pcie_v1_00_a/ − 自定义外设模块,可将 Spartan-6 FPGA 的 PCI Express 集成端点块作为原始 TLP 流连接到 MicroBlaze 软处理器核。
sdk/srec_bootloader_0/ − 面向 MicroBlaze 软处理器的简单引导加载程序,它使用 SREC 镜像格式和 SP605 板载线性闪存来加载和存储 MicroBlaze 主程序。
sdk/main_0/ − MicroBlaze 软处理器的主程序,它使用 SP605 板载以太网端口和 lwIP 网络协议栈,将 PCI-E 总线的原始 TLP 数据包转发到 TCP 连接中。
python/pcie_lib.py − Python 库,用于通过网络与 SP605 板卡上运行的主 MicroBlaze 程序交互,它实现了各种底层和高级抽象,以便从 Python 代码中操作 PCI-E 的 TLP 层。
python/pcie_mem.py − 命令行程序,通过发送 MRd TLP 将宿主机 RAM 转储到屏幕或输出文件。
python/pcie_mem_scan.py − 命令行程序,用于扫描目标宿主机上可通过 PCI-E 总线访问的物理内存范围,对启用 IOMMU 的平台进行安全审计很有用(示例:1、2、3、4)。
python/uefi_backdoor_simple.py − 用于引导前 DMA 攻击的命令行程序,将虚拟 UEFI 驱动程序注入目标机器的引导序列。
python/uefi_backdoor_hv.py − 用于引导前 DMA 攻击的命令行程序,将 Hyper-V VM exit handler 后门注入目标系统的引导序列。
python/uefi_backdoor_boot.py − 用于引导前 DMA 攻击的命令行程序,将 Boot Backdoor 注入目标系统的引导序列。
python/payloads/DmaBackdoorSimple/ − 与 uefi_backdoor_simple.py 配合使用的虚拟 UEFI DXE 驱动程序源代码。
python/payloads/DmaBackdoorHv/ − 与 uefi_backdoor_hv.py 配合使用的 UEFI DXE 驱动程序源代码,它实现了 Hyper-V Backdoor 功能。
python/payloads/DmaBackdoorBoot/ − 与 uefi_backdoor_boot.py 配合使用的 UEFI DXE 驱动程序源代码,它实现了 Boot Backdoor 功能。
Xilinx UG526 文档,也就是 SP605 硬件用户指南,如果你想了解这块出色板卡的使用和配置的更多细节,它就是你最好的朋友。
要从板载 SPI 闪存芯片加载比特流,你需要通过将 SW1 开关拨到 1-ON、2-OFF 位置来配置 SP605。
现在,你需要将 FPGA 比特流写入 SPI 闪存。如果你想通过 JTAG 并借助 Xilinx iMPACT 工具来完成此操作,请使用 s6_pcie_microblaze.mcs 文件(参见本教程);如果你想使用连接到 SP605 的 J17 排针的外部 SPI 闪存编程器(这是最快且更方便的方法),请使用 s6_pcie_microblaze.bin。
如果使用与 flashrom 兼容的 SPI 闪存编程器,你可以使用 flash_to_spi.py 程序作为 flashrom 的包装器:```
$ ./flash_to_spi.py linux_spi:dev=/dev/spidev1.0 s6_pcie_microblaze.bin
Using region: "main".
Calibrating delay loop... OK.
Found Winbond flash chip "W25Q64.V" (8192 kB, SPI) on linux_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip...
Warning: Chip content is identical to the requested image.
Erase/write done.
3) 上一步中写入 SPI flash 的比特流文件包含用于 MicroBlaze 核的自定义引导加载程序(更多细节见 [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c))。该引导加载程序允许配置板卡选项,并通过 SP605 的 UART 端口将主程序写入线性闪存。
要引导 MicroBlaze 进入更新模式,您必须断开 SPI flash 编程器,并在按住 `SW4` 按钮开关的情况下为板卡上电;当指示活动更新模式的 `DS6` LED 亮起时,松开 `SW4`。
4) 要将主程序(更多细节见 [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c))写入线性闪存,您需要将计算机连接到 SP605 的 UART 桥接 USB 端口,并运行带 `--flash` 选项的 `bootloader_ctl.py` 程序:```
$ easy_install pyserial
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --flash sdk/main_0/Debug/main_0.srec
[+] Opening device "/dev/ttyUSB0"...
[+] Flasing 339852 bytes from "sdk/main_0/Debug/main_0.srec"...
Erasing flash...
Writing 0x100 bytes at 0x00100000
Writing 0x100 bytes at 0x00100100
...
Writing 0x100 bytes at 0x00152e00
Writing 0x8c bytes at 0x00152f00
[+] DONE
--config 选项运行 bootloader_ctl.py 程序:```
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --config 192.168.2.247:255.255.255.0:192.168.2.1:28472
[+] Opening device "/dev/ttyUSB0"...
[+] Updating board settings...Address: 192.168.2.247 Netmask: 255.255.255.0 Gateway: 192.168.2.1 Port: 28472
Erasing flash... Writing 0x12 bytes at 0x00000000 [+] DONE
6) 现在,您可以退出更新模式,并从线性闪存启动主 MicroBlaze 程序:```
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --boot
[+] Opening device "/dev/ttyUSB0"...
[+] Exitting from update mode...
SREC Bootloader
Loading SREC image from flash at address: 42000000
Executing program starting at address: 00000000
Loading settings from flash...
[+] Address: 192.168.2.247
[+] Netmask: 255.255.255.0
[+] Gateway: 192.168.2.1
auto-negotiated link speed: 100
start_application(): TCP server is started at port 28472
主板程序会将错误信息输出到板载 UART,你可以使用 bootloader_ctl.py 的 --console 选项实时监视这些信息。
将 SP605 连接到目标计算机的 PCI-E 插槽并开启计算机。当 PCI-E 链路成功建立后,你会看到 DS3 和 DS4 LED 亮起。
在目标计算机上运行 lspci 命令,以确保其操作系统将你的板卡识别为相应的 PCI-E 设备:```
01:00.0 Ethernet controller: Xilinx Corporation Default PCIe endpoint ID
JTAG 相关说明:SP605 板载 USB 转 JTAG 接口,兼容 iMPACT 及其他 Xilinx 工具。不过,该接口质量不太好;因此,如果你打算按照 Xilinx 教程中的描述,使用板载 JTAG 对 SPI flash 进行编程,则必须注意以下事项:
* 在使用 JTAG 时,移除连接到 SP605 FMC 插槽的任何硬件。
* 在 Xilinx iMPACT 设置中,将 JTAG 接口速度配置为 750 KHz(在更高速度下工作不稳定)。