Analyse de l'historique des connexions de périphériques USB
Quand utiliser
- Lors d'une enquête sur une exfiltration potentielle de données via des supports amovibles
- Lors d'enquêtes sur les menaces internes pour suivre l'utilisation de périphériques USB
- Pour des audits de conformité vérifiant l'application des politiques de supports amovibles
- Lors de la corrélation des connexions USB avec les événements d'accès et de copie de fichiers
- Pour établir une chronologie des connexions de périphériques lors d'un incident
Prérequis
- Image forensique ou ruches de registre et journaux d'événements extraits
- Accès aux ruches de registre SYSTEM, SOFTWARE et NTUSER.DAT
- Journaux SetupAPI (setupapi.dev.log)
- Journaux d'événements Windows (Système, Sécurité, DriverFrameworks-UserMode)
- USBDeview, USB Forensic Tracker ou RegRipper
- Compréhension de l'identification des périphériques USB (VID, PID, numéro de série)
Workflow
Étape 1 : Extraire les artefacts liés à l'USB
# Monter l'image forensique et copier les artefacts pertinents
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/evidence.dd /mnt/evidence
mkdir -p /cases/case-2024-001/usb/
# Ruches de registre
cp /mnt/evidence/Windows/System32/config/SYSTEM /cases/case-2024-001/usb/
cp /mnt/evidence/Windows/System32/config/SOFTWARE /cases/case-2024-001/usb/
cp /mnt/evidence/Users/*/NTUSER.DAT /cases/case-2024-001/usb/
# Journaux SetupAPI (horodatages de première connexion)
cp /mnt/evidence/Windows/INF/setupapi.dev.log /cases/case-2024-001/usb/
# Journaux d'événements
cp /mnt/evidence/Windows/System32/winevt/Logs/System.evtx /cases/case-2024-001/usb/
cp "/mnt/evidence/Windows/System32/winevt/Logs/Microsoft-Windows-DriverFrameworks-UserMode%4Operational.evtx" \
/cases/case-2024-001/usb/ 2>/dev/null
cp "/mnt/evidence/Windows/System32/winevt/Logs/Microsoft-Windows-Partition%4Diagnostic.evtx" \
/cases/case-2024-001/usb/ 2>/dev/null
Étape 2 : Analyser la clé de registre USBSTOR
# Extraire les entrées USBSTOR de la ruche SYSTEM
python3 << 'PYEOF'
from Registry import Registry
import json
reg = Registry.Registry("/cases/case-2024-001/usb/SYSTEM")
# Trouver le ControlSet actuel
select = reg.open("Select")
current = select.value("Current").value()
controlset = f"ControlSet{current:03d}"
# Analyser USBSTOR
usbstor_path = f"{controlset}\\Enum\\USBSTOR"
usbstor = reg.open(usbstor_path)
devices = []
print("=== PÉRIPHÉRIQUES USBSTOR ===\n")
for device_class in usbstor.subkeys():
# Format : Disk&Ven_VENDOR&Prod_PRODUCT&Rev_REVISION
class_name = device_class.name()
parts = class_name.split('&')
vendor = parts[1].replace('Ven_', '') if len(parts) > 1 else 'Inconnu'
product = parts[2].replace('Prod_', '') if len(parts) > 2 else 'Inconnu'
revision = parts[3].replace('Rev_', '') if len(parts) > 3 else 'Inconnu'
for instance in device_class.subkeys():
serial = instance.name()
last_write = instance.timestamp()
device_info = {
'vendor': vendor,
'product': product,
'revision': revision,
'serial': serial,
'last_connected': str(last_write),
}
# Obtenir le nom convivial si disponible
try:
friendly = instance.value("FriendlyName").value()
device_info['friendly_name'] = friendly
except:
pass
# Obtenir les paramètres du périphérique
try:
params = instance.subkey("Device Parameters")
try:
device_info['class_guid'] = params.value("ClassGUID").value()
except:
pass
except:
pass
devices.append(device_info)
print(f"Périphérique : {vendor} {product}")
print(f" Série : {serial}")
print(f" Dernière connexion : {last_write}")
print(f" Nom convivial : {device_info.get('friendly_name', 'N/A')}")
print()
# Enregistrer les résultats
with open('/cases/case-2024-001/analysis/usb_devices.json', 'w') as f:
json.dump(devices, f, indent=2)
print(f"\nTotal de périphériques de stockage USB trouvés : {len(devices)}")
PYEOF
Étape 3 : Extraire les lettres de lecteur et les associations utilisateur
# Analyser MountedDevices depuis la ruche SYSTEM
python3 << 'PYEOF'
from Registry import Registry
import struct
reg = Registry.Registry("/cases/case-2024-001/usb/SYSTEM")
mounted = reg.open("MountedDevices")
print("=== PÉRIPHÉRIQUES MONTÉS (Attributions de lettres de lecteur) ===\n")
for value in mounted.values():
name = value.name()
data = value.value()
if name.startswith("\\DosDevices\\"):
drive_letter = name.replace("\\DosDevices\\", "")
if len(data) > 24:
# Périphérique USB - contient le chemin du périphérique
try:
device_path = data.decode('utf-16-le').strip('\x00')
if 'USBSTOR' in device_path or 'USB#' in device_path:
print(f" {drive_letter} -> {device_path}")
except:
pass
else:
# Disque fixe - contient la signature du disque + décalage
disk_sig = struct.unpack('<I', data[0:4])[0]
offset = struct.unpack('<Q', data[4:12])[0]
print(f" {drive_letter} -> Signature disque : 0x{disk_sig:08X}, Décalage : {offset}")
PYEOF
# Analyser les points de montage utilisateur (MountPoints2) - quel utilisateur a accédé à quels périphériques
python3 << 'PYEOF'
from Registry import Registry
import os, glob
print("\n=== POINTS DE MONTAGE UTILISATEUR (MountPoints2) ===\n")
for ntuser in glob.glob("/cases/case-2024-001/usb/NTUSER*.DAT"):
try:
reg = Registry.Registry(ntuser)
mp2 = reg.open("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2")
print(f"Ruche utilisateur : {os.path.basename(ntuser)}")
for key in mp2.subkeys():
guid = key.name()
last_write = key.timestamp()
if '{' in guid:
print(f" Volume : {guid} | Dernier accès : {last_write}")
print()
except Exception as e:
print(f" Erreur lors de l'analyse de {ntuser} : {e}")
PYEOF
Étape 4 : Extraire les horodatages de première connexion depuis SetupAPI
# Analyser setupapi.dev.log pour les horodatages de première installation des périphériques USB
python3 << 'PYEOF'
import re
print("=== INSTALLATIONS DE PÉRIPHÉRIQUES USB SETUPAPI ===\n")
with open('/cases/case-2024-001/usb/setupapi.dev.log', 'r', errors='ignore') as f:
content = f.read()
# Trouver les sections d'installation des périphériques USB
pattern = r'>>>\s+\[Device Install.*?\n.*?Section start (\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}).*?\n(.*?)<<<'
matches = re.findall(pattern, content, re.DOTALL)
usb_installs = []
for timestamp, section in matches:
if 'USBSTOR' in section or 'USB\\VID' in section:
# Extraire l'ID du périphérique
dev_match = re.search(r'(USBSTOR\\[^\s]+|USB\\VID_\w+&PID_\w+[^\s]*)', section)
if dev_match:
device_id = dev_match.group(1)
usb_installs.append({
'first_install': timestamp,
'device_id': device_id
})
print(f" {timestamp} | {device_id}")
print(f"\nTotal d'installations USB trouvées : {len(usb_installs)}")
PYEOF
# Analyser les journaux d'événements Windows pour les événements USB
# ID d'événement : 2003, 2010, 2100, 2102 (DriverFrameworks-UserMode)
# ID d'événement : 6416 (Sécurité - nouveau périphérique externe reconnu)
python3 << 'PYEOF'
import json
from evtx import PyEvtxParser
try:
parser = PyEvtxParser("/cases/case-2024-001/usb/System.evtx")
print("\n=== ÉVÉNEMENTS USB DU JOURNAL SYSTÈME ===\n")
for record in parser.records_json():
data = json.loads(record['data'])
event_id = str(data['Event']['System']['EventID'])
# Événements de connexion de périphérique USB
if event_id in ('20001', '20003', '10000', '10100'):
timestamp = data['Event']['System']['TimeCreated']['#attributes']['SystemTime']
event_data = data['Event'].get('UserData', data['Event'].get('EventData', {}))
print(f" [{timestamp}] EventID {event_id}: {json.dumps(event_data, default=str)[:200]}")
except Exception as e:
print(f"Erreur : {e}")
PYEOF
Étape 5 : Construire la chronologie et le rapport d'activité USB
# Compiler toutes les preuves USB dans une chronologie unifiée
python3 << 'PYEOF'
import json, csv
timeline = []
# Charger les données USBSTOR
with open('/cases/case-2024-001/analysis/usb_devices.json') as f:
devices = json.load(f)
for device in devices:
timeline.append({
'timestamp': device['last_connected'],
'source': 'Registre USBSTOR',
'device': f"{device['vendor']} {device['product']}",
'serial': device['serial'],
'event': 'Dernière connexion',
'detail': device.get('friendly_name', '')
})
# Trier chronologiquement
timeline.sort(key=lambda x: x['timestamp'])
# Écrire le CSV de la chronologie
with open('/cases/case-2024-001/analysis/usb_timeline.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['timestamp', 'source', 'device', 'serial', 'event', 'detail'])
writer.writeheader()
writer.writerows(timeline)
print(f"Chronologie USB : {len(timeline)} événements écrits dans usb_timeline.csv")
# Afficher le résumé
print("\n=== RÉSUMÉ DES PÉRIPHÉRIQUES USB ===")
for entry in timeline:
print(f" {entry['timestamp']} | {entry['device']} | {entry['serial'][:20]} | {entry['event']}")
PYEOF
Concepts clés
| Concept | Description |
|---|---|
| USBSTOR | Clé de registre stockant les données d'identification et de connexion des périphériques de stockage de masse USB |
| VID/PID | Identifiant fabricant (Vendor ID) et identifiant produit (Product ID) identifiant de manière unique le fabricant et le modèle du périphérique USB |
| Numéro de série du périphérique | Identifiant unique pour chaque périphérique USB (certains périphériques partagent des numéros de série) |
| MountedDevices | Clé de registre mappant les GUID de volume et les lettres de lecteur aux périphériques physiques |
| MountPoints2 | Clé de registre par utilisateur montrant à quels volumes un utilisateur a accédé |
| Journal SetupAPI | Journal d'installation des pilotes Windows enregistrant les connexions de périphériques pour la première fois |
| DeviceContainers | Clé de registre dans la ruche SOFTWARE contenant les métadonnées et les horodatages des périphériques |
| EMDMgmt | Clé de registre suivant les périphériques compatibles ReadyBoost avec les numéros de série et les horodatages |
Outils et systèmes
| Outil | Objectif |
|---|---|
| USB Forensic Tracker | Outil spécialisé pour l'extraction de l'historique des périphériques USB |
| USBDeview | Outil NirSoft listant tous les périphériques USB connectés à un système |
| RegRipper (plugin usbstor) | Extraction automatisée des artefacts USB à partir des ruches de registre |
| Registry Explorer | Analyse interactive du registre pour les clés liées à l'USB |
| KAPE | Collecte automatisée des artefacts liés à l'USB |
| Plaso/log2timeline | Création de chronologies incluant les événements de connexion USB |
| FTK Imager | Imagerie forensique incluant les supports amovibles |
| Velociraptor | Agent de point de terminaison avec des artefacts de chasse à l'historique des périphériques USB |
Scénarios courants
Scénario 1 : Exfiltration de données par un employé qui quitte l'entreprise Extraire les entrées USBSTOR pour identifier tous les périphériques USB jamais connectés, corréler les numéros de série des périphériques avec MountPoints2 pour confirmer l'accès de l'utilisateur, recouper les horodatages avec les journaux d'accès aux fichiers et les fichiers récents de la liste de saut, rechercher des modèles de copie de gros fichiers dans le journal USN.
Scénario 2 : Périphérique non autorisé sur un système sécurisé Auditer toutes les entrées USBSTOR par rapport à la liste des périphériques approuvés, identifier les périphériques non autorisés par VID/PID ne correspondant pas au matériel approuvé par l'entreprise, déterminer quand le périphérique non autorisé a été connecté pour la première et la dernière fois, vérifier si des données ont été transférées.
Scénario 3 : Distribution de logiciels malveillants via USB Identifier le périphérique USB connecté juste avant l'exécution du logiciel malveillant (horodatages Prefetch), extraire le numéro de série et les informations du fabricant du périphérique, vérifier si l'exécution automatique était activée pour le périphérique, rechercher le lancement d'un exécutable à partir de la lettre de lecteur amovible dans Prefetch et ShimCache.
Scénario 4 : Suivi d'un périphérique USB spécifique sur plusieurs systèmes Rechercher le même numéro de série de périphérique dans USBSTOR sur toutes les images forensiques, construire une carte des systèmes sur lesquels le périphérique a été connecté et quand, identifier le chemin chronologique du périphérique à travers l'organisation, corréler avec les journaux d'accès au partage réseau.
Format de sortie
Analyse de l'historique des périphériques USB :
Système : DESKTOP-ABC123 (Windows 10 Pro)
Total de périphériques de stockage USB : 12
Sources d'analyse : USBSTOR, MountedDevices, MountPoints2, SetupAPI, Journaux d'événements
Inventaire des périphériques :
1. Kingston DataTraveler 3.0 (Série : 0019E06B4521A2B0)
Première connexion : 2024-01-10 09:15:32 (SetupAPI)
Dernière connexion : 2024-01-18 14:30:00 (USBSTOR)
Lettre de lecteur : E :
Accès utilisateur : suspect_user (MountPoints2)
2. WD My Passport (Série : 575834314131363035)
Première connexion : 2024-01-15 20:00:00
Dernière connexion : 2024-01-15 23:45:00
Lettre de lecteur : F :
Accès utilisateur : suspect_user
Résultats suspects :
- Le périphérique Kingston connecté 15 fois pendant la période d'enquête
- Le WD Passport connecté une seule fois, tard le soir (heures inhabituelles)
- Périphérique inconnu (VID_1234&PID_5678) connecté le 2024-01-17, aucun périphérique approuvé correspondant
Chronologie : /cases/case-2024-001/analysis/usb_timeline.csv