USB流量数据包的取证初探以及CTF中的解题应用

有关USB协议的详细信息,请参见wikishark wikihttps : //wiki.wireshark.org/USB

  • 鼠标流量取证

    每个数据包的数据区有四个字节。第一个字节代表按钮。取0x00时,表示没有按钮。为0x01时,表示左键。当它是0x02时,表示当前按钮是右键。第二个字节可以被认为是带符号的字节类型,最高位是符号位。当该值为正时,表示鼠标水平向右移动多少像素。当它为负数时,表示向左移动了多少像素。第三个字节类似于第二个字节,代表垂直向上和向下移动的偏移量。

    当获取了这些点的信息之后,我们就可以恢复鼠标的轨迹。

    要想有流量包,必须先得想办法抓包,USB流量的捕获可以使用wireshark或者usbpcap来进行,最新版本的wireshark已经支持USB接口的捕获,且在安装时会提示usbpcap的安装,当前网上已有相关中文资料对wireshark抓取usb数据包的方法进行讲解,感兴趣的可以阅读参考链接。该软件的下载地址为 http://desowin.org/usbpcap/,可支持32位以及64位的winxp至win10操作系统,安装完成后须重启机器或者按照提示选择重启所有USB设备。

    我们以自己鼠标为例,打开wireshark,选取我们usb的监听

    image-20200920223057765

    然后用鼠标进行滑动等操作,当然点击左键和右键都是有不一样的数据。

    image-20200920222857520

    抓取到后我们保存流量包,这里保存为 mice.pcapng,我们先来分析一下这个流量包。

    因为本来就插着鼠标,我们抓取的流量也看不到认证始别之类的流量,后续在具体题目中会有提到。

    image-20200920225040744

    不同的鼠标抓到的流量不一样,一般的鼠标流量是四个字节,事实上,起作用的只是三个相邻的字节,比如我这里抓到的是5个字节,可以观察看到起作用的是2,3,4个字节,因此我们需要操作的数据在 0100fffb00上。

    tshark 安装:

    1
    $ apt-get install tshark -y

    接下来,使用 tshark 对数据进行提取:

    1
    $ tshark -r mice.pcapng -T fields -e usb.capdata > micedata

    对 tshark 更详细的命令,参考 https://www.wireshark.org/docs/man-pages/tshark.html

    image-20200920225420561

    数据大概是长这样子的

    image-20200920225505545

    这里提一下,测试发现,在Kali,Windows里面提取的时候,可能会出现没有冒号的情况,这样后期用脚本处理的时候就得修改一下,大概是版本的问题,在Ubuntu 16.04里,apt 默认安装的 tshark 是

    image-20200920225626489

    而在Kali和Windows里(这里以Windows为例),版本可能比较新

    image-20200920225746114

    提取的数据大概长这样的:

    image-20200920225902708

    不影响分析,但如果使用别人的脚本或者代码,软件时记得根据自己的情况修改。

    提取脚本后,我们对需要的数据位进行一个解析,通过它的方向,偏移量,我们得计算出它的像素点位置,然后借助 gnuplot 等绘图工具进行恢复:

    1
    awk -F: 'function comp(v){if(v>127)v-=256;return v}{x+=comp(strtonum("0x"$3));y+=comp(strtonum("0x"$4))}$2=="01"{print x,y}' micedata > pointdata

    这里将我们的数据处理好,以点的方式保存在一个文件里,如果出现类似这样的错误:

    1
    awk: line 2: function strtonum never defined

    安装一下 awk 即可:

    1
    $ sudo apt-get install gawk

    处理后的数据大概长这样的:

    image-20200920231252178

    接下来我们使用 gnuplot 来进行绘制:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $gnuplot
    G N U P L O T
    Version 5.0 patchlevel 3 last modified 2016-02-21
    Copyright (C) 1986-1993, 1998, 2004, 2007-2016
    Thomas Williams, Colin Kelley and many others
    gnuplot home: http://www.gnuplot.info
    faq, bugs, etc: type "help FAQ"
    immediate help: type "help" (plot window: hit 'h')
    Terminal type set to 'qt'
    gnuplot> plot "pointdata"

    于是我们可以看到鼠标的轨迹了

    image-20200920231516224

    当然这是反着的,我们用一些图片处理软件处理一下,就可以看到轨迹内容了,是一个 ‘flag’ 字样的轨迹

    img

    然后我们用一道CTF题来举例子,题目来源: Google CTF 2016,同时也是 ciscn 2020 华中赛区的misc题(flag都没改),题目数据包可以在这获取:https://rootusers.com/wp-content/uploads/2016/05/capture.pcapng

    打开数据包进行分析,可以看到认证等的信息,我们也可以从里面看到这个设备的信息,貌似是罗技的鼠标,然后我们用同样的方法对它的usb数据进行提取。

    image-20200920232138818

    这里的数据是四个字节的,那么我们基本可以判断是usb鼠标的取证了。

    image-20200920232331167

    接着用绘图工具,画出来的还是反的,但是难不倒ctfer。

    image-20200920232437388

    处理过后是这样的:

    img

    当然对于鼠标usb的取证也有一些脚本可以使用,比如 https://github.com/WangYihang/UsbMiceDataHacker

    下载 git clone https://github.com/WangYihang/UsbMiceDataHacker

    使用 python UsbMiceDataHacker.py capture.pacpng out.png

    image-20200920232824264

    使用这个脚本需要下载一些模块和软件:

    1
    2
    3
    $ pip install numpy
    $ pip install matplotlib
    $ apt-get install python-tk
  • 键盘流量取证

    键盘数据包的数据长度为8个字节,和击键信息被集中在第三个字节,每次key stroke都会产生一个keyboard event usb packet。

    在这里我们可以找到这个值与具体键位的对应关系:http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

    img

    同样地,我们用 Wireshark 抓取了我们 usb 键盘的流量,保存为 kb.pcapng,当没有什么混淆的时候,其实硬看也是可以一点一点看出来的,当时写 SarCTF 的时候,我还是先硬看出来最后才写的脚本。。。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #键盘数据转换,注意这个是没有用:分割的版本
    FILE = "data"

    switcher = {
    "04":"a", # or A
    "05":"b", # or B
    "06":"c", # or C
    "07":"d", # or D
    "08":"e", # or E
    "09":"f", # or F
    "0A":"g", # or G
    "0B":"h", # or H
    "0C":"i", # or I
    "0D":"j", # or J
    "0E":"k", # or K
    "0F":"l", # or L
    "10":"m", # or M
    "11":"n", # or N
    "12":"o", # or O
    "13":"p", # or P
    "14":"q", # or Q
    "15":"r", # or R
    "16":"s", # or S
    "17":"t", # or T
    "18":"u", # or U
    "19":"v", # or V
    "1A":"w", # or W
    "1B":"x", # or X
    "1C":"y", # or Y
    "1D":"x", # or Z
    "1E":"1", # or !
    "1F":"2", # or @
    "20":"3", # or #
    "21":"4", # or $
    "22":"5", # or %
    "23":"6", # or ^
    "24":"7", # or &
    "25":"8", # or *
    "26":"9", # or (
    "27":"0", # or )
    "2D":"-", # or _
    "2E":"+", # or =
    "2F":"[", # or {
    "30":"]", # or }
    "31":"\"", # or |
    "33":";", # or :
    "34":"'", # or "
    "35":"`", # or ~
    "36":",", # or <
    "37":".", # or >
    "38":"/" # or ?
    }

    with open(FILE) as f:
    data = f.readlines()
    for line in data:
    byte = line[4:6].upper()
    if byte in switcher:
    print(switcher[byte], end="")

    image-20200920234730353

    image-20200920234751692

    image-20200920234809014

    image-20200920234821077

比如我们看前四个,对照表,就可以翻译出前四个字符是 flag,因此往后继续识别就可以了。

跑一遍脚本,方括号和花括号是一样的,因此提交的时候自行修改一下就可以了。

image-20200920235644178

当然也有现成的项目,https://github.com/WangYihang/UsbKeyboardDataHacker

下载 git clone https://github.com/WangYihang/UsbKeyboardDataHacker

使用 python UsbKeyboardDataHacker.py kb.pcapng

image-20200920235909296

对于 SarCTF 的题目,我们也可以用这个脚本跑出来:

image-20200921000040861

当然还有一些师傅自己整合了一些情况的脚本:

[深入理解USB流量数据包的抓取与分析]

还有一些学习的文章:

从CTF中学USB流量捕获与解析

CTF-Wiki

Google CTF 2016 – Forensic “For2” Write-up


USB流量数据包的取证初探以及CTF中的解题应用
https://52hertz.tech/2020/09/20/usb_forensics/
作者
Ustin1an
发布于
2020年9月20日
许可协议