
Intercetta e analizza il traffico USB Mass Storage a livello di blocco e file, emula dispositivi USB e supporta stub Python personalizzati per ricerca sulla sicurezza, analisi forense e test delle vulnerabilità TOCTOU.

usb-spy è un analizzatore del traffico USB Mass Storage costruito attorno a un microcontrollore con supporto WiFi o Ethernet.
La scheda espone un'immagine disco (FAT o qualsiasi filesystem) come un falso dispositivo USB Mass Storage verso un sistema target, mentre i dati di archiviazione reali sono forniti da un server remoto tramite WiFi o Ethernet. Questa configurazione consente a usb-spy di intercettare e analizzare ogni accesso a blocchi effettuato dal target.
Oltre alla semplice tracciatura a livello di blocchi grezzi, usb-spy comprende i filesystem e può mappare ogni blocco acceduto al corrispondente file e directory, rendendo facile vedere immediatamente quale file viene letto o scritto, invece di soli numeri di settore grezzi.
Inoltre, usb-spy può emulare qualsiasi dispositivo USB personalizzando le proprietà del dispositivo come vendor ID, product ID, numero di serie, produttore e nome prodotto tramite un file di configurazione JSON. Questo permette di impersonare dispositivi USB specifici per scopi di test e analisi.
Lo strumento è facilmente estendibile tramite stub Python scritti dall'utente, permettendo di implementare logica personalizzata per la gestione degli eventi di lettura/scrittura USB e delle operazioni a livello di blocchi.

Quando viene rilevato un filesystem supportato, usb-spy:
Filesystem attualmente supportati:
Il supporto per filesystem aggiuntivi sarà aggiunto in futuro.
Se il filesystem non è supportato, usb-spy può comunque essere utilizzato:
Questo garantisce che usb-spy rimanga utile anche con filesystem sconosciuti, personalizzati o proprietari.

Le istruzioni per la compilazione del firmware per ciascuna scheda supportata sono descritte qui:
Il codice sorgente si trova nella directory src. Caricherà un'immagine FAT, la esporrà tramite una porta TCP e registrerà ogni accesso effettuato all'immagine. Per stampare le informazioni su file e directory, lo strumento si basa sulla libreria TheSleuthKit.
Per compilare, esegui il seguente comando nella directory principale
Recupera tutti i sottomoduli
git submodule update --init --recursive
Quindi esegui il comando waf configure.
./waf configure
Controlla e compila tutte le dipendenze necessarie, quindi per compilare effettivamente il progetto esegui
./waf build
Il binario si troverà nella directory wbuild
Possiamo farlo facilmente con il pacchetto di utilità mtools
Crea un file da 2 MB
dd if=/dev/zero of=disk.img bs=1M count=2
Metti un filesystem FAT su di esso (usa -F per FAT32, altrimenti è automatico)
mformat -i disk.img ::
Aggiungi un file
mcopy -i disk.img example.txt ::
Elenca i file
mdir -i disk.img ::
Estrai un file
mcopy -i disk.img ::/example.txt extracted.txt
Esegui lo spy con l'immagine appena creata
./usb-spy -v disk.img
Collega la scheda alla porta USB del target.
Per emulare un dispositivo USB specifico, i parametri possono essere sovrascritti tramite un file di configurazione JSON:
Il seguente file JSON emulerà un dispositivo USB Kingston DataTraveler:
{
"vendor_id": 2385,
"product_id": 5734,
"bcd_device": 272,
"product_rev": "3.0",
"manufacturer": "Kingston",
"product_name": "DataTraveler",
"serial": "509C4BBFACCDE742880C026B",
"language": 1033
}
Esegui lo spy con questo file di configurazione
./usb-spy -c config/kingston.json disk.img
L'output di dmesg per questo dispositivo:
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
Se vuoi implementare la tua logica per ogni evento di lettura/scrittura, puoi farlo facilmente in Python.
Implementa la classe USBImage in Python come questa immagine dummy:
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")
Ed esegui lo spy con il tuo modulo Python.
./usb-spy --py python/dummy.py disk.img
Puoi anche passare argomenti arbitrari dalla riga di comando alla tua classe Python. Gli argomenti sono disponibili in kwargs.
./usb-spy --py python/dummy.py --py-args arg1=2 --py-args arg2=Hello disk.img
Puoi anche partire dall'esempio rawimage che fornisce un'implementazione completa (~100 righe di codice) di ciò che è implementato nativamente nel binario usb-spy.
Questo progetto è fornito "così com'è". Non vi è alcuna garanzia di correttezza, sicurezza o idoneità per uno scopo particolare.
Utilizza gli strumenti e il firmware a tuo rischio. L'autore e i collaboratori non sono responsabili per eventuali danni, perdita di dati o conseguenze legali che potrebbero derivare dall'uso di questo software o hardware.
I contributi sono benvenuti! Segui questi passaggi:
Questo progetto è concesso in licenza sotto la GNU General Public License v3.0. Vedi il file LICENSE per i dettagli.