分析USB设备连接历史记录 是做什么的?
何时使用
- 调查通过可移动存储设备进行的潜在数据泄露时
- 在内部威胁调查中追踪USB设备使用情况
- 用于验证可移动介质策略执行的合规性审计
- 关联USB连接与文件访问和复制事件时
- 在事件响应期间建立设备连接时间线
前提条件
- 取证镜像或提取的注册表配置单元和事件日志
- 访问SYSTEM、SOFTWARE和NTUSER.DAT注册表配置单元
- SetupAPI日志 (setupapi.dev.log)
- Windows事件日志(系统、安全、DriverFrameworks-UserMode)
- USBDeview、USB Forensic Tracker或RegRipper
- 了解USB设备标识(VID、PID、序列号)
工作流程
步骤1:提取USB相关工件
# 挂载取证镜像并复制相关工件
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/evidence.dd /mnt/evidence
mkdir -p /cases/case-2024-001/usb/
# 注册表配置单元
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/
# SetupAPI日志(首次连接时间戳)
cp /mnt/evidence/Windows/INF/setupapi.dev.log /cases/case-2024-001/usb/
# 事件日志
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
步骤2:解析USBSTOR注册表键
# 从SYSTEM配置单元中提取USBSTOR条目
python3 << 'PYEOF'
from Registry import Registry
import json
reg = Registry.Registry("/cases/case-2024-001/usb/SYSTEM")
# 查找当前ControlSet
select = reg.open("Select")
current = select.value("Current").value()
controlset = f"ControlSet{current:03d}"
# 解析USBSTOR
usbstor_path = f"{controlset}\\Enum\\USBSTOR"
usbstor = reg.open(usbstor_path)
devices = []
print("=== USBSTOR设备 ===\n")
for device_class in usbstor.subkeys():
# 格式: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 '未知'
product = parts[2].replace('Prod_', '') if len(parts) > 2 else '未知'
revision = parts[3].replace('Rev_', '') if len(parts) > 3 else '未知'
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),
}
# 获取友好名称(如果可用)
try:
friendly = instance.value("FriendlyName").value()
device_info['friendly_name'] = friendly
except:
pass
# 获取设备参数
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"设备:{vendor} {product}")
print(f" 序列号:{serial}")
print(f" 最后连接:{last_write}")
print(f" 友好名称:{device_info.get('friendly_name', 'N/A')}")
print()
# 保存结果
with open('/cases/case-2024-001/analysis/usb_devices.json', 'w') as f:
json.dump(devices, f, indent=2)
print(f"\n找到的USB存储设备总数:{len(devices)}")
PYEOF
步骤3:提取驱动器号分配和用户关联
# 从SYSTEM配置单元解析MountedDevices
python3 << 'PYEOF'
from Registry import Registry
import struct
reg = Registry.Registry("/cases/case-2024-001/usb/SYSTEM")
mounted = reg.open("MountedDevices")
print("=== 挂载的设备(驱动器号分配)===\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:
# USB设备 - 包含设备路径字符串
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:
# 固定磁盘 - 包含磁盘签名+偏移量
disk_sig = struct.unpack('<I', data[0:4])[0]
offset = struct.unpack('<Q', data[4:12])[0]
print(f" {drive_letter} -> 磁盘签名:0x{disk_sig:08X}, 偏移量:{offset}")
PYEOF
# 解析用户MountPoints2(哪些用户访问了哪些设备)
python3 << 'PYEOF'
from Registry import Registry
import os, glob
print("\n=== 用户挂载点 (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"用户配置单元:{os.path.basename(ntuser)}")
for key in mp2.subkeys():
guid = key.name()
last_write = key.timestamp()
if '{' in guid:
print(f" 卷:{guid} | 最后访问:{last_write}")
print()
except Exception as e:
print(f" 解析 {ntuser} 时出错:{e}")
PYEOF
步骤4:从SetupAPI提取首次连接时间戳
# 解析setupapi.dev.log以获取USB设备的首次安装时间戳
python3 << 'PYEOF'
import re
print("=== SETUPAPI USB设备安装 ===\n")
with open('/cases/case-2024-001/usb/setupapi.dev.log', 'r', errors='ignore') as f:
content = f.read()
# 查找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:
# 提取设备ID
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"\n找到的USB安装总数:{len(usb_installs)}")
PYEOF
# 解析Windows事件日志中的USB事件
# 事件ID:2003, 2010, 2100, 2102 (DriverFrameworks-UserMode)
# 事件ID:6416 (安全 - 新外部设备被识别)
python3 << 'PYEOF'
import json
from evtx import PyEvtxParser
try:
parser = PyEvtxParser("/cases/case-2024-001/usb/System.evtx")
print("\n=== 系统事件日志USB事件 ===\n")
for record in parser.records_json():
data = json.loads(record['data'])
event_id = str(data['Event']['System']['EventID'])
# 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}] 事件ID {event_id}: {json.dumps(event_data, default=str)[:200]}")
except Exception as e:
print(f"错误:{e}")
PYEOF
步骤5:构建USB活动时间线和报告
# 将所有USB证据编译成统一的时间线
python3 << 'PYEOF'
import json, csv
timeline = []
# 加载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': 'USBSTOR注册表',
'device': f"{device['vendor']} {device['product']}",
'serial': device['serial'],
'event': '最后连接',
'detail': device.get('friendly_name', '')
})
# 按时间排序
timeline.sort(key=lambda x: x['timestamp'])
# 写入时间线CSV
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"USB时间线:{len(timeline)} 个事件已写入 usb_timeline.csv")
# 打印摘要
print("\n=== USB设备摘要 ===")
for entry in timeline:
print(f" {entry['timestamp']} | {entry['device']} | {entry['serial'][:20]} | {entry['event']}")
PYEOF
关键概念
| 概念 | 描述 |
|---|---|
| USBSTOR | 存储USB大容量存储设备标识和连接数据的注册表键 |
| VID/PID | 供应商ID和产品ID,唯一标识USB设备制造商和型号 |
| 设备序列号 | 单个USB设备的唯一标识符(某些设备共享序列号) |
| MountedDevices | 将卷GUID和驱动器号映射到物理设备的注册表键 |
| MountPoints2 | 每个用户的注册表键,显示用户访问过哪些卷 |
| SetupAPI日志 | Windows驱动程序安装日志,记录首次设备连接时间 |
| DeviceContainers | SOFTWARE配置单元中的注册表键,包含设备元数据和时间戳 |
| EMDMgmt | 跟踪ReadyBoost兼容设备的注册表键,包含序列号和时间戳 |
工具与系统
| 工具 | 用途 |
|---|---|
| USB Forensic Tracker | 用于提取USB设备历史记录的专业工具 |
| USBDeview | NirSoft工具,列出连接到系统的所有USB设备 |
| RegRipper (usbstor插件) | 自动从注册表配置单元提取USB工件 |
| Registry Explorer | 交互式注册表分析,用于USB相关键 |
| KAPE | 自动收集USB相关工件 |
| Plaso/log2timeline | 创建时间线,包括USB连接事件 |
| FTK Imager | 取证成像,包括可移动介质 |
| Velociraptor | 端点代理,具有USB设备历史记录狩猎工件 |
常见场景
场景1:离职员工数据泄露 提取USBSTOR条目以识别所有曾经连接过的USB设备,将设备序列号与MountPoints2关联以确认用户访问,将时间戳与文件访问日志和Jump List最近文件进行交叉引用,检查USN日志中的大文件复制模式。
场景2:安全系统上的未授权设备 审计所有USBSTOR条目与已批准设备列表,通过VID/PID识别与公司批准的硬件不匹配的未授权设备,确定未授权设备首次和最后连接的时间,检查是否有任何数据传输。
场景3:通过USB传播恶意软件 识别在恶意软件执行之前连接的USB设备(Prefetch时间戳),提取设备序列号和供应商信息,检查设备是否启用了自动运行,在Prefetch和ShimCache中查找从可移动驱动器号启动的可执行文件。
场景4:跨多个系统追踪特定USB驱动器 在所有取证镜像的USBSTOR中搜索相同的设备序列号,构建驱动器连接到哪些系统以及何时连接的地图,识别设备在组织中的时间路径,与网络共享访问日志进行关联。
输出格式
USB设备历史分析:
系统:DESKTOP-ABC123 (Windows 10 Pro)
USB存储设备总数:12
分析来源:USBSTOR、MountedDevices、MountPoints2、SetupAPI、事件日志
设备清单:
1. Kingston DataTraveler 3.0 (序列号:0019E06B4521A2B0)
首次连接: 2024-01-10 09:15:32 (SetupAPI)
最后连接: 2024-01-18 14:30:00 (USBSTOR)
驱动器号: E:
用户访问: suspect_user (MountPoints2)
2. WD My Passport (序列号:575834314131363035)
首次连接: 2024-01-15 20:00:00
最后连接: 2024-01-15 23:45:00
驱动器号: F:
用户访问: suspect_user
可疑发现:
- Kingston驱动器在调查期间连接了15次
- WD Passport仅连接一次,时间在深夜(非正常时间)
- 未知设备 (VID_1234&PID_5678) 于 2024-01-17 连接,未匹配到已批准设备
时间线:/cases/case-2024-001/analysis/usb_timeline.csv