├── Add_profile.py ├── LICENSE ├── README.md ├── TODO ├── HUB.pcapng ├── hgame.pcap └── xiaomi.pcapng ├── USBFlow_Soer.py ├── USB_ID_LIST.txt ├── demo ├── 304_wireless.pcapng ├── CTL_480.pcapng ├── Default_Keyboard.pcap ├── GPW_502.pcapng ├── LOG_0xc539.pcapng └── LOG_G402Mouse.pcapng └── profile.yaml /Add_profile.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | from USBFlow_Soer import * 3 | 4 | ''' 5 | 添加设备的模板,注意:需要添加到对应的公司 6 | 如果列表中没有该公司,需要手动加公司的ID和Name, 7 | 如果时间紧急,可以直接将流量的压缩包发到y1shin@163.com就行,谢谢师傅的支持 8 | 9 | - Device_ID: "" 10 | Device_Name: "" 11 | Device_Type: "" 12 | Device_DefName: "" 13 | 14 | 添加的时候请师傅注意大小写和缩进; 15 | 添加完成只需要工具目录下执行一次即可 16 | 17 | 如果是未添加过的Unknown的设备,如下是添加新设备的模版 18 | "Company_ID": 19 | Company_ID: "" 20 | Device_ID: "" 21 | Device_Type: "" 22 | Device_DefName: "" 23 | ''' 24 | 25 | des_dir = ''' 26 | Company_List: 27 | - "0x046d": "LOG" 28 | "0x056a": "WACOM" 29 | "0x1532": "Razer" 30 | "0x05ac": "Apple" 31 | "0x18f8": "Maxxter" 32 | "0x248a": "Maxxter" 33 | LOG: 34 | - Company_ID: "0x046d" 35 | Company_name: "Logitech, Inc." 36 | 37 | - Device_ID: "0xc539" 38 | Device_Name: "Lightspeed Receiver" 39 | Device_Type: "Mouse" 40 | Device_DefName: "LOG_Lightspeed_Reveiver" 41 | 42 | - Device_ID: "0xc07e" 43 | Device_Name: "G402 Gaming Mouse" 44 | Device_Type: "Mouse" 45 | Device_DefName: "G402_Gaming_Mouse" 46 | 47 | - Device_ID: "0xc08b" 48 | Device_Name: "Logitech G502 SE HERO Gaming Mouse" 49 | Device_Type: "Mouse" 50 | Device_DefName: "LOG_G502_MOUSE" 51 | 52 | - Device_ID: "0xc077" 53 | Device_Name: "Logitech Mouse" 54 | Device_Type: "Mouse" 55 | Device_DefName: "Mouse" 56 | 57 | - Device_ID: "0xc341" 58 | Device_Name: "Logitech Unknow Keyboard Type" 59 | Device_Type: "KeyBoard" 60 | Device_DefName: "Unknown_keyboard" 61 | 62 | - Device_ID: "0xc53f" 63 | Device_Name: "G304 Wireless" 64 | Device_Type: "Mouse" 65 | Device_DefName: "G304_Wireless" 66 | 67 | - Device_ID: "0xc09d" 68 | Device_Name: "G102 Wire" 69 | Device_Type: "Mouse" 70 | Device_DefName: "G102_Wire" 71 | 72 | - Device_ID: "0xc05a" 73 | Device_Name: "M90/M100 Optical Mouse" 74 | Device_Type: "Mouse" 75 | Device_DefName: "M90_M100_Mouse" 76 | 77 | - Device_ID: "0xc092" 78 | Device_Name: "G102/G203 LIGHTSYNC Gaming Mouse" 79 | Device_Type: "Mouse" 80 | Device_DefName: "G402_Gaming_Mouse" 81 | 82 | Maxxter: 83 | - Company_ID: "0x18f8" 84 | Company_name: "Maxxter" 85 | 86 | - Device_ID: "0x0f97" 87 | Device_Name: "Optical Gaming Mouse [Xtrem]" 88 | Device_Type: "Mouse" 89 | Device_DefName: "Maxxter_OpticalGaming_Mouse" 90 | 91 | - Device_ID: "0x8366" 92 | Device_Name: "Wireless Optical Mouse ACT-MUSW-002" 93 | Device_Type: "Mouse" 94 | Device_DefName: "Wireless_Optical_Mouse_ACT" 95 | 96 | WACOM: 97 | - Company_ID: "0x056a" 98 | Company_name: "Wacom Co., Ltd" 99 | 100 | - Device_ID: "0x030e" 101 | Device_Name: "CTL-480 [Intuos Pen (S)]" 102 | Device_Type: "wacom" 103 | Device_DefName: "CTL_480" 104 | 105 | - Device_ID: "0x0357" 106 | Device_Name: "PTH-660 [Intuos Pro (M)]" 107 | Device_Type: "wacom" 108 | Device_DefName: "PTH_660" 109 | 110 | Razer: 111 | - Company_ID: "0x1532" 112 | Company_name: "Razer USA, Ltd" 113 | 114 | - Device_ID: "0x0083" 115 | Device_Name: "RC30-0315, Gaming Mouse [Basilisk x HyperSpeed]" 116 | Device_Type: "Mouse" 117 | Device_DefName: "Basilisk_Mouse" 118 | 119 | - Device_ID: "0x004f" 120 | Device_Name: "RZ01-0145, Gaming Mouse [DeathAdder 2000 (Alternate)]" 121 | Device_Type: "Mouse" 122 | Device_DefName: "DeathAdder_Mouse" 123 | 124 | - Device_ID: "0x0098" 125 | Device_Name: "Razer UnknownType Mouse" 126 | Device_Type: "Mouse" 127 | Device_DefName: "Razer_UnkownType_Mouse" 128 | 129 | - Device_ID: "0x0094" 130 | Device_Name: "Razer UnknownType Mouse 2" 131 | Device_Type: "Mouse" 132 | Device_DefName: "Razer_UnkownType_Mouse2" 133 | 134 | Apple: 135 | - Company_ID: "0x05ac" 136 | Company_name: "Apple, Inc." 137 | 138 | - Device_ID: "0x024f" 139 | Device_Name: "Aluminium Keyboard (ANSI)" 140 | Device_Type: "KeyBoard" 141 | Device_DefName: "ANSI" 142 | 143 | HP: 144 | - Company_ID: "0x03f0" 145 | Company_name: "HP, Inc" 146 | 147 | 148 | 149 | Unknown: 150 | "0x256c": 151 | Company_ID: "0x256c" 152 | Device_ID: "0x006d" 153 | Device_Type: "Wacom Like" 154 | Device_DefName: "Wacom_Like_1" 155 | 156 | "0x093a": 157 | Company_ID: "0x093a" 158 | Device_ID: "0x2530" 159 | Device_Type: "Mouse Like" 160 | Device_DefName: "Mouse_Like_1" 161 | 162 | "0x2341": 163 | Company_ID: "0x2341" 164 | Device_ID: "0x8036" 165 | Device_Type: "Keyboard Like" 166 | Device_DefName: "KeyBoard_Like_1" 167 | 168 | Default: 169 | - type: "Mouse" 170 | datalen: 8 171 | name: "Default Mouse" 172 | - type: "KeyBoard" 173 | datalen: 16 174 | name: "Default KeyBoard" 175 | ''' 176 | dict_var = yaml.safe_load(des_dir) 177 | with open("./profile.yaml" ,"w" ,encoding="utf-8") as f: 178 | yaml.dump(dict_var ,f ,default_flow_style=False) 179 | print("[+] 更新profile.yaml成功") 180 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # USBFlow_Soer 2 | Usage : python3 USBFlow_Soer.py -f filename -p usb.src -d [usbhid.data/usb.capdata] 3 | 4 | 这个项目的原理是通过USBid的唯一性,来写出特定的数据解析脚本,本质上是穷举的做法,师傅们如果遇到了什么特殊的USB流量或者是对这个项目有什么建议, 5 | 欢迎与我QQ:`2729913542`交流,基本上能做到秒回(づ ̄ 3 ̄)づ。 6 | 本项目基于tshark建造,请确保linux中下载有tshark. 7 | 8 | 由于不知道为什么有些demo上传不进去,于是就上传到网盘了:`https://pan.baidu.com/s/1qEL3mfSJLOBig0tSq9UV7Q?pwd=love`如果需要的话,烦请师傅手动下一下 9 | 10 | 更新日志1:在zeror师傅的指导下,对代码进行了重构,现在添加新设备将更加简单和易懂; 11 | 由于本工具原理是穷举,所以难免会出现解密不了的数据,届时,还烦请师傅您将流量包发到邮箱`y1shin@163.com`谢谢师傅您的支持 12 | 13 | 更新日志2:修复若干bug,如果想要在windows下使用,只需要想办法在windows下执行tshark命令即可,再将main()函数的第一个判断语句删掉即可 14 | 15 | 更新日志3:借鉴了knm的鼠标的显示模式,分成左右中总四块分别显示 16 | 17 | 18 | 19 | >Q&A: 20 | 21 | > Q1.为什么没有什么数据都没有提出来? 22 | 23 | > A: 检查tshark版本,4.0以上为好 `sudo apt-get update|sudo apt-get install tshark` 24 | 25 | > Q2.为什么Windows不能用? 26 | 27 | > A: 因为windows下没有tshark,所以需要先安装tshark,因为windows下的tshark是`exe`文件,所以需要手动添加tshark路径,或者是将`tshark.exe`添加到环境变量中 28 | -------------------------------------------------------------------------------- /TODO/HUB.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/TODO/HUB.pcapng -------------------------------------------------------------------------------- /TODO/hgame.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/TODO/hgame.pcap -------------------------------------------------------------------------------- /TODO/xiaomi.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/TODO/xiaomi.pcapng -------------------------------------------------------------------------------- /USBFlow_Soer.py: -------------------------------------------------------------------------------- 1 | '''Author y1shin@163.com''' 2 | import os 3 | import sys 4 | import yaml 5 | import argparse 6 | import platform 7 | import matplotlib.pyplot as plt 8 | import operator 9 | 10 | logo = ''' 11 | __ _ _ 12 | /_ | | | (_) 13 | _ _ | | ___ | |__ _ _ __ 14 | | | | | | | / __| | '_ \ | | | '_ \ 15 | | |_| | | | \__ \ | | | | | | | | | | 16 | \__, | |_| |___/ |_| |_| |_| |_| |_| 17 | __/ | 18 | |___/ 19 | ''' 20 | 21 | class END: 22 | def Without_Match(): 23 | print("-"*50 ,"\n[-] 解密失败,请联系QQ:2729913542更新USB数据") 24 | def Message(): 25 | print("-"*50 ,"\n[+] 工具由y1shin开发,欢迎加QQ:2729913542与我讨论") 26 | 27 | class GET_START: 28 | def Get_Basic_Parameter(): 29 | parser = argparse.ArgumentParser() 30 | parser.add_argument('-f' ,type=str ,default=None ,required=True , 31 | help='输入文件路径') 32 | parser.add_argument('-p' ,type=str ,default=None ,required=True , 33 | help='输入需要提取的srcIP') 34 | parser.add_argument('-d' ,type=str ,default=None ,required=True , 35 | help='输入需要提取的字段名:usbhid.data/usb.capdata') 36 | args = parser.parse_args() 37 | return args.f ,args.p ,args.d 38 | 39 | def Build_Cmd_And_Get_Data(file_name:str ,des_IP:str ,field_name:str): 40 | Reponse_IP = des_IP[:-1]+"0" 41 | os.system(f'tshark -r {file_name} -T fields -Y "usb.src=={des_IP}" -e {field_name} > temp_data.out') 42 | os.system(f'tshark -r {file_name} -T fields -Y \"usb && usb.src!=host && usb.src!={des_IP}\" -e \"usb.idProduct\" > temp_id.out') 43 | os.system(f'tshark -r {file_name} -T fields -Y \"usb && usb.src!=host && usb.src!={des_IP}\" -e \"usb.idVendor\" > temp_vendor.out') 44 | os.system(f'tshark -r {file_name} -T fields -Y \"usb && usb.src!=host && usb.src=={Reponse_IP}\" -e \"usb.idVendor\" > temp_Response.out') 45 | os.system(f'tshark -r {file_name} -T fields -Y \"usb && usb.src!=host && usb.src=={Reponse_IP}\" -e \"usb.idProduct\" > temp_Res.out') 46 | 47 | with open("temp_data.out") as f: 48 | USB_Value_List = f.readlines() 49 | with open("temp_id.out") as f: 50 | USB_Device_Id = f.read().strip().split() 51 | with open("temp_vendor.out") as f: 52 | USB_Vendor_Id = f.read().strip().split() 53 | with open("temp_Response.out") as f: 54 | Des_VendorID = f.read().strip().split() 55 | with open("temp_Res.out") as f: 56 | Des_ProductID = f.read().strip().split() 57 | 58 | # 在zeror师傅的指导下,旨在增强代码的健壮性 59 | temp_dirlist = ["temp_data.out" ,"temp_id.out" ,"temp_vendor.out" ,"temp_Response.out" ,"temp_Res.out" ,] 60 | for i in temp_dirlist: 61 | try: 62 | os.remove(i) 63 | except: 64 | print(f"运行名录下临时文件{i}未能删除,请手动删除") 65 | 66 | # 读取所有的ID值 67 | ID = [] 68 | for i in range(len(USB_Vendor_Id)): 69 | ID.append((USB_Vendor_Id[i] ,USB_Device_Id[i])) 70 | 71 | # 这里是为了解决出题人只截取部分流量包的问题 72 | if len(Des_VendorID) != 0: 73 | return USB_Value_List ,ID ,(Des_VendorID[0] ,Des_ProductID[0]) 74 | else: 75 | return USB_Value_List ,ID ,(None ,None) 76 | 77 | class KEYBOARD: 78 | ''' 79 | Leftover Capture Data(usb.capdata): 0200040000000000 80 | [0:2]->binary:00000010(按下了Left Shift) : 81 | 数据由大端储存 82 | { 按下了什么功能键,对应的值为1,则已按下 83 | bit_0:Left Ctrl 84 | bit_1:Left Shift 85 | bit_2:Left Alt 86 | bit_3:Left Win 87 | bit_4:Right Ctrl 88 | bit_5:Right Shift 89 | bit_6:Right Alt 90 | bit_7:Right Win 91 | } 92 | [4:6]:按下的键盘上的键,如果短时间按了两个键,那么[6:8]也会有数据 93 | ''' 94 | # 还原键盘的按键情况 95 | def Value_2_PlainText(data_list): 96 | normal_Keys = { 97 | "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":"\n","29":"","2a":"", "2b":"\t","2c":" ","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"","33":";","34":"'","35":"","36":",","37":".","38":"/","39":"","3a":"","3b":"", "3c":"","3d":"","3e":"","3f":"","40":"","41":"","42":"","43":"","44":"","45":"","46":"","47":"","48":"","49":"","4a":"","4b":"","4c":"","4d":"","4e":"","4f":"","50":"","51":"","52":"","00":"","":""} 98 | shift_Keys = { 99 | "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":"\n","29":"","2a":"","2b":"\t","2c":" ","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"","33":"\"","34":":","35":"","36":"<","37":">","38":"?","39":"","3a":"","3b":"","3c":"","3d":"","3e":"","3f":"","40":"","41":"","42":"","43":"","44":"","45":"","46":"","47":"","48":"","49":"","4a":"","4b":"","4c":"","4d":"","4e":"","4f":"","50":"","51":"","52":"","00":""} 100 | CAP_Count = 0 # 默认开始是小写 101 | result = "" 102 | 103 | Func_Choice = input('需要输出所有的功能键吗?[y/n]:').upper() 104 | 105 | for i in data_list: 106 | i = i.strip("\n") 107 | single_press = i[4:6] 108 | Function_press_bit = str(bin(int(i[0:2] ,16))[2:].zfill(8)[::-1]) 109 | 110 | Function_press_dir = {"[Ctrl]":0 ,"[Shift]":0 ,"[Alt]":0 ,"[Win]":0} 111 | # 计算功能键的按下情况 112 | if Function_press_bit[0] != "0" or Function_press_bit[4] != "0": 113 | Function_press_dir["[Ctrl]"] = 1 114 | if Function_press_bit[1] != "0" or Function_press_bit[5] != "0": 115 | Function_press_dir["[Shift]"] = 1 116 | if Function_press_bit[2] != "0" or Function_press_bit[6] != "0": 117 | Function_press_dir["[Alt]"] = 1 118 | if Function_press_bit[3] != "0" or Function_press_bit[7] != "0": 119 | Function_press_dir["[Win]"] = 1 120 | 121 | # 判断是否为有效press 122 | if (single_press not in normal_Keys) or (single_press not in shift_Keys): 123 | continue 124 | 125 | # 排除重复press 126 | if i[4:6] != "00" and i[6:8] != "00": 127 | continue 128 | 129 | # 判断按下大写键没 130 | if single_press == "39": 131 | CAP_Count += 1 132 | continue 133 | 134 | # 输出功能键组合 135 | if Func_Choice == "Y": 136 | if 1 in Function_press_dir.values() and (Function_press_dir["[Alt]"] == 1 or Function_press_dir["[Ctrl]"] == 1 or Function_press_dir["[Win]"] == 1): 137 | for Func_tuple in Function_press_dir.items(): 138 | if Func_tuple[1] == 1: 139 | print(f"{Func_tuple[0]} {shift_Keys[single_press]}") 140 | 141 | # 输出按下的键位 142 | CAP_Judge = (CAP_Count + Function_press_dir["[Shift]"])%2 143 | 144 | if Function_press_dir["[Shift]"] == 0: 145 | if CAP_Judge == 0: 146 | print(normal_Keys[single_press].lower() ,end="") 147 | elif CAP_Judge == 1: 148 | print(normal_Keys[single_press].upper() ,end="") 149 | else: 150 | if CAP_Judge == 0: 151 | print(shift_Keys[single_press].lower() ,end="") 152 | elif CAP_Judge == 1: 153 | print(shift_Keys[single_press].upper() ,end="") 154 | 155 | print("\n" ,"-"*50) 156 | 157 | class MOUSE: 158 | ''' 159 | Leftover Capture Data(usb.capdata): 0205fa00 160 | [0:2]->binary:00000010(正在按鼠标右键){ 161 | 大端储存,数据==1则按下, 162 | bit_0:鼠标左键 163 | bit_1:鼠标右键 164 | bit_2:鼠标中键 165 | bit_[3:7]:保留位 166 | } 167 | ''' 168 | # 将鼠标轨迹画出来 169 | def Value_2_plt(data_list): 170 | # 本来是想用一个文件来存数据的,但是临时文件太多了,就用变量来存了,运行速度也大差不差 171 | Left_x_dir ,Left_y_dir = [] ,[] 172 | Right_x_dir ,Right_y_dir = [] ,[] 173 | Mid_x_dir ,Mid_y_dir = [] ,[] 174 | All_x_dir ,All_y_dir = [] ,[] 175 | pos_x ,pos_y = 0 ,0 176 | offset_x ,offset_y = 0 ,0 177 | for i in data_list: 178 | press_state = bin(int(i[0:2] ,16))[2:].zfill(8)[::-1] 179 | offset_x = int(i[2:4] ,16) 180 | offset_y = int(i[4:6] ,16) 181 | if offset_x > 127: 182 | offset_x -= 256 183 | if offset_y > 127: 184 | offset_y -= 256 185 | pos_x += offset_x 186 | pos_y += offset_y 187 | 188 | # 这段是用来记录所有的按键情况的痕迹 189 | if press_state[0] == "1": 190 | Left_x_dir.append(pos_x) 191 | Left_y_dir.append(-pos_y) 192 | if press_state[1] == "1": 193 | Right_x_dir.append(pos_x) 194 | Right_y_dir.append(-pos_y) 195 | if press_state[2] == "1": 196 | Mid_x_dir.append(pos_x) 197 | Mid_y_dir.append(-pos_y) 198 | All_x_dir.append(pos_x) 199 | All_y_dir.append(-pos_y) 200 | 201 | ''' 202 | 这一段子图借鉴了 FzWjScJ 神的knm 项目地址 203 | https://github.com/FzWjScJ/knm 204 | ''' 205 | fig ,axs = plt.subplots(2 ,2) 206 | 207 | '''可以根据自己电脑的尺寸修改显示的尺寸''' 208 | fig.set_figwidth(12) 209 | fig.set_figheight(10) 210 | ax1 ,ax2 ,ax3 ,ax4 = axs[0 ,0] ,axs[0 ,1] ,axs[1 ,0] ,axs[1 ,1] 211 | 212 | ax1.scatter(All_x_dir ,All_y_dir ,color="hotpink") 213 | ax1.set_title("ALL") 214 | ax2.scatter(Right_x_dir ,Right_y_dir ,color="hotpink") 215 | ax2.set_title("RIGHT") 216 | ax3.scatter(Left_x_dir ,Left_y_dir ,color="hotpink") 217 | ax3.set_title("LEFT") 218 | ax4.scatter(Mid_x_dir ,Mid_y_dir ,color="hotpink") 219 | ax4.set_title("MID") 220 | 221 | plt.show() 222 | 223 | Get_press_choice = input("需要输出鼠标按键二进制码吗?[y/N](slow):").upper() 224 | if Get_press_choice == "Y": 225 | MOUSE.Get_Mouse_press(data_list) 226 | print("1") 227 | 228 | # 获取鼠标三个按键的二进制,这一段写的很臭,用处估计也不大 229 | def Get_Mouse_press(data_list): 230 | Mouse_left_press = "" 231 | Mouse_right_press = "" 232 | Mouse_mid_press = "" 233 | for i in data_list: 234 | i = i.strip("\n") 235 | data = str(bin(int(i ,16))[2:].zfill(8))[::-1] 236 | if data[0] == "1": 237 | Mouse_left_press += "1" 238 | else: 239 | Mouse_left_press += "0" 240 | if data[1] == "1": 241 | Mouse_right_press += "1" 242 | else: 243 | Mouse_right_press += "0" 244 | if data[2] == "1": 245 | Mouse_mid_press += "1" 246 | else: 247 | Mouse_mid_press += "0" 248 | # 左键数据 249 | if "1" not in Mouse_left_press: 250 | print(f"[-] Mouse_left_press: NOTHING") 251 | else: 252 | f = open("./Mouse_LEFTKEY.out" ,"w") 253 | f.write(Mouse_left_press) 254 | f.close() 255 | print(f"[+] 左键数据已经保存在了运行目录下") 256 | # 右键数据 257 | if "1" not in Mouse_right_press: 258 | print(f"[-] Mouse_right_press: NOTHING") 259 | else: 260 | f = open("./Mouse_RIGHTKEY.out" ,"w") 261 | f.write(Mouse_right_press) 262 | f.close() 263 | print(f"[+] 右键数据已经保存在了运行目录下") 264 | # 中键数据 265 | if "1" not in Mouse_mid_press: 266 | print(f"[-] Mouse_mid_press: NOTHING") 267 | else: 268 | f = open("./Mouse_MIDKEY.out" ,"w") 269 | f.write(Mouse_mid_press) 270 | f.close() 271 | print(f"[+] 中键数据已经保存在了运行目录下") 272 | print("-"*50) 273 | 274 | class WACOM: 275 | # Wacom Co., Ltd(0x056a) 276 | def CTL_480(data_list): 277 | ''' 278 | 型号:CTL-480 [Intuos Pen (S)] (0x030e) 279 | HID Data(usbhid.data): 02f1560e790fe9022800 280 | [0:4]==02f1是有效数据 x坐标[4:8] y坐标[8:12] 281 | 坐标储存是小端储存 282 | ''' 283 | print("[+] 型号:Wacom CTL-480 [Intuos Pen (S)] (0x030e)\n") 284 | x_list ,y_list = [],[] 285 | for i in data_list: 286 | i = i.strip("\n") 287 | if i[0:4] == "02f1": 288 | x_pos = int(i[4:6] ,16) + int(i[6:8] ,16)*256 289 | y_pos = int(i[8:10] ,16) + int(i[10:12] ,16)*256 290 | x_list.append(x_pos) 291 | y_list.append(-y_pos) 292 | plt.scatter(x=x_list ,y=y_list ,c='hotpink') 293 | plt.title("CTL 480") 294 | plt.show() 295 | 296 | def PTH_660(data_list): 297 | ''' 298 | 型号:PTH-660 [Intuos Pro (M)] (0x0357) 299 | HID Data(usbhid.data): 10614157000a1f00bd191404000000000084308094420810004208 300 | [16:18]!=00即为有效数据 x坐标[4:8] y坐标[10:14] 301 | 坐标储存是小端储存 302 | ''' 303 | print("[+] Wacom 型号:PTH-660 [Intuos Pro (M)] (0x0357)\n") 304 | x_list ,y_list = [],[] 305 | for i in data_list: 306 | i = i.strip("\n") 307 | if len(i) != 54: 308 | continue 309 | if i[16:18] != "00" : 310 | x_pos = int(i[4:6] ,16) + int(i[6:8] ,16)*256 311 | y_pos = int(i[10:12] ,16) + int(i[12:14] ,16)*256 312 | x_list.append(x_pos) 313 | y_list.append(-y_pos) 314 | plt.scatter(x=x_list ,y=y_list ,c='hotpink') 315 | plt.title("PTH 660") 316 | plt.show() 317 | 318 | class LOG: 319 | # Logitech, Inc.(0x046d) 320 | def LOG_Lightspeed_Reveiver(data_list): 321 | ''' 322 | 型号:Lightspeed Receiver(0xc539) 323 | usbhid.data = 020000130000000000 324 | 头部的02是标识符,相当于是识别的符号 325 | [2:4]是press [6:8]是x轴变化 [10:12]是y轴变化 326 | ''' 327 | print("[+] 型号:Logitech Lightspeed Receiver(0xc539)\n") 328 | changed_datalist = [] 329 | for i in data_list: 330 | i = f"{i[2:4]}{i[6:8]}{i[10:12]}00" 331 | changed_datalist.append(i) 332 | MOUSE.Value_2_plt(changed_datalist) 333 | 334 | def LOG_G502_MOUSE(data_list): 335 | ''' 336 | 型号:G502 SE HERO Gaming Mouse(0xc08b) 337 | HID Data(usbhid.data):0000feff02000000 338 | [4:6]:x坐标 [8:10]:y坐标 339 | ''' 340 | print("[+] 型号:Logitech G502 SE HERO Gaming Mouse(0xc08b)\n") 341 | changed_data = [] 342 | for i in data_list: 343 | # 将这个数据转化成基础的鼠标流量的数据结构 344 | i = f"{i[0:2]}{i[4:6]}{i[8:10]}00" 345 | changed_data.append(i) 346 | MOUSE.Value_2_plt(changed_data) 347 | 348 | def Mouse(data_list): 349 | ''' 350 | 型号:Mouse(0xc077) 351 | 数据类型:普通类型 352 | ''' 353 | print("[+] 型号:Logitech Mouse(0xc077)\n") 354 | MOUSE.Value_2_plt(data_list) 355 | 356 | def Unknown_keyboard(data_list): 357 | ''' 358 | 型号:Unknown(0xc341) 359 | 数据类型:普通类型 360 | ''' 361 | print("[+] 型号:Logitech Unknow Keyboard Type(0xc341)\n") 362 | KEYBOARD.Value_2_PlainText(data_list) 363 | 364 | def G304_Wireless(data_list): 365 | ''' 366 | 型号: G304 无线鼠标(0xc53f) 367 | 数据结构(usbhid.data):020100ffff01000000 368 | [2:4] press [6:8] x位移 [10:12] y位移 369 | ''' 370 | print("[+] G304 Wireless(0xc53f)") 371 | changed_list = [] 372 | for i in data_list: 373 | i = f"{i[2:4]}{i[6:8]}{i[10:12]}00" 374 | changed_list.append(i) 375 | MOUSE.Value_2_plt(changed_list) 376 | 377 | def G102_Wire(data_list): 378 | ''' 379 | 型号: G102 有线鼠标 380 | 数据结构(usbhid.data):0100fefffeff0000 381 | [0:2] press [4:6] x位移 [8:10] y位移 382 | ''' 383 | print("[+] G102 Mouse(0xc09d)") 384 | changed_list =[] 385 | for i in data_list: 386 | i = f"{i[0:2]}{i[4:6]}{i[8:10]}00" 387 | changed_list.append(i) 388 | MOUSE.Value_2_plt(changed_list) 389 | 390 | def M90_M100_Mouse(data_list): 391 | ''' 392 | 型号: M90/M100 Optical Mouse 393 | 数据结构(usbhid.data):01fefc00 394 | 和普通鼠标是一样的 395 | ''' 396 | print("[+] M90/M100 Optical Mouse(0xc05a)") 397 | MOUSE.Value_2_plt(data_list) 398 | 399 | def G402_Gaming_Mouse(data_list): 400 | ''' 401 | 型号: G402 Gaming Mouse (0xc07e)||G102/G203 LIGHTSYNC Gaming Mouse 402 | 数据结构(usbhid.data):0100010001000000 403 | [0:2] press [4:6] x位移 [8:10] y位移 404 | ''' 405 | changed_list = [] 406 | for i in data_list: 407 | i = f"{i[0:2]}{i[4:6]}{i[8:10]}00" 408 | changed_list.append(i) 409 | MOUSE.Value_2_plt(changed_list) 410 | 411 | # def G102_G203_Mouse(data_list): 412 | # ''' 413 | # 型号: 414 | # 数据结构(usbhid.data):0100010001000000 415 | # [0:2] press [4:6] x位移 [8:10] y位移 416 | # ''' 417 | 418 | class Razer: 419 | # Razer USA, Ltd (0x1532) 420 | 421 | def Basilisk_Mouse(data_list): 422 | ''' 423 | 型号:RC30-0315, Gaming Mouse [Basilisk x HyperSpeed] (0x0083) 424 | 数据结构(usbhid.data):01feff00feffffff 425 | [0:2] press [2:4] x位移 [4:6] y轴 426 | ''' 427 | print("[+] RC30-0315, Gaming Mouse [Basilisk x HyperSpeed] (0x0083)") 428 | changed_list = [] 429 | for i in data_list: 430 | i = f"{i[0:2]}{i[2:4]}{i[4:6]}00" 431 | changed_list.append(i) 432 | MOUSE.Value_2_plt(changed_list) 433 | 434 | def DeathAdder_Mouse(data_list): 435 | ''' 436 | 型号:RZ01-0145, Gaming Mouse [DeathAdder 2000 (Alternate)] (0x004f) 437 | 数据结构(usbhid.data):0006fe000600feff 438 | [0:2] press [2:4] x位移 [4:6] y位移 439 | ''' 440 | print("[+] RZ01-0145, Gaming Mouse [DeathAdder 2000 (Alternate)] (0x004f)") 441 | changed_list = [] 442 | for i in data_list: 443 | i = f"{i[0:2]}{i[2:4]}{i[4:6]}00" 444 | changed_list.append(i) 445 | MOUSE.Value_2_plt(changed_list) 446 | 447 | def Razer_UnkownType_Mouse(data_list): 448 | ''' 449 | 型号:Unknown (0x0098) 450 | 数据结构(usbhid.data):0101f8000100f8ff 451 | [0:2] press [2:4] x位移 [4:6] y位移 452 | ''' 453 | print("[+] Razer UnknownType Mouse (0x0098)") 454 | changed_list = [] 455 | for i in data_list: 456 | i = f"{i[0:2]}{i[2:4]}{i[4:6]}{i[6:8]}" 457 | changed_list.append(i) 458 | MOUSE.Value_2_plt(changed_list) 459 | 460 | def Razer_UnkownType_Mouse2(data_list): 461 | ''' 462 | 型号:Unknown (0x0098) 463 | 数据结构(usbhid.data):00000000feff0100 464 | [0:2] press [8:10] x位移 [12:14] y位移 465 | ''' 466 | print("[+] Razer UnknownType Mouse 2 (0x0094)") 467 | changed_list = [] 468 | for i in data_list: 469 | i = f"{i[0:2]}{i[8:10]}{i[12:14]}00" 470 | changed_list.append(i) 471 | MOUSE.Value_2_plt(changed_list) 472 | 473 | class Apple: 474 | # Apple, Inc.(0x05ac) 475 | def ANSI(data_list): 476 | TODO:需要将它改成更合理的数据处理 477 | ''' 478 | 型号:Aluminium Keyboard (ANSI) (0x024f) 479 | 暂且当成普通的键盘来解 480 | ''' 481 | print("[+] 型号:Apple Aluminium Keyboard (ANSI)(0x024f)\n") 482 | pad_Keys = { 483 | "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":"\n","29":"","2a":"", "2b":"\t","2c":" ","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"","33":";","34":"'","35":"","36":",","37":".","38":"/","39":"","3a":"","3b":"", "3c":"","3d":"","3e":"","3f":"","40":"","41":"","42":"","43":"","44":"","45":"","46":"","47":"","48":"","49":"","4a":"","4b":"","4c":"","4d":"","4e":"","4f":"","50":"","51":"","52":"","53":"","54":"1","55":"*","56":"-","57":"+","58":"","59":"<1/END>","5a":"<2/Down>","5b":"<3/PageDn","5c":"<4/LeftArrow>","5d":"5","5e":"<6/RightArrow>","5f":"<7/Home>","60":"<8/UpArrow>","61":"<9/PageUp>","62":"<0/Insert>","63":"<./Delete>","00":"","":""} 484 | for i in data_list: 485 | try: 486 | i = i.strip("\n") 487 | print(pad_Keys[i[4:6]] ,end="") 488 | except: 489 | continue 490 | print("\n","-"*50) 491 | chioce = input("[+] 只需要留下数字键吗?[Y/N]").upper() 492 | print("\n") 493 | if chioce == "Y": 494 | pad_Keys = { 495 | "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":"\n","29":"","2a":"", "2b":"\t","2c":" ","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"","33":";","34":"'","35":"","36":",","37":".","38":"/","39":"","3a":"","3b":"", "3c":"","3d":"","3e":"","3f":"","40":"","41":"","42":"","43":"","44":"","45":"","46":"","47":"","48":"","49":"","4a":"","4b":"","4c":"","4d":"","4e":"","4f":"","50":"","51":"","52":"","53":"","54":"1","55":"*","56":"-","57":"+","58":"","59":"1","5a":"2","5b":"3","5c":"4","5d":"5","5e":"6","5f":"7","60":"8","61":"9","62":"0","63":".","00":"","":""} 496 | for i in data_list: 497 | try: 498 | i = i.strip("\n") 499 | print(pad_Keys[i[4:6]] ,end="") 500 | except: 501 | continue 502 | print("\n","-"*50) 503 | 504 | class Maxxter: 505 | def Maxxter_OpticalGaming_Mouse(data_list): 506 | ''' 507 | 型号: Optical Gaming Mouse [Xtrem](0x0f97) 508 | usbhid.data = 0100f97f0000(6 bytes) 509 | [0:2] press [4:6] x位移 [6:8] y位移 510 | ''' 511 | print("[+] 型号: Maxxter Optical Gaming Mouse [Xtrem](0x0f97)") 512 | changed_datalist = [] 513 | for i in data_list: 514 | i = f"{i[0:2]}{i[4:6]}{i[6:8]}00" 515 | changed_datalist.append(i) 516 | MOUSE.Value_2_plt(changed_datalist) 517 | 518 | def Wireless_Optical_Mouse_ACT(data_list): 519 | ''' 520 | 型号: Wireless Optical Mouse ACT-MUSW-002(0x8366) 521 | usbhid.data = 0100fbff00(5 bytes) 522 | [0:2] press [4:6] x位移 [6:8] y位移 523 | ''' 524 | print("[+] 型号: Wireless Optical Mouse ACT-MUSW-002(0x8366)") 525 | changed_datalist = [] 526 | for i in data_list: 527 | i = f"{i[0:2]}{i[4:6]}{i[6:8]}00" 528 | changed_datalist.append(i) 529 | MOUSE.Value_2_plt(changed_datalist) 530 | 531 | class Unknown_Type_Device: 532 | ''' 533 | 这个类是专门用来存储特殊或者是没有名字的USBVendor, 534 | 所以我给它取的名字就叫Unknown,函数名也将用它的流量类似什么标准USB流量来命名 535 | ''' 536 | 537 | def Check_Unknown_And_Recover(DesID_List ,profile_data ,Field_Value ,ip ,file ,Company_List): 538 | if DesID_List[0] in profile_data["Unknown"]: 539 | Def_Name = profile_data["Unknown"][DesID_List[0]]["Device_DefName"] 540 | operator.methodcaller(Def_Name ,Field_Value)(Unknown_Type_Device) 541 | print(1) 542 | # 询问是否需要爆破所有的值 543 | Brute_Choice = input("需要爆破所有的数据吗?[y/N](也许会不准确or是报错):").upper() 544 | if Brute_Choice != "Y": 545 | END.Message() 546 | exit(-1) 547 | else: 548 | Burteforce(file ,ip ,profile_data ,Company_List) 549 | 550 | END.Message() 551 | exit(-1) 552 | else: 553 | return None 554 | 555 | def Wacom_Like_1(Field_Value): 556 | ''' 557 | 设备ID:0x006d 公司ID:0x256c 558 | 流量格式:0ac0a63f37420000161a(usbhid.data) 559 | [2:4]==c1为有效数据 [4:8] 为x坐标 [8:12] 为y坐标;并且是大端储存 560 | ''' 561 | print("[+] 类似Wacom的画板") 562 | xlist ,ylist = [] ,[] 563 | for data in Field_Value: 564 | xpos = int(data[4:6] ,16) + int(data[6:8] ,16)*256 565 | ypos = int(data[8:10] ,16) + int(data[10:12] ,16)*256 566 | if data[2:4] == "c1": 567 | xlist.append(xpos) 568 | ylist.append(-ypos) 569 | plt.scatter(xlist ,ylist ,c='hotpink') 570 | plt.show() 571 | 572 | def Mouse_Like_1(Field_Value): 573 | ''' 574 | 这是zeror师傅发我的一个流量包 575 | 设备ID:0x2530 公司ID:0x093a 576 | 流量格式:0103fd000300fdff(usbhid.data) 577 | [0:2] 按键 [2:4] x位移 [4:6] y位移 578 | ''' 579 | Changed_Value = [] 580 | for i in Field_Value: 581 | i = f"{i[0:2]}{i[2:4]}{i[4:6]}00" 582 | Changed_Value.append(i) 583 | MOUSE.Value_2_plt(Changed_Value) 584 | 585 | def KeyBoard_Like_1(Field_Value): 586 | ''' 587 | 原题:0xGAME2023 notverybadusb 588 | 这个是 Arduino 的键盘流量,去掉前两位标识符就是正常的键盘流量 589 | 因为可能会不太常见,所以就把它丢到Unknown了,没有专门写一个类 590 | 0200001a0000000000 591 | [0:2] 标识符 [2:4] 功能键 [6:8] 按键 592 | ''' 593 | print(1) 594 | changed_list = [] 595 | for i in Field_Value: 596 | i = f"{i[2:4]}00{i[6:8]}0000000000" 597 | changed_list.append(i) 598 | KEYBOARD.Value_2_PlainText(changed_list) 599 | 600 | def Get_defname(Device_ID:str ,Device_List:list) -> str: 601 | # 返回查找到对应公司下的产品对应的解密函数名 602 | for i in Device_List: 603 | if i["Device_ID"] == Device_ID: 604 | return i["Device_DefName"] 605 | 606 | def Burteforce(file ,ip ,profile_data ,Company_List): 607 | os.system(f'tshark -r {file} -T fields -Y \"usb.src!=host && usb.src!={ip}\" -e usb.src > temp_ALLIP.out') 608 | with open("temp_ALLIP.out") as f: 609 | ALL_IP_List = [i.strip("\n") for i in (list(set(f.readlines()))) if i.strip("\n")[-1] != "0"] 610 | 611 | # 判断是否还有数据可以提取 612 | if len(ALL_IP_List) == 0: 613 | print("[-] 已经没有数据可以提取") 614 | END.Message() 615 | exit(-1) 616 | print(f"[+] 有如下{ALL_IP_List}IP可以提取数据") 617 | 618 | for Other_ip in ALL_IP_List: 619 | # 这一段是在读取此IP的数据类型(usbhid.data/usb.capdata) 620 | print("-"*50 ,f"\n[=] 正在提取 {Other_ip} 地址的数据") 621 | 622 | Zero_ip = Other_ip[:-1] + "0" 623 | os.system(f'tshark -r {file} -T fields -Y "usb.src=={Zero_ip}" -e usb.bInterfaceClass > temp_dataType.out') 624 | with open("temp_dataType.out") as f: 625 | dataType = "".join(t for t in [i.strip("\n") for i in list(set(f.readlines()))]) 626 | if "0x03" in dataType: 627 | dataType = "usbhid.data" 628 | else:continue # 由于还没发现usb.capdata的数据,所以遇到不是usbhid.data的直接跳过 629 | 630 | # 这段就是把main函数的一部分给套过来了,因为不会递归( 631 | Field_Value ,ID_List ,DesID_List = GET_START.Build_Cmd_And_Get_Data(file_name=file ,des_IP=Other_ip ,field_name=dataType) 632 | 633 | if len(Field_Value) == 0: 634 | print(f"[-] 源IP为{ip},字段名称为{dataType}提取出来的数据为空\n" ,"-"*50) 635 | continue 636 | Unknown_Type_Device.Check_Unknown_And_Recover(DesID_List ,profile_data ,Field_Value ,Other_ip ,file ,Company_List) 637 | 638 | # 处理目的IP的数据 639 | if DesID_List[0] in Company_List: 640 | # 获取配置文件中的类名 641 | class_name = Company_List[DesID_List[0]] 642 | # 获取配置文件中的函数名 643 | Device_List = profile_data[class_name][1:] 644 | Def_Name = Get_defname(DesID_List[1] ,Device_List) 645 | # 将获取的函数名和类名实例化并且执行 646 | operator.methodcaller(Def_Name ,Field_Value)(globals()[class_name]) 647 | # 处理默认值 648 | else: 649 | if len(Field_Value[0].strip("\n")) == 8: 650 | MOUSE.Value_2_plt(Field_Value) 651 | elif len(Field_Value[0].strip("\n")) == 16: 652 | KEYBOARD.Value_2_PlainText(Field_Value) 653 | else: 654 | print(f"[-] 地址为 {Other_ip} 的数据未能解密\n" ,"-"*50) 655 | 656 | def main(): 657 | # 检查系统是否是linux系统 658 | # if platform.system() == "Linux" or platform.system() == "Darwin": 659 | # print(f"[-] 您当前的操作系统{platform.system()},本工具只适用于Linux系统!\n[=] PS:将tshark命令添加到环境变量,再注释main()函数第一个判断语句就可以在windows使用了^^") 660 | # exit(-1) 661 | 662 | # 读取配置文件 663 | profile_data = {} 664 | 665 | with open(f"{os.path.split(os.path.realpath(__file__))[0]}/profile.yaml" ,"r" ,encoding="utf-8") as f: 666 | profile_data = f.read() 667 | profile_data = yaml.safe_load(profile_data) 668 | 669 | # 从命令行读取流量包的相关数据 670 | file ,ip ,field = GET_START.Get_Basic_Parameter() 671 | Field_Value ,ID_List ,DesID_List = GET_START.Build_Cmd_And_Get_Data(file_name=file ,des_IP=ip ,field_name=field) 672 | print(f"[+] [DEVICE_LIST]: {ID_List}\n[+] 您可以在USB_ID_List.txt中查找具体的设备名称\n" ,"-"*50) 673 | 674 | # 如果返回值有问题,报错并且停止程序 675 | if len(Field_Value) == 0: 676 | print(f"[-] 源IP为{ip},字段名称为{field}提取出来的数据为空,请检查一下IP和字段是否正确以及对应IP下是否有数据") 677 | exit(-1) 678 | 679 | # 获取记录的所有公司的ID号 680 | Company_List = profile_data["Company_List"][0] 681 | print(Company_List) 682 | 683 | # 判断目的IP是否是Unknown类型的数据,并且解密; 684 | Unknown_Type_Device.Check_Unknown_And_Recover(DesID_List ,profile_data ,Field_Value ,ip ,file ,Company_List) 685 | 686 | # 处理目的IP的数据 687 | if DesID_List[0] in Company_List: 688 | # 获取配置文件中的类名 689 | class_name = Company_List[DesID_List[0]] 690 | # 获取配置文件中的函数名 691 | Device_List = profile_data[class_name][1:] 692 | Def_Name = Get_defname(DesID_List[1] ,Device_List) 693 | if Def_Name == None: 694 | print("[-] 该产品尚未记录在工具中,请练习作者增添该工具") 695 | exit(-1) 696 | # 将获取的函数名和类名实例化并且执行 697 | operator.methodcaller(Def_Name ,Field_Value)(globals()[class_name]) 698 | 699 | # 处理默认值 700 | else: 701 | if len(Field_Value[0].strip("\n")) == 8: 702 | MOUSE.Value_2_plt(Field_Value) 703 | elif len(Field_Value[0].strip("\n")) == 16: 704 | KEYBOARD.Value_2_PlainText(Field_Value) 705 | 706 | # 询问是否需要爆破所有的值 707 | Brute_Choice = input("需要爆破所有的数据吗?[y/N](也许会不准确or是报错):").upper() 708 | if Brute_Choice != "Y": 709 | END.Message() 710 | exit(-1) 711 | 712 | # 接下来的所有代码就是爆破所有的数据,也不是都能爆破出来,只是给做题的时候提供一点线索(如果有的话) 713 | Burteforce(file ,ip ,profile_data ,Company_List) 714 | 715 | 716 | os.remove("temp_dataType.out") 717 | os.remove("temp_ALLIP.out") 718 | END.Message() 719 | 720 | if __name__ == "__main__": 721 | main() 722 | -------------------------------------------------------------------------------- /demo/304_wireless.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/304_wireless.pcapng -------------------------------------------------------------------------------- /demo/CTL_480.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/CTL_480.pcapng -------------------------------------------------------------------------------- /demo/Default_Keyboard.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/Default_Keyboard.pcap -------------------------------------------------------------------------------- /demo/GPW_502.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/GPW_502.pcapng -------------------------------------------------------------------------------- /demo/LOG_0xc539.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/LOG_0xc539.pcapng -------------------------------------------------------------------------------- /demo/LOG_G402Mouse.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y1shiny1shin/USBFlow_Soer/4edb56d3a404e7547de7a171c4e84c5d1a420ad5/demo/LOG_G402Mouse.pcapng -------------------------------------------------------------------------------- /profile.yaml: -------------------------------------------------------------------------------- 1 | Apple: 2 | - Company_ID: '0x05ac' 3 | Company_name: Apple, Inc. 4 | - Device_DefName: ANSI 5 | Device_ID: '0x024f' 6 | Device_Name: Aluminium Keyboard (ANSI) 7 | Device_Type: KeyBoard 8 | Company_List: 9 | - '0x046d': LOG 10 | '0x056a': WACOM 11 | '0x05ac': Apple 12 | '0x1532': Razer 13 | '0x18f8': Maxxter 14 | '0x248a': Maxxter 15 | Default: 16 | - datalen: 8 17 | name: Default Mouse 18 | type: Mouse 19 | - datalen: 16 20 | name: Default KeyBoard 21 | type: KeyBoard 22 | HP: 23 | - Company_ID: '0x03f0' 24 | Company_name: HP, Inc 25 | LOG: 26 | - Company_ID: '0x046d' 27 | Company_name: Logitech, Inc. 28 | - Device_DefName: LOG_Lightspeed_Reveiver 29 | Device_ID: '0xc539' 30 | Device_Name: Lightspeed Receiver 31 | Device_Type: Mouse 32 | - Device_DefName: G402_Gaming_Mouse 33 | Device_ID: '0xc07e' 34 | Device_Name: G402 Gaming Mouse 35 | Device_Type: Mouse 36 | - Device_DefName: LOG_G502_MOUSE 37 | Device_ID: '0xc08b' 38 | Device_Name: Logitech G502 SE HERO Gaming Mouse 39 | Device_Type: Mouse 40 | - Device_DefName: Mouse 41 | Device_ID: '0xc077' 42 | Device_Name: Logitech Mouse 43 | Device_Type: Mouse 44 | - Device_DefName: Unknown_keyboard 45 | Device_ID: '0xc341' 46 | Device_Name: Logitech Unknow Keyboard Type 47 | Device_Type: KeyBoard 48 | - Device_DefName: G304_Wireless 49 | Device_ID: '0xc53f' 50 | Device_Name: G304 Wireless 51 | Device_Type: Mouse 52 | - Device_DefName: G102_Wire 53 | Device_ID: '0xc09d' 54 | Device_Name: G102 Wire 55 | Device_Type: Mouse 56 | - Device_DefName: M90_M100_Mouse 57 | Device_ID: '0xc05a' 58 | Device_Name: M90/M100 Optical Mouse 59 | Device_Type: Mouse 60 | - Device_DefName: G402_Gaming_Mouse 61 | Device_ID: '0xc092' 62 | Device_Name: G102/G203 LIGHTSYNC Gaming Mouse 63 | Device_Type: Mouse 64 | Maxxter: 65 | - Company_ID: '0x18f8' 66 | Company_name: Maxxter 67 | - Device_DefName: Maxxter_OpticalGaming_Mouse 68 | Device_ID: '0x0f97' 69 | Device_Name: Optical Gaming Mouse [Xtrem] 70 | Device_Type: Mouse 71 | - Device_DefName: Wireless_Optical_Mouse_ACT 72 | Device_ID: '0x8366' 73 | Device_Name: Wireless Optical Mouse ACT-MUSW-002 74 | Device_Type: Mouse 75 | Razer: 76 | - Company_ID: '0x1532' 77 | Company_name: Razer USA, Ltd 78 | - Device_DefName: Basilisk_Mouse 79 | Device_ID: '0x0083' 80 | Device_Name: RC30-0315, Gaming Mouse [Basilisk x HyperSpeed] 81 | Device_Type: Mouse 82 | - Device_DefName: DeathAdder_Mouse 83 | Device_ID: '0x004f' 84 | Device_Name: RZ01-0145, Gaming Mouse [DeathAdder 2000 (Alternate)] 85 | Device_Type: Mouse 86 | - Device_DefName: Razer_UnkownType_Mouse 87 | Device_ID: '0x0098' 88 | Device_Name: Razer UnknownType Mouse 89 | Device_Type: Mouse 90 | - Device_DefName: Razer_UnkownType_Mouse2 91 | Device_ID: '0x0094' 92 | Device_Name: Razer UnknownType Mouse 2 93 | Device_Type: Mouse 94 | Unknown: 95 | '0x093a': 96 | Company_ID: '0x093a' 97 | Device_DefName: Mouse_Like_1 98 | Device_ID: '0x2530' 99 | Device_Type: Mouse Like 100 | '0x2341': 101 | Company_ID: '0x2341' 102 | Device_DefName: KeyBoard_Like_1 103 | Device_ID: '0x8036' 104 | Device_Type: Keyboard Like 105 | '0x256c': 106 | Company_ID: '0x256c' 107 | Device_DefName: Wacom_Like_1 108 | Device_ID: '0x006d' 109 | Device_Type: Wacom Like 110 | WACOM: 111 | - Company_ID: '0x056a' 112 | Company_name: Wacom Co., Ltd 113 | - Device_DefName: CTL_480 114 | Device_ID: '0x030e' 115 | Device_Name: CTL-480 [Intuos Pen (S)] 116 | Device_Type: wacom 117 | - Device_DefName: PTH_660 118 | Device_ID: '0x0357' 119 | Device_Name: PTH-660 [Intuos Pro (M)] 120 | Device_Type: wacom 121 | --------------------------------------------------------------------------------