Intercepte et analyse le trafic USB Mass Storage au niveau bloc et fichier, émule des périphériques USB, et prend en charge des stubs Python personnalisés pour la recherche en sécurité, la forensique et les tests de vulnérabilité TOCTOU.

usb-spy est un analyseur de trafic USB Mass Storage conçu autour d'un microcontrôleur compatible WiFi ou Ethernet.
La carte expose une image disque (FAT ou tout autre système de fichiers) comme un faux périphérique USB Mass Storage à un système cible, tandis que les données de stockage réelles sont fournies par un serveur distant via WiFi ou Ethernet. Cette configuration permet à usb-spy d'intercepter et d'analyser chaque accès aux blocs effectué par la cible.
Au-delà du traçage brut au niveau des blocs, usb-spy comprend les systèmes de fichiers et peut mapper chaque bloc accédé au fichier et répertoire correspondant, ce qui permet de voir immédiatement quel fichier est lu ou écrit, au lieu de simples numéros de secteurs bruts.
De plus, usb-spy peut émuler n'importe quel périphérique USB en personnalisant les propriétés du périphérique telles que l'identifiant du fournisseur, l'identifiant du produit, le numéro de série, le fabricant et le nom du produit via un fichier de configuration JSON. Cela vous permet d'usurper des périphériques USB spécifiques à des fins de test et d'analyse.
L'outil est facilement extensible grâce à des stubs Python écrits par l'utilisateur, vous permettant d'implémenter une logique personnalisée pour gérer les événements de lecture/écriture USB et les opérations au niveau des blocs.

Lorsqu'un système de fichiers pris en charge est détecté, usb-spy :
Systèmes de fichiers actuellement pris en charge :
La prise en charge de systèmes de fichiers supplémentaires sera ajoutée à l'avenir.
Si le système de fichiers n'est pas pris en charge, usb-spy peut toujours être utilisé :
Cela garantit qu'usb-spy reste utile même avec des systèmes de fichiers inconnus, personnalisés ou propriétaires.

Les instructions de compilation du firmware pour chaque carte prise en charge sont décrites ici :
Le code source se trouve dans le répertoire src. Il charge une image FAT, l'expose via un port TCP et journalise chaque accès effectué à l'image. Pour afficher les informations sur les fichiers et répertoires, l'outil s'appuie sur la bibliothèque TheSleuthKit.
Pour compiler, exécutez la commande suivante dans le répertoire racine
Récupérez tous les sous-modules
git submodule update --init --recursive
Puis exécutez la commande de configuration waf.
./waf configure
Si vous souhaitez compiler sans la prise en charge de l'intégration Python, configurez avec :
./waf configure --disable-python
Cela vérifiera et compilera toutes les dépendances nécessaires, puis pour compiler réellement le projet, exécutez
./waf build
Le binaire se trouvera dans le répertoire wbuild
Lorsqu'il est compilé avec --disable-python, les options d'exécution --py et --py-args ne sont pas disponibles.
Nous pouvons facilement le faire avec le paquet utilitaire mtools
Créez un fichier de 2 Mo
dd if=/dev/zero of=disk.img bs=1M count=2
Placez un système de fichiers FAT dessus (utilisez -F pour FAT32, sinon c'est automatique)
mformat -i disk.img ::
Ajoutez un fichier
mcopy -i disk.img example.txt ::
Listez les fichiers
mdir -i disk.img ::
Extrayez un fichier
mcopy -i disk.img ::/example.txt extracted.txt
Exécutez le spy avec l'image nouvellement créée
./usb-spy -v disk.img
Pour forcer le mode brut et ignorer la détection automatique du système de fichiers :
./usb-spy --raw disk.img
Pour rediriger l'accès directement vers un vrai périphérique bloc :
./usb-spy --proxy /dev/sda
Branchez la carte sur le port USB de la cible.
Pour émuler un périphérique USB spécifique, les paramètres peuvent être remplacés via un fichier de configuration json :
Le fichier json suivant émule un périphérique 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
}
Exécutez le spy avec ce fichier de configuration
./usb-spy -c config/kingston.json disk.img
La sortie dmesg pour ce périphérique :
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
Si vous souhaitez implémenter votre propre logique pour chaque événement de lecture/écriture, vous pouvez facilement le faire en python.
Implémentez la classe USBImage en python comme cette image 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")
Et exécutez le spy avec votre module python.
./usb-spy --py python/dummy.py disk.img
Vous pouvez également passer des arguments arbitraires depuis la ligne de commande à votre classe python. Les arguments sont disponibles dans kwargs.
./usb-spy --py python/dummy.py --py-args arg1=2 --py-args arg2=Hello disk.img
Vous pouvez également partir de l'exemple rawimage qui fournit une implémentation complète (~100 lignes de code) de ce qui est implémenté nativement dans le binaire usb-spy.
Ce projet est fourni « en l'état ». Il n'y a aucune garantie d'exactitude, de sécurité ou d'adéquation à un usage particulier.
Utilisez les outils et le firmware à vos propres risques. L'auteur et les contributeurs ne sont pas responsables des dommages, pertes de données ou conséquences juridiques pouvant découler de l'utilisation de ce logiciel ou matériel.
Les contributions sont les bienvenues ! Veuillez suivre ces étapes :
Ce projet est sous licence GNU General Public License v3.0. Voir le fichier LICENSE pour plus de détails.