编辑“︁
USB
”︁(章节)
跳转到导航
跳转到搜索
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= USB = == 简介 == '''USB详述''': [https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf] * 鼠标协议 鼠标移动时表现为连续性,与键盘击键的离散性不一样,不过实际上鼠标动作所产生的数据包也是离散的,毕竟计算机表现的连续性信息都是由大量离散信息构成的 [[File:./figure/mouse.png|mouse]] 每一个数据包的数据区有四个字节,第一个字节代表按键,当取0x00时,代表没有按键、为0x01时,代表按左键,为0x02时,代表当前按键为右键。第二个字节可以看成是一个signed byte类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。 得到这些点的信息后,即可恢复出鼠标移动轨迹 * Tools ** [https://github.com/WangYihang/UsbMiceDataHacker UsbMiceDataHacker] * 键盘协议 键盘数据包的数据长度为8个字节,击键信息集中在第3个字节 [[File:./figure/keyboard.png|keyboard]] 根据data值与具体键位的对应关系 [[File:./figure/keyboard_pro.png|keyboard_pro]] 可从数据包恢复出键盘的案件信息 * Tools ** [https://github.com/WangYihang/UsbKeyboardDataHacker UsbKeyboardDataHacker] '''参考''' * https://www.anquanke.com/post/id/85218 == 例题 == <blockquote><code>Xman</code>三期夏令营排位赛练习题:<code>AutoKey</code> WP:https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html </blockquote> 问题描述: [[File:./figure/task_AutoKey.png|task_AutoKey]] 这道题是我参加 <code>Xman</code> 三期夏令营选拔赛出的一道题,我们如何对其进行分析? <span id="流量包是如何捕获的"></span> === 流量包是如何捕获的? === 首先我们从上面的数据包分析可以知道,这是个 <code>USB</code> 的流量包,我们可以先尝试分析一下 <code>USB</code> 的数据包是如何捕获的。 在开始前,我们先介绍一些 <code>USB</code> 的基础知识。 <code>USB</code> 有不同的规格,以下是使用 <code>USB</code> 的三种方式: <syntaxhighlight lang="shell">l USB UART l USB HID l USB Memory</syntaxhighlight> <code>UART</code> 或者 <code>Universal Asynchronous Receiver/Transmitter</code> 。这种方式下,设备只是简单的将 <code>USB</code> 用于接受和发射数据,除此之外就再没有其他通讯功能了。 <code>HID</code> 是人性化的接口。这一类通讯适用于交互式,有这种功能的设备有:键盘,鼠标,游戏手柄和数字显示设备。 最后是 <code>USB Memory</code> ,或者说是数据存储。 <code>External HDD</code> , <code>thumb drive/flash drive</code> 等都是这一类的。 其中使用的最广的不是 <code>USB HID</code> 就是 <code>USB Memory</code> 了。 每一个 <code>USB</code> 设备(尤其是 <code>HID</code> 或者 <code>Memory</code> )都有一个供应商 <code>ID(Vendor ID)</code> 和产品识别码<code>(Product Id)</code> 。 <code>Vendor ID</code> 是用来标记哪个厂商生产了这个 <code>USB</code> 设备。 <code>Product ID</code> 用来标记不同的产品,他并不是一个特殊的数字,当然最好不同。如下图: [[File:./figure/Product-ID.png|Product-ID]] 上图是我在虚拟机环境下连接在我电脑上的 <code>USB</code> 设备列表,通过 <code>lsusb</code> 查看命令。 例如说,我在 <code>VMware</code> 下有一个无线鼠标。它是属于 <code>HID</code> 设备。这个设备正常的运行,并且通过<code>lsusb</code> 这个命令查看所有 <code>USB</code> 设备,现在大家能找出哪一条是这个鼠标吗??没有错,就是第四个,就是下面这条: <syntaxhighlight lang="shell">Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse</syntaxhighlight> 其中,<code>ID 0e0f:0003</code> 就是 <code>Vendor-Product ID</code> 对, <code>Vendor ID</code> 的值是 <code>0e0f</code> ,并且 <code>Product ID</code> 的值是 <code>0003</code> 。 <code>Bus 002 Device 002</code> 代表 <code>usb</code> 设备正常连接,这点需要记下来。 我们用 <code>root</code> 权限运行 <code>Wireshark</code> 捕获 <code>USB</code> 数据流。但是通常来说我们不建议这么做。我们需要给用户足够的权限来获取 <code>Linux</code> 中的 <code>usb</code> 数据流。我们可以用 <code>udev</code> 来达到我们的目的。我们需要创建一个用户组 <code>usbmon</code> ,然后把我们的账户添加到这个组中。 <syntaxhighlight lang="shell">addgroup usbmon gpasswd -a $USER usbmon echo 'SUBSYSTEM=="usbmon", GROUP="usbmon", MODE="640"' > /etc/udev/rules.d/99-usbmon.rules</syntaxhighlight> 接下来,我们需要 <code>usbmon</code> 内核模块。如果该模块没有被加载,我们可以通过以下命令加载该模块: <syntaxhighlight lang="shell">modprobe usbmon</syntaxhighlight> 打开 <code>wireshark</code> ,你会看到 <code>usbmonX</code> 其中 <code>X</code> 代表数字。下图是我们本次的结果(我使用的是<code>root </code>): [[File:./figure/usbmon0.png|usbmon0]] 如果接口处于活跃状态或者有数据流经过的时候, <code>wireshark</code> 的界面就会把它以波形图的方式显示出来。那么,我们该选那个呢?没有错,就是我刚刚让大家记下来的,这个X的数字就是对应这 <code>USB Bus</code> 。在本文中是 <code>usbmon0</code> 。打开他就可以观察数据包了。 [[File:./figure/analysis-usbmon0.png|analysis-usbmon0]] 通过这些,我们可以了解到 <code>usb</code> 设备与主机之间的通信过程和工作原理,我们可以来对流量包进行分析了。 <span id="如何去分析一个usb流量包"></span> === 如何去分析一个USB流量包? === 根据前面的知识铺垫,我们大致对 <code>USB</code> 流量包的抓取有了一个轮廓了,下面我们介绍一下如何分析一个 <code>USB</code> 流量包。 <code>USB</code> 协议的细节方面参考 <code>wireshark</code> 的 <code>wiki</code> :https://wiki.wireshark.org/USB 我们先拿 <code>GitHub</code> 上一个简单的例子开始讲起: [[File:./figure/example-usbpcap.png|example-usbpcap]] 我们分析可以知道, <code>USB</code> 协议的数据部分在 <code>Leftover Capture Data</code> 域之中,在 <code>Mac</code> 和 <code>Linux</code> 下可以用 <code>tshark</code> 命令可以将 <code>leftover capture data</code> 单独提取出来,命令如下: <syntaxhighlight lang="shell">tshark -r example.pcap -T fields -e usb.capdata //如果想导入usbdata.txt文件中,后面加上参数:>usbdata.txt</syntaxhighlight> <code>Windows</code> 下装了 <code>wireshark</code> 的环境下,在 <code>wireshark</code>目录下有个 <code>tshark.exe</code> ,比如我的在 <code>D:\Program Files\Wireshark\tshark.exe</code> [[File:./figure/Windows-tshark.png|Windows-tshark]] 调用 <code>cmd</code> ,定位到当前目录下,输入如下命令即可: <pre>tshark.exe -r example.pcap -T fields -e usb.capdata //如果想导入usbdata.txt文件中,后面加上参数:>usbdata.txt</pre> 有关 <code>tshark</code> 命令的详细使用参考 <code>wireshark</code> 官方文档:https://www.wireshark.org/docs/man-pages/tshark.html 运行命令并查看 <code>usbdata.txt</code> 发现数据包长度为八个字节 [[File:./figure/usbdata.png|usbdata]] 关于 <code>USB</code> 的特点应用我找了一张图,很清楚的反应了这个问题: [[File:./figure/usb-feature.png|usb-feature]] 这里我们只关注 <code>USB</code> 流量中的键盘流量和鼠标流量。 键盘数据包的数据长度为 <code>8</code> 个字节,击键信息集中在第 <code>3</code> 个字节,每次 <code>key stroke</code> 都会产生一个 <code>keyboard event usb packet</code> 。 鼠标数据包的数据长度为 <code>4</code> 个字节,第一个字节代表按键,当取 <code>0x00</code> 时,代表没有按键、为0x01时,代表按左键,为 <code>0x02</code> 时,代表当前按键为右键。第二个字节可以看成是一个 <code>signed byte</code> 类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。 我翻阅了大量的 <code>USB</code> 协议的文档,在这里我们可以找到这个值与具体键位的对应关系:https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf <code>usb keyboard</code> 的映射表 根据这个映射表将第三个字节取出来,对应对照表得到解码: [[File:./figure/keyboard_pro.png|keyboard_pro]] 我们写出如下脚本: <syntaxhighlight lang="python">mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." } nums = [] keys = open('usbdata.txt') for line in keys: if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0': continue nums.append(int(line[6:8],16)) # 00:00:xx:.... keys.close() output = "" for n in nums: if n == 0 : continue if n in mappings: output += mappings[n] else: output += '[unknown]' print('output :n' + output)</syntaxhighlight> 结果如下: [[File:./figure/usb-solved.png|usb-solved]] 我们把前面的整合成脚本,得: <syntaxhighlight lang="python">#!/usr/bin/env python import sys import os DataFileName = "usb.dat" presses = [] normalKeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"} shiftKeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"} def main(): # check argv if len(sys.argv) != 2: print "Usage : " print " python UsbKeyboardHacker.py data.pcap" print "Tips : " print " To use this python script , you must install the tshark first." print " You can use `sudo apt-get install tshark` to install it" print " Thank you for using." exit(1) # get argv pcapFilePath = sys.argv[1] # get data of pcap os.system("tshark -r %s -T fields -e usb.capdata > %s" % (pcapFilePath, DataFileName)) # read data with open(DataFileName, "r") as f: for line in f: presses.append(line[0:-1]) # handle result = "" for press in presses: Bytes = press.split(":") if Bytes[0] == "00": if Bytes[2] != "00": result += normalKeys[Bytes[2]] elif Bytes[0] == "20": # shift key is pressed. if Bytes[2] != "00": result += shiftKeys[Bytes[2]] else: print "[-] Unknow Key : %s" % (Bytes[0]) print "[+] Found : %s" % (result) # clean the temp data os.system("rm ./%s" % (DataFileName)) if __name__ == "__main__": main()</syntaxhighlight> 效果如下: [[File:./figure/example-solved.png|example-solved]] 另外贴上一份鼠标流量数据包转换脚本: <syntaxhighlight lang="python">nums = [] keys = open('usbdata.txt','r') posx = 0 posy = 0 for line in keys: if len(line) != 12 : continue x = int(line[3:5],16) y = int(line[6:8],16) if x > 127 : x -= 256 if y > 127 : y -= 256 posx += x posy += y btn_flag = int(line[0:2],16) # 1 for left , 2 for right , 0 for nothing if btn_flag == 1 : print posx , posy keys.close()</syntaxhighlight> 键盘流量数据包转换脚本如下: <syntaxhighlight lang="python">nums=[0x66,0x30,0x39,0x65,0x35,0x34,0x63,0x31,0x62,0x61,0x64,0x32,0x78,0x33,0x38,0x6d,0x76,0x79,0x67,0x37,0x77,0x7a,0x6c,0x73,0x75,0x68,0x6b,0x69,0x6a,0x6e,0x6f,0x70] s='' for x in nums: s+=chr(x) print s mappings = { 0x41:"A", 0x42:"B", 0x43:"C", 0x44:"D", 0x45:"E", 0x46:"F", 0x47:"G", 0x48:"H", 0x49:"I", 0x4a:"J", 0x4b:"K", 0x4c:"L", 0x4d:"M", 0x4e:"N",0x4f:"O", 0x50:"P", 0x51:"Q", 0x52:"R", 0x53:"S", 0x54:"T", 0x55:"U",0x56:"V", 0x57:"W", 0x58:"X", 0x59:"Y", 0x5a:"Z", 0x60:"0", 0x61:"1", 0x62:"2", 0x63:"3", 0x64:"4", 0x65:"5", 0x66:"6", 0x67:"7", 0x68:"8", 0x69:"9", 0x6a:"*", 0x6b:"+", 0X6c:"separator", 0x6d:"-", 0x6e:".", 0x6f:"/" } output = "" for n in nums: if n == 0 : continue if n in mappings: output += mappings[n] else: output += '[unknown]' print 'output :\n' + output</syntaxhighlight> 那么对于 <code>xman</code> 三期夏令营排位赛的这道题,我们可以模仿尝试如上这个例子: 首先我们通过 <code>tshark</code> 将 <code>usb.capdata</code> 全部导出: <syntaxhighlight lang="shell">tshark -r task_AutoKey.pcapng -T fields -e usb.capdata //如果想导入usbdata.txt文件中,后面加上参数:>usbdata.txt</syntaxhighlight> 结果如下: [[File:./figure/tshark-task_AutoKey.png|tshark-task_AutoKey]] 我们用上面的 <code>python</code> 脚本将第三个字节取出来,对应对照表得到解码: <syntaxhighlight lang="python">mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." } nums = [] keys = open('usbdata.txt') for line in keys: if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0': continue nums.append(int(line[6:8],16)) # 00:00:xx:.... keys.close() output = "" for n in nums: if n == 0 : continue if n in mappings: output += mappings[n] else: output += '[unknown]' print('output :n' + output)</syntaxhighlight> 运行结果如下: [[File:./figure/task_AutoKey-solved.png|task_AutoKey-solved]] <syntaxhighlight lang="shell">output :n[unknown]A[unknown]UTOKEY''.DECIPHER'[unknown]MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXO[DEL]PZE[DEL]IZ'</syntaxhighlight> 我们可以看出这是自动密匙解码,现在的问题是在我们不知道密钥的情况下应该如何解码呢? 我找到了如下这篇关于如何爆破密匙:http://www.practicalcryptography.com/cryptanalysis/stochastic-searching/cryptanalysis-autokey-cipher/ 爆破脚本如下: <syntaxhighlight lang="python">from ngram_score import ngram_score from pycipher import Autokey import re from itertools import permutations qgram = ngram_score('quadgrams.txt') trigram = ngram_score('trigrams.txt') ctext = 'MPLRVFFCZEYOUJFJKYBXGZVDGQAURKXZOLKOLVTUFBLRNJESQITWAHXNSIJXPNMPLSHCJBTYHZEALOGVIAAISSPLFHLFSWFEHJNCRWHTINSMAMBVEXPZIZ' ctext = re.sub(r'[^A-Z]','',ctext.upper()) # keep a list of the N best things we have seen, discard anything else class nbest(object): def __init__(self,N=1000): self.store = [] self.N = N def add(self,item): self.store.append(item) self.store.sort(reverse=True) self.store = self.store[:self.N] def __getitem__(self,k): return self.store[k] def __len__(self): return len(self.store) #init N=100 for KLEN in range(3,20): rec = nbest(N) for i in permutations('ABCDEFGHIJKLMNOPQRSTUVWXYZ',3): key = ''.join(i) + 'A'*(KLEN-len(i)) pt = Autokey(key).decipher(ctext) score = 0 for j in range(0,len(ctext),KLEN): score += trigram.score(pt[j:j+3]) rec.add((score,''.join(i),pt[:30])) next_rec = nbest(N) for i in range(0,KLEN-3): for k in xrange(N): for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': key = rec[k][1] + c fullkey = key + 'A'*(KLEN-len(key)) pt = Autokey(fullkey).decipher(ctext) score = 0 for j in range(0,len(ctext),KLEN): score += qgram.score(pt[j:j+len(key)]) next_rec.add((score,key,pt[:30])) rec = next_rec next_rec = nbest(N) bestkey = rec[0][1] pt = Autokey(bestkey).decipher(ctext) bestscore = qgram.score(pt) for i in range(N): pt = Autokey(rec[i][1]).decipher(ctext) score = qgram.score(pt) if score > bestscore: bestkey = rec[i][1] bestscore = score print bestscore,'autokey, klen',KLEN,':"'+bestkey+'",',Autokey(bestkey).decipher(ctext)</syntaxhighlight> 跑出来的结果如下: [[File:./figure/usbpwn.png|usbpwn]] 我们看到了 <code>flag</code> 的字样,整理可得如下: <syntaxhighlight lang="shell">-674.914569565 autokey, klen 8 :"FLAGHERE", HELLOBOYSANDGIRLSYOUARESOSMARTTHATYOUCANFINDTHEFLAGTHATIHIDEINTHEKEYBOARDPACKAGEFLAGISJHAWLZKEWXHNCDHSLWBAQJTUQZDXZQPF</syntaxhighlight> 我们把字段进行分割看: <syntaxhighlight lang="shell">HELLO BOYS AND GIRLS YOU ARE SO SMART THAT YOU CAN FIND THE FLAG THAT IH IDE IN THE KEY BOARD PACKAGE FLAG IS JHAWLZKEWXHNCDHSLWBAQJTUQZDXZQPF</syntaxhighlight> 最后的 <code>flag</code> 就是 <code>flag{JHAWLZKEWXHNCDHSLWBAQJTUQZDXZQPF}</code> == 参考文献 == * https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html * https://blog.csdn.net/songze_lee/article/details/77658094 * https://wiki.wireshark.org/USB * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf * https://www.wireshark.org/docs/man-pages/tshark.html * http://www.practicalcryptography.com/cryptanalysis/stochastic-searching/cryptanalysis-autokey-cipher/ * https://hackfun.org/2017/02/22/CTF%E4%B8%AD%E9%82%A3%E4%BA%9B%E8%84%91%E6%B4%9E%E5%A4%A7%E5%BC%80%E7%9A%84%E7%BC%96%E7%A0%81%E5%92%8C%E5%8A%A0%E5%AF%86/
摘要:
请注意,所有对gamedev的贡献均可能会被其他贡献者编辑、修改或删除。如果您不希望您的文字作品被随意编辑,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源(详情请见
Gamedev:著作权
)。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
导航菜单
个人工具
未登录
讨论
贡献
创建账号
登录
命名空间
页面
讨论
不转换
不转换
简体
繁體
大陆简体
香港繁體
澳門繁體
大马简体
新加坡简体
臺灣正體
查看
阅读
编辑
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息