USB是 UniversalSerial Bus(通用串行總線)的縮寫,是一個外部總線標準,用於規範電腦與外部設備的連接和通訊,例如鍵盤、鼠標、打印機、磁盤或網絡適配器等等。通過對該接口流量的監聽,我們可以得到鍵盤的擊鍵記錄、鼠標的移動軌跡、磁盤的傳輸內容等一系列信息。

在Linux中,可以使用lsusb命令,如圖所示:

我們這裏主要演示USB的鼠標流量和鍵盤流量。Linux下的分析已經比較多了,下面的環境均在Windows下進行。

一、鼠標流量

1.1 特點分析

USB鼠標流量的規則如下所示:

1.2 使用Wireshark捕獲和分析

要想使用Wireshark進行捕獲,需要在安裝時勾選上usbpcap工具選項,這樣你的Wireshark中會有一個usb接口的選項,點擊就可以進行抓包了。

下圖是我點擊鼠標左鍵在屏幕上畫圓圈的流量:

有的鼠標可能協議不是很標準,會導致分析不了。

Wireshark中捕獲的USB流量集中在Leftover Capture Data模塊,我們可以使用tshark工具來進行提取。在Windows中安裝tshark.exe的目錄中輸入:

tshark.exe -r b.pcap -T fields -e usb.capdata >b.txt //這裏b.pcap是我抓捕的數據包名字,b.txt是把提取的數據輸入到b.txt中

查看b.txt的內容會發現,因爲有的數據包無用所以出現了很多空行,在進行下一步之前,我們需要把空行去掉。

把空行去掉之後,根據鼠標流量的規則繪製像素座標,最後通過畫圖工具(如matlab或者python的matplotlib進行繪製圖像即可)

瞭解原理之後,爲了方便,可以直接使用王一航大佬的工具進行提取,輸入:

python UsbMiceDataHacker.py b.pcap LEFT //其中b.pcap是我抓捕的數據包的名字

運行之後就可以看到畫面:

需要注意的是這個工具必須在python2環境下,同時保證安裝了matplotlib和numpy。

二、鍵盤流量

2.1 特點分析

鍵盤數據包的數據長度爲8個字節,擊鍵信息集中在第3個字節,每次擊鍵都會產生一個數據包。所以如果看到給出的數據包中的信息都是8個字節,並且只有第3個字節不爲0000,那麼幾乎可以肯定是一個鍵盤流量了。

在USB協議的 文檔中搜索 keyboard。就可以找到擊鍵信息和數據包中16進制數據的對照表:

2.2 使用Wireshark捕獲和分析

捕獲的步驟與上面相似。下面以XCTF的高校戰疫比賽中的一道例題(ez_mem&usb)來說明。

最後一步我們得到一個壓縮包,通過密碼進行解壓後,得到一個鍵盤流量的文本文件:

根據鍵盤流量的特點,我們可以很容易判斷出。

對照解碼錶使用代碼進行提取即可,這裏貼出代碼:

# coding:utf-8
import sys
import os

usb_codes = {
    0x04: "aA", 0x05: "bB", 0x06: "cC", 0x07: "dD", 0x08: "eE", 0x09: "fF",
    0x0A: "gG", 0x0B: "hH", 0x0C: "iI", 0x0D: "jJ", 0x0E: "kK", 0x0F: "lL",
    0x10: "mM", 0x11: "nN", 0x12: "oO", 0x13: "pP", 0x14: "qQ", 0x15: "rR",
    0x16: "sS", 0x17: "tT", 0x18: "uU", 0x19: "vV", 0x1A: "wW", 0x1B: "xX",
    0x1C: "yY", 0x1D: "zZ", 0x1E: "1!", 0x1F: "2@", 0x20: "3#", 0x21: "4$",
    0x22: "5%", 0x23: "6^", 0x24: "7&", 0x25: "8*", 0x26: "9(", 0x27: "0)",
    0x2C: "  ", 0x2D: "-_", 0x2E: "=+", 0x2F: "[{", 0x30: "]}", 0x32: "#~",
    0x33: ";:", 0x34: "'\"", 0x36: ",<", 0x37: ".>", 0x4f: ">", 0x50: "<"
}


def code2chr(filepath):
    lines = []
    pos = 0
    for x in open(filepath, "r").readlines():
        code = int(x[6:8], 16)  # 即第三個字節
        if code == 0:
            continue
        # newline or down arrow - move down
        if code == 0x51 or code == 0x28:
            pos += 1
            continue
        # up arrow - move up
        if code == 0x52:
            pos -= 1
            continue

        # select the character based on the Shift key
        while len(lines) <= pos:
            lines.append("")
        if code in range(4, 81):
            if int(x[0:2], 16) == 2:
                lines[pos] += usb_codes[code][1]
            else:
                lines[pos] += usb_codes[code][0]

    for x in lines:
        print(x)


if __name__ == "__main__":
    code2chr('E://CTF練習/雜項/18e4c103d4de4f07b33a42cb1f0eaa1d/00000122/usbdata.txt')

當然也可以直接使用王一航大佬的代碼,直接從pcap包提取出文件,省去了中間很多步驟,代碼也很通用。

*本文作者:polemo,轉載請註明來自FreeBuf.COM

相關文章