CTF实战从USB鼠标流量到Flag我是如何用Wireshark和gnuplot一步步画出来的第一次参加BUU CTF比赛时我遇到了一道关于USB鼠标流量分析的题目。作为一个刚入门的新手面对一堆看似杂乱无章的流量数据我完全不知道从何下手。经过几天的摸索和无数次的失败尝试我终于成功提取出了隐藏在鼠标移动轨迹中的Flag。下面我将详细记录整个解题过程希望能帮助其他遇到类似问题的CTF爱好者。1. 初步分析捕获文件拿到题目提供的pcap文件后我首先用Wireshark打开查看。在过滤器中输入usb可以看到大量的USB HID数据包。这些数据包包含了鼠标的移动和点击信息。关键观察点每个数据包都包含8字节的Leftover Capture Data数据格式符合典型的USB鼠标流量特征为了更深入地分析我决定使用tshark工具提取原始数据tshark -r usb.pcap -T fields -e usb.capdata usbdata.txt但运行后发现生成的文件中有很多空行这会影响后续处理。经过搜索我找到了解决方案tshark -r usb.pcap -T fields -e usb.capdata | sed /^\s*$/d usbdata.txt提示使用sed命令可以过滤掉空行确保数据文件干净整洁2. 解析鼠标数据格式USB鼠标流量通常由4个字节组成8个十六进制字符每个字节都有特定含义字节位置含义说明1-2按键状态0x00无按键0x01左键0x02右键3-4X轴移动有符号数正数右移负数左移5-6Y轴移动有符号数正数下移负数上移7-8滚轮本题中未使用我编写了一个Python脚本来解析这些数据def parse_mouse_data(input_file, output_file): with open(input_file, r) as f_in, open(output_file, w) as f_out: for line in f_in: line line.strip() if len(line) 8: # 确保是鼠标数据 # 格式化输出为冒号分隔 formatted :.join([line[i:i2] for i in range(0, 8, 2)]) f_out.write(formatted \n)3. 处理坐标数据将原始数据转换为坐标点时我遇到了几个关键问题符号位处理鼠标移动数据是有符号的需要正确处理负数按键过滤只需要记录特定按键状态下的坐标累积坐标需要累加每次的偏移量而不是使用绝对值经过多次调试最终的处理代码如下def convert_to_coordinates(input_file, output_file): pos_x, pos_y 0, 0 with open(input_file, r) as f_in, open(output_file, w) as f_out: for line in f_in: if len(line.strip()) ! 11: # 包括冒号和换行符 continue parts line.strip().split(:) btn int(parts[0], 16) x int(parts[1], 16) y int(parts[2], 16) # 处理有符号数 if x 127: x - 256 if y 127: y - 256 pos_x x pos_y y # 只记录右键点击时的坐标 if btn 0x02: f_out.write(f{pos_x} {pos_y}\n)注意在实际比赛中可能需要尝试不同的按键过滤条件本题中右键点击时的坐标才是关键4. 使用gnuplot绘制轨迹有了坐标数据后我尝试用gnuplot绘制鼠标移动轨迹。最初直接使用gnuplot -e plot xy.txt with lines; pause -1但发现图形太小无法辨认。经过多次调整最终确定了合适的参数gnuplot -e set terminal png size 1024,768; set output flag.png; plot xy.txt with lines lw 2;关键参数说明set terminal png size 1024,768设置输出图片大小with lines lw 2使用线宽为2的线条连接点绘制出的图形清晰地显示了Flag内容。整个过程让我深刻体会到CTF比赛中流量分析题目不仅需要技术知识更需要耐心和细致的调试。