├── Images └── USBDeviceViewer.png ├── README.md ├── requirements.txt └── usbfind.py /Images/USBDeviceViewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Merimetso-Code/USB-Hacking/23c6ad2d6c1b5fb7a7b1b341a26e67dd352c4134/Images/USBDeviceViewer.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # USB Hacking 2 | 3 | ## USB Hacking Tools for Linux/MAC and Windows 4 | There are a number of tools available for the Linux/MAC and Windows operating systems that we can use when profiling and hacking USB connections. 5 | #### USB Hacking Tools for Linux and MAC 6 | On the Unix/Linux and the MAC the standard tool for profiling and identifying USB connections is called *lsusb*. The following is the online help page for *lsusb*. 7 | On Linux systems we can install *lsusb* using the following command: *$apt install lsusb*. 8 | ```sh 9 | $ lsusb -h 10 | Usage: lsusb [options]... 11 | List USB devices 12 | -v, --verbose 13 | Increase verbosity (show descriptors) 14 | -s [[bus]:][devnum] 15 | Show only devices with specified device and/or 16 | bus numbers (in decimal) 17 | -d vendor:[product] 18 | Show only devices with the specified vendor and 19 | product ID numbers (in hexadecimal) 20 | -D device 21 | Selects which device lsusb will examine 22 | -t, --tree 23 | Dump the physical USB device hierarchy as a tree 24 | -V, --version 25 | Show version of program 26 | -h, --help 27 | Show usage and help 28 | $ 29 | ``` 30 | Simply running the *lsusb* command will produce a list of devices that are currently connected to the target computer system. 31 | It will display the bus that the device is connected to along with the device identifier and description of the device. 32 | ```sh 33 | $ lsusb 34 | Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 35 | Bus 002 Device 011: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC 36 | Bus 002 Device 009: ID 0e0f:0008 VMware, Inc. VMware Virtual USB Mouse 37 | Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub 38 | Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse 39 | Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 40 | $ 41 | ``` 42 | We can also use the *lsusb* tool to identify the class of USB device (eg. Wireless or Hub), along with the type of device driver required by the USB device. 43 | ```sh 44 | $ lsusb -t 45 | /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M 46 | |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M 47 | |__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/7p, 12M 48 | |__ Port 1: Dev 9, If 0, Class=Wireless, Driver=btusb, 12M 49 | |__ Port 1: Dev 9, If 1, Class=Wireless, Driver=btusb, 12M 50 | |__ Port 2: Dev 11, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M 51 | /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M 52 | $ 53 | ``` 54 | We can also use *lsusb* to find detailed information about a specific USB device if we known its 55 | vendor identifier (idVendor) and its product identifier (idProduct). The key elements that we are 56 | interested in are confirming that the Manufacturer and Product is what we expect it to be be, and 57 | that we can identify the data transfer type and data packet size. 58 | ```sh 59 | $ lsusb -d 0x0e0f:0x0003 -v 60 | Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse 61 | Device Descriptor: 62 | bLength 18 63 | bDescriptorType 1 64 | bcdUSB 1.10 65 | bDeviceClass 0 66 | bDeviceSubClass 0 67 | bDeviceProtocol 0 68 | bMaxPacketSize0 8 69 | idVendor 0x0e0f VMware, Inc. 70 | idProduct 0x0003 Virtual Mouse 71 | bcdDevice 1.03 72 | iManufacturer 1 VMware 73 | iProduct 2 VMware Virtual USB Mouse 74 | . . . . . . 75 | Endpoint Descriptor: 76 | bLength 7 77 | bDescriptorType 5 78 | bEndpointAddress 0x81 EP 1 IN 79 | bmAttributes 3 80 | Transfer Type Interrupt 81 | Synch Type None 82 | Usage Type Data 83 | wMaxPacketSize 0x0008 1x 8 bytes 84 | bInterval 1 85 | $ 86 | ``` 87 | The *usb-devices* is another Linux tool that can be used to profile a set of USB devices. 88 | This tool provides not only the *Bus* and *Device* identifier, but also manufacturer and product information. 89 | ```sh 90 | $ usb-devices 91 | 92 | T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 6 93 | D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 94 | P: Vendor=1d6b ProdID=0002 Rev=05.04 95 | S: Manufacturer=Linux 5.4.0-48-generic ehci_hcd 96 | S: Product=EHCI Host Controller 97 | S: SerialNumber=0000:02:03.0 98 | C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=0mA 99 | I: If#=0x0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub 100 | . . . . . . . . . . . 101 | $ 102 | ``` 103 | 104 | #### USB Hacking Tools for Microsoft Windows 105 | The standard tools used to profile and gather intelligence about USB connections in the Microsoft Windows Operating system are contained in the SDK. For MicroSoft Windows 10 the SDK tool *devcon* can be located at: https://docs.microsoft.com/en-gb/windows-hardware/drivers/devtest/devcon. In the following example we are going to use the *devcon* tool to identify all devices to type *USB* that can connect to the operating system. 106 | ```sh 107 | C:\>devcon findall =USB 108 | USB\ROOT_HUB20\4&25BC73E0&0 : USB Root Hub 109 | USB\VID_046D&PID_0A66\6&1ADC9119&0&1 : USB Composite Device 110 | USB\VID_046D&PID_C313\5&1BADB653&0&11 : USB Composite Device 111 | USB\VID_046D&PID_0A66\6&37942266&0&4 : USB Composite Device 112 | USB\VID_0951&PID_1666\08606E6D3FE5BF303337EC21 : USB Mass Storage Device 113 | USB\VID_046D&PID_085E\29317058 : Logitech BRIO 114 | USB\VID_0451&PID_8140\5&1BADB653&0&19 : Generic SuperSpeed USB Hub 115 | USB\ROOT_HUB30\4&52BDE52&0&0 : USB Root Hub (USB 3.0) 116 | USB\VID_2109&PID_0812\5&1BADB653&0&16 : Generic SuperSpeed USB Hub 117 | USB\VID_059B&PID_0032\8032487F934E3821 : Iomega USB Bus Powered Zip 250 118 | USB\VID_046D&PID_0A66\5&1BADB653&0&14 : USB Composite Device 119 | USB\VID_0781&PID_5591\4C530001111127119231 : USB Mass Storage Device 120 | USB\VID_21A9&PID_1006\0000000004BE : Saleae Logic Pro 16 USB Logic Analyzer 121 | USB\VID_064F&PID_03E9\000002086370 : USB Mass Storage Device 122 | USB\VID_174C&PID_1153\00000000000000000000 : USB Mass Storage Device 123 | USB\VID_090C&PID_1000\SCY0000000102485 : USB Mass Storage Device 124 | USB\VID_0BDA&PID_0321\201312261010 : Realtek USB 3.0 Card Reader 125 | USB\VID_1F75&PID_0903\1874321027 : USB Mass Storage Device 126 | USB\ROOT_HUB20\4&2266B0C5&0 : USB Root Hub 127 | USB\VID_2109&PID_2812\5&1BADB653&0&5 : Generic USB Hub 128 | USB\VID_8087&PID_8002\5&31D9FF4&0&1 : Generic USB Hub 129 | . . . . . . . . . . 130 | 29 matching device(s) found. 131 | 132 | C:\> 133 | ``` 134 | The other tool that we can use for profiling USB connections on Micorosft Windows is cann *USBVIEW*. 135 | This allows to navigate in a graphical form between various USB devices. 136 | ![USBView](Images/USBDeviceViewer.png) 137 | ## Installation of the USB module in Python 3.8 138 | We can install the pyusb module using PIP 139 | ```sh 140 | $ pip install pysub 141 | ``` 142 | Or we can install the modules using the Conda utility. 143 | ```sh 144 | $ conda install pyusb 145 | ``` 146 | Or you can use *pip* to install all of the Python dependencies via the following: 147 | ```sh 148 | $ pip install requirements.txt 149 | ``` 150 | We can then test that the module has been installed correctly by importing it in Python. 151 | ```sh 152 | $ python 153 | Python 3.8.3 (default, Jul 2 2020, 11:26:31) 154 | [Clang 10.0.0 ] :: Anaconda, Inc. on darwin 155 | Type "help", "copyright", "credits" or "license" for more information 156 | >>> 157 | >>> import usb.core 158 | >>> 159 | >>> import usb.util 160 | >>> 161 | ``` 162 | ## USB Hacking Tools in Python 163 | The following are the tools that we can use when hacking a USB connection on a embedded system. 164 | 165 | - usbfind.py 166 | 167 | ## usbfind 168 | The role and function of the usbfind tool is to enumerate all USB connections on a target system. When enumerating a USB connection we can choose to be verbose or succint. 169 | Verbose output will not only profile the USB device but also the USB connection and the USB endpoint in the operating system. 170 | ```sh 171 | $ python ./usbfind.py -h 172 | 173 | Program: usbfind.py - Version: 1.0 - Author: ab@merimetso.net - Date: 2020/10/21 174 | 175 | USAGE: usbfind.py [-h] [-v] [-s bus:device] [-b backend] 176 | 177 | Optional Arguments: 178 | -h Show this help message and exit. 179 | -v Display verbose USB information. Please note this argument overrules -s 180 | -s Specify a specific USB device to profile. The device must be specified as a bus:devic 181 | For example, you can profile the device locate at BusID:001 and DeviceID:006 as 182 | $ python usbfind.py -s 001:006. Please note numbers must be decimal. 183 | -b Specify the backend responsible for process USB API calls. For example to use the 184 | /usr/lib/libusb-1.0.so backend we would specify: $ python usbfind.py -b 1 185 | EXAMPLE: 186 | To produce a verbose profile of the device locate at BusID:002 and DeviceID:005 using the 187 | libusb backend to process all USB API calls we would use the following: 188 | $ python usbfind.py -v -s 002:005 -b 1 189 | 190 | $ 191 | ``` 192 | In the following example we are going to gnerate a succinct list USB device connected to a target system. 193 | ```sh 194 | $ python usnfind.py 195 | Running USB Profiling Tool - Version: 1.0 - Author:ab@merimetso.net 196 | 197 | Manufacturer : 0x3 198 | Product : 0x2 199 | Device Class : 0x9 200 | Device Protocol : 0x0 201 | Device SubClass : 0x0 202 | Device Version : 05.04 203 | Device DevNum : 0x1 204 | Device Filename : 205 | Serial Number : 0x1 206 | Product ID : 0x2 207 | Vendor ID : 0x1d6b 208 | Max Packet Size : 0x40 209 | USB Version : 02.00 210 | . . . . . . . . . . . . . . . 211 | $ 212 | ``` 213 | We can also choose to profile a USB connection in verbose mode. 214 | ```sh 215 | $ python usbfind.py -v 216 | Running USB Profiling Tool - Version: 1.0 - Author:ab@merimetso.net 217 | 218 | DEVICE ID 1d6b:0002 on Bus 001 Address 001 ================= 219 | bLength : 0x12 (18 bytes) 220 | bDescriptorType : 0x1 Device 221 | bcdUSB : 0x200 USB 2.0 222 | bDeviceClass : 0x9 Hub 223 | bDeviceSubClass : 0x0 224 | bDeviceProtocol : 0x0 225 | bMaxPacketSize0 : 0x40 (64 bytes) 226 | idVendor : 0x1d6b 227 | idProduct : 0x0002 228 | bcdDevice : 0x504 Device 5.04 229 | iManufacturer : 0x3 Error Accessing String 230 | iProduct : 0x2 Error Accessing String 231 | iSerialNumber : 0x1 Error Accessing String 232 | bNumConfigurations : 0x1 233 | CONFIGURATION 1: 0 mA ==================================== 234 | bLength : 0x9 (9 bytes) 235 | bDescriptorType : 0x2 Configuration 236 | wTotalLength : 0x19 (25 bytes) 237 | bNumInterfaces : 0x1 238 | bConfigurationValue : 0x1 239 | iConfiguration : 0x0 240 | bmAttributes : 0xe0 Self Powered, Remote Wakeup 241 | bMaxPower : 0x0 (0 mA) 242 | INTERFACE 0: Hub ======================================= 243 | bLength : 0x9 (9 bytes) 244 | bDescriptorType : 0x4 Interface 245 | bInterfaceNumber : 0x0 246 | bAlternateSetting : 0x0 247 | bNumEndpoints : 0x1 248 | bInterfaceClass : 0x9 Hub 249 | bInterfaceSubClass : 0x0 250 | bInterfaceProtocol : 0x0 251 | iInterface : 0x0 252 | ENDPOINT 0x81: Interrupt IN ========================== 253 | bLength : 0x7 (7 bytes) 254 | bDescriptorType : 0x5 Endpoint 255 | bEndpointAddress : 0x81 IN 256 | bmAttributes : 0x3 Interrupt 257 | wMaxPacketSize : 0x4 (4 bytes) 258 | bInterval : 0xc 259 | 260 | . . . . . . . . . . . . . . . 261 | $ 262 | ``` 263 | ## Bug Report 264 | - Please report bugs, error and omissions to *ab@merimetso.net* 265 | 266 | ## License 267 | - MIT 268 | 269 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyusb 2 | -------------------------------------------------------------------------------- /usbfind.py: -------------------------------------------------------------------------------- 1 | # 2 | # This is the USB profiling tool for USD devices 3 | # Program Name: usbfind.py 4 | # Program Version Number: 1.0 5 | # Author(s): ab@merimetso.net 6 | # Date: 31st October 2020 7 | # 8 | # 9 | import sys 10 | import usb.core 11 | # 12 | from objbrowser import browse 13 | # 14 | # 15 | # 16 | def usage(): 17 | print("\nProgram: usbfind.py - Version: 1.0 - Author: ab@merimetso.net - Date: 2020/10/21") 18 | print("") 19 | print("USAGE: usbfind.py [-h] [-v] [-s bus:device] [-b backend]") 20 | print("") 21 | print(" Optional Arguments:") 22 | print(" -h Show this help message and exit.") 23 | print(" -v Display verbose USB information. Please note this argument overrules -s") 24 | print(' -s Specify a specific USB device to profile. The device must be specified as a bus:devic') 25 | print(' For example, you can profile the device locate at BusID:001 and DeviceID:006 as') 26 | print(' $ python usbfind.py -s 001:006. Please note numbers must be decimal.') 27 | print(' -b Specify the backend responsible for process USB API calls. For example to use the ') 28 | print(' /usr/lib/libusb-1.0.so backend we would specify $ python usbfind.py -b 1') 29 | print('EXAMPLE:') 30 | print(' To produce a verbose profile of the device locate at BusID:002 and DeviceID:005 using the ') 31 | print(' libusb backend to process all USB API calls we would use the following:') 32 | print(' $ python usbfind.py -v -s 002:005 -b 1') 33 | print("") 34 | sys.exit(0) 35 | # 36 | # 37 | # 38 | def main(): 39 | print("\nRunning USB Profiling Tool - Version: 1.0 - Author:ab@merimetso.net\n") 40 | if BackEnd != 'NONE': 41 | try: 42 | if str(BackEnd) == '1': 43 | backnd = usb.backend.libusb1.get_backend(find_library=lambda x: "/usr/lib/libusb-1.0.so") 44 | bsses = usb.busses(backend=backnd) 45 | else: 46 | print('ERROR: Attempt to use unkown USB backend.') 47 | sys.exit(0) 48 | except: 49 | print('ERROR: Error Processing Backend Request.') 50 | sys.exit(0) 51 | else: 52 | bsses = usb.busses() 53 | # 54 | for bus in bsses: 55 | 56 | for device in bus.devices: 57 | if Verbose == True: 58 | print(device.dev) 59 | else: 60 | if Busses == 'NONE': 61 | print('Bus Location : ' + str(hex(bus.location))) 62 | print('Manufacturer : ' + str(hex(device.iManufacturer))) 63 | print('Product : ' + str(hex(device.iProduct))) 64 | print('Device Class : ' + str(hex(device.deviceClass))) 65 | print('Device Protocol : ' + str(hex(device.deviceProtocol))) 66 | print('Device SubClass : ' + str(hex(device.deviceSubClass))) 67 | print('Device Version : ' + str(device.deviceVersion)) 68 | print('Device DevNum : ' + str(hex(device.devnum))) 69 | print('Device Filename : ' + str(device.filename)) 70 | print('Serial Number : ' + str(hex(device.iSerialNumber))) 71 | print('Product ID : ' + str(hex(device.idProduct))) 72 | print('Vendor ID : ' + str(hex(device.idVendor))) 73 | print('Max Packet Size : ' + str(hex(device.maxPacketSize))) 74 | print('USB Version : ' + str(device.usbVersion)) 75 | print('') 76 | else: 77 | try: 78 | busID = int(Busses.split(':')[0]) 79 | venID = int(Busses.split(':')[1]) 80 | if (busID == int(bus.location) and venID == int(device.idProduct)): 81 | print('Bus Location : ' + str(hex(bus.location))) 82 | print('Manufacturer : ' + str(hex(device.iManufacturer))) 83 | print('Product : ' + str(hex(device.iProduct))) 84 | print('Device Class : ' + str(hex(device.deviceClass))) 85 | print('Device Protocol : ' + str(hex(device.deviceProtocol))) 86 | print('Device SubClass : ' + str(hex(device.deviceSubClass))) 87 | print('Device Version : ' + str(device.deviceVersion)) 88 | print('Device DevNum : ' + str(hex(device.devnum))) 89 | print('Device Filename : ' + str(device.filename)) 90 | print('Serial Number : ' + str(hex(device.iSerialNumber))) 91 | print('Product ID : ' + str(hex(device.idProduct))) 92 | print('Vendor ID : ' + str(hex(device.idVendor))) 93 | print('Max Packet Size : ' + str(hex(device.maxPacketSize))) 94 | print('USB Version : ' + str(device.usbVersion)) 95 | print('') 96 | except: 97 | print('ERROR: Error process Bus ID and Vendor ID.') 98 | sys.exit(0) 99 | # 100 | # 101 | # 102 | def mmember(argList, member): 103 | counter = 0 104 | for item in argList: 105 | if argList[counter] == member: return True, counter 106 | counter = counter + 1 107 | return False, -1 108 | 109 | 110 | # 111 | # 112 | # 113 | if __name__ == "__main__": 114 | Verbose = False 115 | Busses = 'NONE' 116 | BackEnd = 'NONE' 117 | # 118 | if len(sys.argv) == 1: 119 | main() 120 | sys.exit(0) 121 | else: 122 | sys.argv.pop(0) 123 | # 124 | try: 125 | memTruth, index = mmember(sys.argv, '-v') 126 | if memTruth: 127 | sys.argv.pop(index) 128 | Verbose = True 129 | except: 130 | print('ERROR: Error processing "-v" argument in the command line.') 131 | print(' If you need to see the help page then use the "-h" option.\n') 132 | sys.exit(0) 133 | # 134 | 135 | memTruth, index = mmember(sys.argv, '-h') 136 | if memTruth: 137 | sys.argv.pop(index) 138 | usage() 139 | sys.exit(0) 140 | 141 | # 142 | try: 143 | memTruth, index = mmember(sys.argv, '-s') 144 | if memTruth: 145 | sys.argv.pop(index) 146 | Busses = sys.argv.pop(index) 147 | except: 148 | print('ERROR: Error processing the "-s" argument in the command line.') 149 | sys.exit(0) 150 | # 151 | try: 152 | memTruth, index = mmember(sys.argv, '-b') 153 | if memTruth: 154 | sys.argv.pop(index) 155 | BackEnd = sys.argv.pop(index) 156 | except: 157 | print('ERROR: Error processing the "-b" argument in the command line.') 158 | sys.exit(0) 159 | # 160 | if len(sys.argv) == 0: 161 | main() 162 | sys.exit(1) 163 | else: 164 | print('ERROR: There is an illegal parameter in the command line.') 165 | print(' If you need to see the help page then use the "-h" option.\n') 166 | sys.exit(0) 167 | # 168 | # 169 | # 170 | # The End of the FINDUSB.PY Program. 171 | # 172 | 173 | --------------------------------------------------------------------------------