Skip to content

Commit 170e1b3

Browse files
authored
Merge pull request #1599 from HackTricks-wiki/research_update_src_generic-methodologies-and-resources_basic-forensic-methodology_pcap-inspection_usb-keystrokes_20251124_082926
Research Update Enhanced src/generic-methodologies-and-resou...
2 parents c15c8f5 + 74f1f1b commit 170e1b3

File tree

1 file changed

+73
-5
lines changed
  • src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection

1 file changed

+73
-5
lines changed

src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,87 @@ If you have a pcap containing the communication via USB of a keyboard like the f
66

77
![](<../../../images/image (962).png>)
88

9-
You can use the tool [**ctf-usb-keyboard-parser**](https://github.com/TeamRocketIst/ctf-usb-keyboard-parser) to get what was written in the communication:
9+
USB keyboards usually speak the HID **boot protocol**, so every interrupt transfer towards the host is only 8 bytes long: one byte of modifier bits (Ctrl/Shift/Alt/Super), one reserved byte, and up to six keycodes per report. Decoding those bytes is enough to rebuild everything that was typed.
10+
11+
## USB HID report basics
12+
13+
The typical IN report looks like:
14+
15+
| Byte | Meaning |
16+
| --- | --- |
17+
| 0 | Modifier bitmap (`0x02` = Left Shift, `0x20` = Right Alt, etc.). Multiple bits can be set simultaneously. |
18+
| 1 | Reserved/padding but often reused by gaming keyboards for vendor data. |
19+
| 2-7 | Up to six concurrent keycodes in USB usage ID format (`0x04 = a`, `0x1E = 1`). `0x00` means "no key". |
20+
21+
Keyboards without NKRO usually send `0x01` in byte 2 when more than six keys are pressed to signal "rollover". Understanding this layout helps when you only have the raw `usb.capdata` bytes.
22+
23+
## Extracting HID data from a PCAP
24+
25+
### Wireshark workflow
26+
27+
1. **Isolate the device**: filter on interrupt IN traffic from the keyboard, e.g. `usb.transfer_type == 0x01 && usb.endpoint_address.direction == "IN" && usb.device_address == 3`.
28+
2. **Add useful columns**: right-click the `Leftover Capture Data` field (`usb.capdata`) and your preferred `usbhid.*` fields (e.g. `usbhid.boot_report.keyboard.keycode_1`) to follow keystrokes without opening every frame.
29+
3. **Hide empty reports**: apply `!(usb.capdata == 00:00:00:00:00:00:00:00)` to drop idle frames.
30+
4. **Export for post-processing**: `File -> Export Packet Dissections -> As CSV`, include `frame.number`, `usb.src`, `usb.capdata`, and `usbhid.modifiers` to script the reconstruction later.
31+
32+
### Command-line workflow
33+
34+
`ctf-usb-keyboard-parser` already automates the classic tshark + sed pipeline:
1035

1136
```bash
1237
tshark -r ./usb.pcap -Y 'usb.capdata && usb.data_len == 8' -T fields -e usb.capdata | sed 's/../:&/g2' > keystrokes.txt
1338
python3 usbkeyboard.py ./keystrokes.txt
1439
```
1540

16-
You can read more information and find some scripts about how to analyse this in:
41+
On newer captures you can keep both `usb.capdata` and the richer `usbhid.data` field by batching per device:
1742

18-
- [https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4](https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4)
19-
- [https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup)
43+
```bash
44+
tshark -r usb.pcapng -Y "usb.capdata || usbhid.data" -T fields -e usb.src -e usb.capdata -e usbhid.data | \
45+
sort -s -k1,1 | \
46+
awk '{ printf "%s", (NR==1 ? $1 : pre!=$1 ? "\n" $1 : "") " " $2; pre=$1 }' | \
47+
awk '{ for (i=2; i<=NF; i++) print $i > "usbdata-" $1 ".txt" }'
48+
```
2049

21-
{{#include ../../../banners/hacktricks-training.md}}
50+
Those per-device files drop straight into any decoder. If the capture came from BLE keyboards tunneled over GATT, filter on `btatt.value && frame.len == 20` and dump the hex payloads before decoding.
51+
52+
## Automating the decoding
53+
54+
- **ctf-usb-keyboard-parser** remains handy for quick CTF challenges and already ships in the repository.
55+
- **CTF-Usb_Keyboard_Parser** (`main.py`) parses both `pcap` and `pcapng` files natively, understands `LinkTypeUsbLinuxMmapped`/`LinkTypeUsbPcap`, and does not require tshark, so it works nicely inside isolated sandboxes.
56+
- **USB-HID-decoders** adds keyboard, mouse, and tablet visualizers. You can either run the `extract_hid_data.sh` helper (tshark backend) or `extract_hid_data.py` (scapy backend) and then feed the resulting text file to the decoder or replay modules to watch the keystrokes unfold.
57+
58+
## Quick Python decoder
59+
60+
```python
61+
#!/usr/bin/env python3
62+
import sys
63+
HID = {0x04:'a',0x05:'b',0x06:'c',0x07:'d',0x08:'e',0x09:'f',0x0a:'g',0x1c:'y',0x1d:'z',0x28:'\n'}
64+
for raw in sys.stdin:
65+
raw = raw.strip().replace(':', '')
66+
if len(raw) != 16:
67+
continue
68+
keycode = int(raw[4:6], 16)
69+
modifier = int(raw[0:2], 16)
70+
if keycode:
71+
char = HID.get(keycode, '?')
72+
if modifier & 0x02:
73+
char = char.upper()
74+
sys.stdout.write(char)
75+
```
76+
77+
Feed it with the plain hex lines dumped earlier to get an instant rough reconstruction without pulling a full parser into the environment.
78+
79+
## Troubleshooting tips
2280

81+
- If Wireshark does not populate `usbhid.*` fields, the HID report descriptor was probably not captured. Replug the keyboard while capturing or fall back to raw `usb.capdata`.
82+
- Windows captures require the **USBPcap** extcap interface; make sure it survived Wireshark upgrades, as missing extcaps leave you with empty device lists.
83+
- Always correlate `usb.bus_id:device:interface` (e.g. `1.9.1`) before decoding anything — mixing multiple keyboards or storage devices leads to nonsense keystrokes.
2384

85+
## References
2486

87+
- [ctf-usb-keyboard-parser](https://github.com/TeamRocketIst/ctf-usb-keyboard-parser)
88+
- [HackTheBox Deadly Arthropod write-up](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup)
89+
- [CTF-Usb_Keyboard_Parser](https://github.com/5h4rrk/CTF-Usb_Keyboard_Parser)
90+
- [USB-HID-decoders](https://github.com/Nissen96/USB-HID-decoders)
91+
92+
{{#include ../../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)