基于Xilinx SP605开发板的DMA攻击工具环境搭建及工具使用过程。
# 开发板基本组成
入门手册见:https://docs.xilinx.com/v/u/en-US/ug525
完整用户手册见:https://www.xilinx.com/support/documentation/boards_and_kits/ug526.pdf
完整组成为:
我们需要关注的几个组件:
SPI接口
SP605开发板搭载一个SPI接口,可通过连接JTAG接口,用Xilinx iMPACT配置工具进行固件读写。具体配置方式见:
https://www.xilinx.com/support/documents/boards_and_kits/sp605_PCIe_Gen1_x1_pdf_xtp065_13.4.pdf
外接编程器编程方法
其存储芯片为Winbond W25Q64BVSFIG,下面是SP605上的SPI引脚定义:
根据用户指南,要使用外部SPI跳线J17来编程SPI芯片的话,需要安装J46跳线:
安装下面红框中的跳线:
连接J17引脚(除VCC外)和编程器,使用开发板本身供电:
用编程器直接烧录s6_pcie_microblaze.bin
内容。
USB-to-UART接口
开发板包含一个Silicon Labs CP2103GM USB-to-UART bridge(U4)设备,可以通过USB线连接到主机进行调试输出。
LED指示灯
LED灯定义表如下:
ISE安装
安装Xilinx ISE 14.7版本,下载地址:https://china.xilinx.com/support/download/index.html/content/xilinx/zh/downloadNav/vivado-design-tools/archive-ise.html
下载解压完成后运行xsetup.exe
进行安装。
如果选择的是Win10版本,将会安装虚拟机,在虚拟机中运行ISE。
安装完成后,运行桌面的Project Navigator即可运行:
虚拟机默认用户ise
,密码xilinx
安装时可以选择共享文件夹,也可以安装完成后安装VBox的增强功能,运行./autorun.sh
脚本:
安装完成后重启虚拟机即可在设备->
菜单下设置共享文件夹、拖放文件、共享粘贴板功能了。
安装License,打开Project Navigator
,选择Help->Manage License...
:
点Load License...
,选择xilinx ise 14.7 license.lic
文件即可激活许可证:
激活完成后即可打开项目进行编写了:
项目编译
在Start界面点击Open Project...
,选择s6_pcie_microblaze.xise
文件来打开项目。
- 重新生成
s6_pcie_v2_4
和fifo_generator_v8_4
的IP核:
打开项目后,在Design界面下双击fifo_generator_v8_4
:
弹出Fifo生成器,点击Generate
生成即可:
同样,双击s6_pcie_v2_4
重新生成IP核:
- 选择
microblaze_top
下的microblaze_i
实例,然后双击运行Export Hardware Design To SDK with Bitstream
:
如出现以下错误:
TODO 解决此处错误
命令行输入下面的命令:
cd ./s6_pcie_microblaze-master/ipcore_dir/s6_pcie_v2_4/s6_pcie_v2_4/implement
./implement.sh > implement.log 2>&1
该脚本会在目录下生成一系列编译文件:
iMPACT配置工具写入固件
用USB线连接USB JTAG接口和工作机:
要从板载SPI闪存芯片加载比特流,需要把SW1开关设置为1-ON
,2-OFF
,S1设置为0000:
J46跳线需要设置:
打开iMPACT程序,创建一个新项目:
选择Prepare a PROM File:
点ok进入下一步,设置PROM文件格式,第一步选择SPI Flash – Configure Single FPGA,然后点绿箭头进入下一步,Storage Device(bits)选择64M,点击Add Storage Device,然后下一步选择输出文件名和输出文件夹,点OK完成配置:
要求添加设备,选择刚刚编译生成的./s6_pcie_microblaze-master/ipcore_dir/s6_pcie_v2_4/s6_pcie_v2_4/implement/results/routed.bit
文件:
点击菜单的Operations -> Generate File… 生成mcs文件:
生成完成后双击Boundary Scan:
菜单选择File->Initialize Chain:
右键点”SPI/BPI?”,点Add SPI/BPI Flash:
选择生成的mcs文件:
选择SPI PROM、W25Q64BV/CV、Data Width: 4
右键flash图标,点Program:
编程选项不用改,直接默认配置:
等待编程完成:
写入SPI Flash的比特流文件包括为MicroBlaze core定制的bootloader,这个bootloader可以配置板子的选项,可通过UART接口将main程序写入linear flash中。
下面是将main程序写入linear flash的方法:
- 板子连接上电源,按住SW4按钮,并打开SW2电源开关,等待DS6 LED灯亮起后松开SW4按钮,进入更新模式。
- 将USB线连接到UART接口,输入下面的命令:
# sudo pip install pyserial
# sudo python2 ./python/bootloader_ctl.py /dev/ttyUSB0 --flash sdk/main_0/Debug/main_0.srec
[+] Opening device "/dev/ttyUSB0"...
[+] Flasing 447284 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 0x00100200
Writing 0x100 bytes at 0x00100300
Writing 0x100 bytes at 0x00100400
Writing 0x100 bytes at 0x00100500
Writing 0x100 bytes at 0x00100600
...
Writing 0x100 bytes at 0x0016d000
Writing 0x100 bytes at 0x0016d100
Writing 0x100 bytes at 0x0016d200
Writing 0x34 bytes at 0x0016d300
[+] DONE
- 使用下面的命令设置IP:
# sudo python2 ./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
- 网线连接攻击机和开发板,退出更新模式,从linear flash中启动mian MicroBlaze程序:
# sudo python2 ./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
main()
Loading settings from flash...
[+] Address: 192.168.2.247
[+] Netmask: 255.255.255.0
[+] Gateway: 192.168.2.1
auto-negotiated link speed: 100
Option ROM support is present
Initializing DMA...
Initializing interrupts...
start_application(): TCP server is started at port 28472
- 将SP605插入目标机的PCI-E插槽,打开开发板电源开关,待DS5 LED灯亮起后打开目标机电源,可以看到DS3、DS4 LED灯亮起,说明PCI-E成功连接:
- 目标机上运行lspci命令,可以看到Xilinx PCI-E设备:
开发工具包使用
基本使用
安装依赖:python2 -m pip install pefile
在攻击机上配置python\pcie_lib_config.py
文件中的IP和端口,与上述更新模式中配置的IP一致即可:
DEVICE_TYPE_TCP = 1
DEVICE_TYPE_SERIAL = 2
DEVICE_TYPE_UIO = 3
DEVICE_TYPE_DRIVER = 4
DEVICE_TYPE_DRIVER_DIRECT = 5
class Conf:
device_type = DEVICE_TYPE_TCP
#
# DEVICE_TYPE_SERIAL options
#
# serial port device
device = '/dev/ttyUSB0'
# serial port baudrate
baud = 115200
#
# DEVICE_TYPE_TCP options
#
# board IP address and port
addr = ( '192.168.2.247', 28472 )
#
# EoF
#
工具包提供两个环境变量可覆盖某些选项的默认值:
DEBUG_TLP : 设置为1,则打印TX、RX TLP数据包到屏幕输出中
TARGET_ADDR: <ip addr>:<port>,该环境变量可覆盖pcie_lib_config.py文件中的配置
攻击机上运行命令python2 pcie_cfg.py
,可查看PCI-E设备的配置空间寄存器:
使用pcie_mem.py
程序可读取目标机的物理内存,下例为从0x0地址开始,读取0x80个字节的物理内存:
DEBUG_TLP=1 python2 pcie_mem.py 0x0 0x80
也可将物理内存转储到文件中:
python2 pcie_mem.py 0x18000000 0x200 dump.bin
DMA预引导攻击
uefi_backdoor_simple.py
、uefi_backdoor_hv.py
、uefi_backdoor_boot.py
和uefi_backdoor_boot_shell.py
支持两种不同的方式来传递执行到注入的UEFI DXE驱动镜像:
EFI_SYSTEM_TABLE
劫持 – 从物理地址0xF0000000到0向下扫描系统内存,每次0x10000字节,通过EFI系统表的签名找到EFI_SYSTEM_TABLE
,并patchLocateProtocol()
函数地址。可以使用SCAN_FROM和SCAN_STEP环境变量来覆盖内存扫描选项。PROTOCOL_ENTRY
劫持 – 从物理地址0x76000000到0xA0000000向上扫描系统内存,每次0x1000字节,找到CPU I/O 2协议的EFI_CPU_IO2_PROTOCOL
结构,然后patch该结构中的一个函数。可以使用SCAN_FROM、SCAN_TO和SCAN_STEP环境变量来覆盖内存扫描选项。
默认情况下,所有四个程序都使用EFI系统表劫持方法,如果要使用PROTOCOL_ENTRY
方法,可以使用--inj-prot
命令行选项。 为了减少执行攻击所需的时间,可以在EFI_SYSTEM_TABLE
劫持时使用--system-table
选项指定先前找到的EFI_SYSTEM_TABLE
结构地址,或在PROTOCOL_ENTRY
劫持时使用--prot-entry
选项指定PROTOCOL_ENTRY
结构地址。
另外,所有四个Python程序都有--test
命令行选项,这个选项用于进行内存扫描,找到所需的结构地址,但不执行实际的劫持流程。在首次运行时,可以用--test
选项运行所需的程序来找到所需的地址,第二次运行时再用--system-table
或--prot-entry
选项运行相同的程序来指定该地址。
近期评论