Dev-usbmon

From aldeid
Jump to navigation Jump to search

Description

Learn how to capture USB traffic and read it, using Wireshark and Tshark.

Useful resources:

Capture USB traffic

Identify USB interface

The lsusb command will list USB devices and reveals the bus number:

$ lsusb 
Bus 003 Device 002: ID 8087:8000 Intel Corp. 
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 004: ID 138a:0017 Validity Sensors, Inc. VFS 5011 fingerprint sensor
Bus 002 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 002 Device 005: ID 8087:07dc Intel Corp. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Now, if you have a look at the /dev directory, you'll notice several usbmon{N} interfaces, where N is the bus number

$ ll /dev/ | grep usb
drwxr-xr-x  2 root    root          80 Mar 23 15:44 usb
crw-------  1 root    root    241,   0 Mar 23 17:04 usbmon0
crw-------  1 root    root    241,   1 Mar 23 17:04 usbmon1
crw-------  1 root    root    241,   2 Mar 23 17:04 usbmon2
crw-------  1 root    root    241,   3 Mar 23 17:04 usbmon3
crw-------  1 root    root    241,   4 Mar 23 17:04 usbmon4

Capture USB traffic

To dump USB traffic on Linux, you need the usbmon kernel module:

# modprobe usbmon

Start wireshark as root and you'll see the usbmon interfaces:

Wireshark-usbmon-interfaces.png

Read USB traffic

Keyboard

The data is composed of 8 bytes.

  • The 1st byte indicates if the pressed key is upper (0x02) or lower (0x00)
  • The 3rd byte indicates the key pressed (refer to [1], section #10 Keyboard/Keypad Page (0x07) for the list of codes)

Wireshark-usb-keyboard-usbcapdata.png

Let's assume you have captured a USB traffic from a USB keyboard in a file named keyboard.pcap. You can extract the relevant data using tshark as follows:

$ tshark -r keyboard.pcap -2 -R "usb.capdata!=\"\"" -T fields -e usb.capdata > keyboard.txt

You can then use the following python script to read keys from this text file.

#!/usr/bin/python3

newmap = { 1: '[ErrorRollOver]', 2: '',#[LSHIFT]', 4: 'a', 5: 'b', 6: 'c',
    7: 'd', 8: 'e', 9: 'f', 10: 'g', 11: 'h', 12: 'i', 13: 'j', 14: 'k',
    15: 'l', 16: 'm', 17: 'n', 18: 'o', 19: 'p', 20: 'q', 21: 'r', 22: 's',
    23: 't', 24: 'u', 25: 'v', 26: 'w', 27: 'x', 28: 'y', 29: 'z', 30: '1',
    31: '2', 32: '3', 33: '4', 34: '5', 35: '6', 36: '7', 37: '8', 38: '9',
    39: '0', 40: '[ENTER]', 41: '[ESC]', 42: '[DEL]', 43: '[TAB]', 44: ' ',
    45: '-', 46: '=', 47: '[', 48: ']', 55: '.', 56: '/', 57: '[CAPSLOCK]',
    79: '[RIGHTARROW]', 80: '[LEFTARROW]' }

myKeys = open('keyboard.txt')
output = []
i = 1
for line in myKeys:
    bytesArray = bytearray.fromhex(line.strip())
    
    keyVal = int(bytesArray[2])
    if keyVal != 0:
        if int(bytesArray[0]) == 2:
            caps = 1
        else:
            caps = 0

        if keyVal in newmap:
            if caps == 1:
                output.append(newmap[keyVal].upper())
            else:
                output.append(newmap[keyVal])
            print ("%s\t%s\t%s\t%s\t%s" % (hex(keyVal), keyVal, newmap[keyVal], caps, bytesArray))
        else:
            print ('No map found for this value: ' + str(keyVal))

print(''.join(output))

Below is an output example:

0x28	40	[ENTER]	0	bytearray(b'\x00\x00(\x00\x00\x00\x00\x00')
0x13	19	p	1	bytearray(b'\x02\x00\x13\x00\x00\x00\x00\x00')
0x14	20	q	0	bytearray(b'\x00\x00\x14\x00\x00\x00\x00\x00')
0x15	21	r	0	bytearray(b'\x00\x00\x15\x00\x00\x00\x00\x00')
0x17	23	t	0	bytearray(b'\x00\x00\x17\x00\x00\x00\x00\x00')
0x2c	44	 	0	bytearray(b'\x00\x00,\x00\x00\x00\x00\x00')
0x1e	30	1	1	bytearray(b'\x02\x00\x1e\x00\x00\x00\x00\x00')
0x2c	44	 	0	bytearray(b'\x00\x00,\x00\x00\x00\x00\x00')
0x37	55	.	0	bytearray(b'\x00\x007\x00\x00\x00\x00\x00')
0x2c	44	 	0	bytearray(b'\x00\x00,\x00\x00\x00\x00\x00')
0xc	12	i	0	bytearray(b'\x00\x00\x0c\x00\x00\x00\x00\x00')
0x19	25	v	1	bytearray(b'\x02\x00\x19\x00\x00\x00\x00\x00')
0x5	5	b	1	bytearray(b'\x02\x00\x05\x00\x00\x00\x00\x00')
0x12	18	o	1	bytearray(b'\x02\x00\x12\x00\x00\x00\x00\x00')
0x15	21	r	1	bytearray(b'\x02\x00\x15\x00\x00\x00\x00\x00')
0x1d	29	z	0	bytearray(b'\x00\x00\x1d\x00\x00\x00\x00\x00')
0x27	39	0	1	bytearray(b"\x02\x00\'\x00\x00\x00\x00\x00")
0xe	14	k	1	bytearray(b'\x02\x00\x0e\x00\x00\x00\x00\x00')
0xa	10	g	1	bytearray(b'\x02\x00\n\x00\x00\x00\x00\x00')
0xa	10	g	0	bytearray(b'\x00\x00\n\x00\x00\x00\x00\x00')
0x12	18	o	0	bytearray(b'\x00\x00\x12\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x11	17	n	1	bytearray(b'\x02\x00\x11\x00\x00\x00\x00\x00')
0x16	22	s	1	bytearray(b'\x02\x00\x16\x00\x00\x00\x00\x00')
0x18	24	u	1	bytearray(b'\x02\x00\x18\x00\x00\x00\x00\x00')
0xb	11	h	0	bytearray(b'\x00\x00\x0b\x00\x00\x00\x00\x00')
0x8	8	e	1	bytearray(b'\x02\x00\x08\x00\x00\x00\x00\x00')
0x18	24	u	1	bytearray(b'\x02\x00\x18\x00\x00\x00\x00\x00')
0xa	10	g	0	bytearray(b'\x00\x00\n\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x1e	30	1	1	bytearray(b'\x02\x00\x1e\x00\x00\x00\x00\x00')
0xe	14	k	0	bytearray(b'\x00\x00\x0e\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0xc	12	i	1	bytearray(b'\x02\x00\x0c\x00\x00\x00\x00\x00')
0x2e	46	=	1	bytearray(b'\x02\x00.\x00\x00\x00\x00\x00')
0x6	6	c	1	bytearray(b'\x02\x00\x06\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0xc	12	i	1	bytearray(b'\x02\x00\x0c\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x14	20	q	1	bytearray(b'\x02\x00\x14\x00\x00\x00\x00\x00')
0x28	40	[ENTER]	0	bytearray(b'\x00\x00(\x00\x00\x00\x00\x00')
0x28	40	[ENTER]	0	bytearray(b'\x00\x00(\x00\x00\x00\x00\x00')
0x28	40	[ENTER]	0	bytearray(b'\x00\x00(\x00\x00\x00\x00\x00')
0x6	6	c	0	bytearray(b'\x01\x00\x06\x00\x00\x00\x00\x00')
[ENTER]Pqrt 1 . iVBORz0KGgoQQQQNSUhEUgQQQ1kQQQI=CQIQQQ[ENTER][ENTER][ENTER]c

Mouse

The data is composed of 4 bytes:

  • 1st byte represents the button:
    • 0x00 = no button
    • 0x01 = left button
    • 0x02 = right button
  • 2nd byte: signed byte, with the highest bit being the sign bit
    • if positive value: gives the number of pixels the mouse is horizontally shifted to the right
    • if negative value, represents the number of pixels the mouse is horizontally shifted to the left
  • 3rd byte: signed byte, with the highest bit being the sign bit
    • if positive value: gives the number of pixels the mouse is vertically shifted to the top
    • if negative value, represents the number of pixels the mouse is vertically shifted to the bottom

Wireshark-usb-mouse-capdata.png

Suppose you have captured your USB mouse traffic in mouse.pcap. You can use UsbMiceDataHacker.py to decrypt the traffic.

The below example shows the mouse movements when the left button was pressed.

$ python2 UsbMiceDataHacker.py mouse.pcap LEFT

Here is the output:

UsbMiceDataHacker-output.png

Comments

blog comments powered by Disqus

Keywords: forensics drivers linux dev usb lsusb usbmon capture pcap