作为一名长期从事网络安全审计的技术人员,我经常需要处理各种设备通信数据的分析工作。USB设备作为最普遍的外设接口,其通信数据包中往往隐藏着关键的操作痕迹。最近我在一次CTF比赛中遇到了一个典型的USB流量分析题目,通过完整的数据包解析流程最终成功获取了flag。这个案例非常具有代表性,下面我将详细分享整个分析过程和技术要点。
USB设备通信数据包审计的核心价值在于还原设备操作轨迹。无论是键盘输入、鼠标移动还是存储设备读写,这些操作都会在USB协议层留下数据包记录。通过专业工具解析这些数据包,我们能够实现:
本次审计的目标文件包含三种关键数据包类型:
在开始审计前,需要准备以下工具链:
提示:建议使用Linux环境进行操作,所有工具均可通过apt-get等包管理器一键安装。Windows用户需要注意工具路径的环境变量配置。
tshark过滤语法:
bash复制tshark -r input.pcap -Y "usb.capdata" -T fields -e usb.capdata > output.txt
这个命令会从pcap文件中提取所有usb.capdata字段。-Y参数指定显示过滤器,-T fields定义输出格式,-e指定要提取的字段。
WinHex使用技巧:
Python环境依赖:
bash复制pip install scapy pyusb
Scapy库用于处理网络数据包,pyusb提供USB协议支持。
首先使用Wireshark打开原始pcap文件,观察数据包结构。通过显示过滤器筛选USB协议相关数据包:
code复制usb.transfer_type == 0x01 || usb.transfer_type == 0x02 || usb.transfer_type == 0x03
这分别对应控制传输(0x01)、等时传输(0x02)和批量传输(0x03)。
关键发现:
使用tshark提取所有BULK out包的Leftover Capture Data:
bash复制tshark -r input.pcap -Y "usb.transfer_type == 0x03 && usb.endpoint_number.direction == 0" -T fields -e usb.capdata | xxd -r -p > output.bin
这里xxd工具将十六进制字符串转换回二进制格式。
多个分段文件需要按顺序拼接:
bash复制cat part1.bin part2.bin part3.bin > all.bin
验证文件完整性:
bash复制md5sum all.bin
wc -c all.bin
使用WinHex打开all.bin文件,搜索魔术字"d4c3b2a1"(小端序的pcap文件标识)。找到后,从该位置开始提取数据。
编写Python转换脚本:
python复制import binascii
with open('all.bin', 'rb') as f:
data = f.read()
pcap_start = data.find(b'\xd4\xc3\xb2\xa1')
if pcap_start != -1:
with open('output.pcap', 'wb') as out:
out.write(data[pcap_start:])
从转换后的pcap中提取usb.capdata:
bash复制tshark -r output.pcap -Y "usb.capdata" -T fields -e usb.capdata > keystrokes.txt
典型键盘数据包为8字节,结构如下:
code复制字节1:修饰键状态(Shift/Ctrl/Alt等)
字节2:保留
字节3-8:按键扫描码
创建基础键值映射表:
python复制keymap = {
0x04: 'a', 0x05: 'b', 0x06: 'c',
0x07: 'd', 0x08: 'e', 0x09: 'f',
0x0A: 'g', 0x0B: 'h', 0x0C: 'i',
# 完整映射表参考USB HID标准
}
处理修饰键逻辑:
python复制def decode_keystroke(data):
modifiers = data[0]
shift_pressed = modifiers & 0x02
keycode = data[2]
if keycode in keymap:
char = keymap[keycode]
return char.upper() if shift_pressed else char
return ''
最终解析出的按键序列组合形成了flag{u5b_key}。
现象:拼接后的文件无法识别为有效PCAP
排查:
解决方案:
bash复制file all.bin # 验证文件类型
hexdump -C all.bin | head # 查看文件头
现象:解码出的字符不符合预期
原因:
验证方法:
python复制# 打印原始数据包
for packet in keystrokes:
print(binascii.hexlify(packet))
对于大型数据包文件,可以采用:
示例:
bash复制tshark -r large.pcap -R "usb.capdata" -2 -T fields -e usb.capdata | parallel --pipe python process_chunk.py
USB鼠标数据通常包含:
解析示例:
python复制def decode_mouse(data):
x = data[1] if data[1] < 128 else data[1] - 256
y = data[2] if data[2] < 128 else data[2] - 256
left = data[0] & 0x01
right = data[0] & 0x02
return x, y, left, right
对于USB大容量存储设备:
关键命令:
bash复制# 提取USB Mass Storage通信
tshark -r input.pcap -Y "usb.bulk" -T json > bulk_data.json
可疑特征包括:
检测脚本示例:
python复制def check_anomalies(packets):
sizes = [len(p) for p in packets]
avg = sum(sizes)/len(sizes)
return any(s > 2*avg for s in sizes)
在实际操作中,有几点关键经验值得分享:
数据验证必不可少:在每个处理阶段都应该进行完整性校验,比如使用checksum验证文件拼接是否正确。我曾遇到过因为文件顺序错位导致整个分析失败的情况。
键值映射要灵活:不同厂商的USB设备可能有细微的键值差异,建议先捕获已知输入来建立映射基准。有些特殊键盘的Fn键组合需要特别注意。
时间戳分析价值:USB数据包的时间戳信息往往被忽视,但实际上对于还原操作时序非常有帮助。在分析复杂交互时,我会专门绘制事件时间线。
环境隔离建议:分析未知USB数据时,最好在隔离的虚拟环境中进行。曾经有一次分析过程中意外触发了设备固件中的异常行为。
脚本化处理流程:对于重复性分析工作,建议将每个步骤封装为脚本。这样不仅提高效率,也便于复查和分享。我的工具库中保存了各种USB分析脚本模板。