
USBマスストレージトラフィックをブロックおよびファイルレベルで傍受・解析し、USBデバイスをエミュレートし、セキュリティ研究、フォレンジック、TOCTOU脆弱性テストのためのカスタムPythonスタブをサポートします。

usb-spy は、WiFiまたはイーサネット対応マイクロコントローラをベースに構築されたUSBマスストレージトラフィックアナライザです。
このボードは、ディスクイメージ(FATまたは任意のファイルシステム)を偽のUSBマスストレージデバイスとしてターゲットシステムに公開し、実際のストレージデータはWiFiまたはイーサネット経由でリモートサーバーから提供されます。この構成により、usb-spyはターゲットによって実行されるすべてのブロックアクセスを傍受して分析できます。
生のブロックレベルのトレースに加えて、usb-spyはファイルシステムを理解し、アクセスされた各ブロックを対応するファイルおよびディレクトリにマッピングできるため、生のセクタ番号だけでなく、どのファイルが読み書きされているかを即座に確認できます。
さらに、usb-spyはJSON設定ファイルを通じてベンダーID、プロダクトID、シリアル番号、メーカー名、製品名などのデバイスプロパティをカスタマイズすることで、任意のUSBデバイスをエミュレートできます。これにより、テストおよび分析目的で特定のUSBデバイスになりすますことができます。
このツールは、ユーザーが作成したPythonスタブを通じて簡単に拡張でき、USB読み取り/書き込みイベントおよびブロックレベル操作を処理するカスタムロジックを実装できます。

サポートされているファイルシステムが検出されると、usb-spyは以下を実行します:
現在サポートされているファイルシステム:
追加のファイルシステムへの対応は今後追加される予定です。
ファイルシステムがサポートされていない場合でも、usb-spyは引き続き使用できます:
これにより、未知のファイルシステム、カスタムファイルシステム、または独自のファイルシステムでもusb-spyの有用性が保証されます。

各サポート対象ボードのファームウェアビルド手順はここに記載されています:
ソースコードはsrcディレクトリにあります。FATイメージをロードし、TCPポート経由で公開し、イメージへのすべてのアクセスをログに記録します。 ファイルおよびディレクトリ情報を表示するために、このツールはTheSleuthKitライブラリに依存しています。
ビルドするには、ルートディレクトリで次のコマンドを実行します。
すべてのサブモジュールを取得します。
git submodule update --init --recursive
次に、waf configureコマンドを実行します。
./waf configure
Python埋め込みサポートなしでビルドする場合は、次のように設定します:
./waf configure --disable-python
必要なすべての依存関係をチェックしてビルドし、その後プロジェクトを実際にビルドするには次を実行します。
./waf build
バイナリはwbuildディレクトリに配置されます。
--disable-pythonでビルドした場合、--pyおよび--py-argsランタイムオプションは使用できません。
これはmtoolsユーティリティパッケージを使用して簡単に実行できます。
2 MBのファイルを作成します。
dd if=/dev/zero of=disk.img bs=1M count=2
FATファイルシステムを配置します(FAT32の場合は-Fを使用、それ以外は自動です)。
mformat -i disk.img ::
ファイルを追加します。
mcopy -i disk.img example.txt ::
ファイルを一覧表示します。
mdir -i disk.img ::
ファイルを抽出します。
mcopy -i disk.img ::/example.txt extracted.txt
新しく作成したイメージでスパイを実行します。
./usb-spy -v disk.img
生モードを強制し、ファイルシステムの自動検出をスキップするには:
./usb-spy --raw disk.img
アクセスを実際のブロックデバイスに直接プロキシするには:
./usb-spy --proxy /dev/sda
ボードをターゲットのUSBポートに接続します。
特定のUSBデバイスをエミュレートするには、JSON設定ファイルを通じてパラメータを上書きできます:
次のJSONファイルはKingston DataTraveler USBデバイスをエミュレートします:
{
"vendor_id": 2385,
"product_id": 5734,
"bcd_device": 272,
"product_rev": "3.0",
"manufacturer": "Kingston",
"product_name": "DataTraveler",
"serial": "509C4BBFACCDE742880C026B",
"language": 1033
}
この設定ファイルでスパイを実行します。
./usb-spy -c config/kingston.json disk.img
このデバイスのdmesg出力:
usb 1-8: New USB device found, idVendor=0951, idProduct=1666, bcdDevice= 1.10
usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-8: Product: DataTraveler
usb 1-8: Manufacturer: Kingston
usb 1-8: SerialNumber: 509C4BBFACCDE742880C026B
usb-storage 1-8:1.0: USB Mass Storage device detected
scsi host6: usb-storage 1-8:1.0
scsi 6:0:0:0: Direct-Access Kingston DataTraveler 3.0 PQ: 0 ANSI: 2
すべての読み取り/書き込みイベントに対して独自のロジックを実装したい場合は、Pythonで簡単に実行できます。
次のdummyイメージのように、PythonでUSBImageクラスを実装します:
class USBImage:
def __init__(self, *args, **kwargs):
"""
Initialize the USBImage.
:param args: should contain:
- filename: The name of the file to manage.
:param kwargs: Arbitrary arguments passed from the c++ command line including:
readOnly: Whether the interface is read-only.
verbose: Whether to enable verbose logging.
block: Whether to enable block mode.
"""
pass
def getBlockNumber(self):
"""Get block number"""
return 100
def getBlockSize(self):
"""Get block size"""
return 512
def read(self, lba, buffer, size):
"""Read block"""
print(f"read block={lba} size={size}")
for i in range(size):
buffer[i] = (lba + i) % 256 # Simulate reading data
return size
def write(self, lba, buffer, size):
"""Write block"""
print(f"write block={lba} size={size}")
print(buffer)
return size
def flush(self):
"""Flush block"""
print("flush data")
そして、Pythonモジュールを使用してスパイを実行します。
./usb-spy --py python/dummy.py disk.img
コマンドラインからPythonクラスに任意の引数を渡すこともできます。 引数はkwargsで利用できます。
./usb-spy --py python/dummy.py --py-args arg1=2 --py-args arg2=Hello disk.img
また、usb-spyバイナリでネイティブに実装されている内容の完全な実装(約100行のコード)を提供するrawimageの例から始めることもできます。
このプロジェクトは「現状のまま」提供されます。正確性、セキュリティ、または特定の目的への適合性についての保証はありません。
ツールおよびファームウェアは自己責任で使用してください。作者および貢献者は、このソフトウェアまたはハードウェアの使用から生じる損害、データ損失、または法的結果について責任を負いません。
貢献を歓迎します!次の手順に従ってください:
このプロジェクトはGNU General Public License v3.0の下でライセンスされています。詳細についてはLICENSEファイルを参照してください。