在 Ubuntu 20.04 上将 USB 击键的 (Wireshark) LiveCapture 读入 python?
Reading a (Wireshark) LiveCapture of USB keystrokes into python on Ubuntu 20.04?
上下文
我的键盘蓝牙不稳定,这是设备的一个已知问题。制造商表示,micro-USB 不传输按键,仅用于充电。但是,我使用 Wireshark 检查了 USB 数据,发现它确实通过其微型 USB 连接传输击键。所以我试图通过微型 USB 连接让键盘重获新生(并希望能帮助遇到同样问题的人)。
系统
Ubuntu 20.04
方法
我已经在 Wireshark 中识别了我的键盘设备的 USB 端口,并记录了该端口上的数据流。该数据被保存到一个名为 abcd.pcapng
的文件中(我在录制过程中按下了按钮 abcd
)。接下来,我编写了一个基本的 python 脚本,该脚本使用 tshark
将 abcd.pcapng
文件转换为其原始按键 abcd
.
代码
这是将 abcd.pcapng
文件转换为字母 abcd
:
的 Python 代码
# This script extracts the keypresses from a pcapng file.
import os
pcapng_filename = "abcd.pcapng"
keypress_ids_filename = "keypress_ids.txt"
# create the output for
command_pcapng_to_keypress_ids = (
f"tshark -r '{pcapng_filename}' -T fields -e usb.capdata > {keypress_ids_filename}"
)
print(
f"Running the following bash command to convert the pcapng file to 00xx00000 nrs:\n{command_pcapng_to_keypress_ids}"
)
os.system(command_pcapng_to_keypress_ids)
# read keypress id file
switcher = {
"04": "a", # or A
"05": "b", # or B
"06": "c", # or C
"07": "d", # or D
"08": "e", # or E
"09": "f", # or F
"0A": "g", # or G
"0B": "h", # or H
"0C": "i", # or I
"0D": "j", # or J
"0E": "k", # or K
"0F": "l", # or L
"10": "m", # or M
"11": "n", # or N
"12": "o", # or O
"13": "p", # or P
"14": "q", # or Q
"15": "r", # or R
"16": "s", # or S
"17": "t", # or T
"18": "u", # or U
"19": "v", # or V
"1A": "w", # or W
"1B": "x", # or X
"1C": "y", # or Y
"1D": "x", # or Z
"1E": "1", # or !
"1F": "2", # or @
"20": "3", # or #
"21": "4", # or $
"22": "5", # or %
"23": "6", # or ^
"24": "7", # or &
"25": "8", # or *
"26": "9", # or (
"27": "0", # or )
"2D": "-", # or _
"2E": "+", # or =
"2F": "[", # or {
"30": "]", # or }
"31": '"', # or |
"33": ";", # or :
"34": "'", # or "
"35": "`", # or ~
"36": ",", # or <
"37": ".", # or >
"38": "/", # or ?
}
def readFile(filename):
fileOpen = open(filename)
return fileOpen
file = readFile(keypress_ids_filename)
print(f"file={file}")
# parse the 0000050000000000 etc codes and convert them into keystrokes
for line in file:
if len(line) == 17:
two_chars = line[4:6]
try:
print(
f"line={line[0:16]}, relevant characters indicating keypress ID: {two_chars} convert keypres ID to letter: {switcher[two_chars]}"
)
except:
pass
输出
指定文件的脚本输出是:
Running the following bash command to convert the pcapng file to 00xx00000 nrs:
tshark -r 'abcd.pcapng' -T fields -e usb.capdata > keypress_ids.txt
file=<_io.TextIOWrapper name='keypress_ids.txt' mode='r' encoding='UTF-8'>
line=0000040000000000, relevant characters indicating keypress ID: 04 convert keypres ID to letter: a
line=0000050000000000, relevant characters indicating keypress ID: 05 convert keypres ID to letter: b
line=0000060000000000, relevant characters indicating keypress ID: 06 convert keypres ID to letter: c
line=0000070000000000, relevant characters indicating keypress ID: 07 convert keypres ID to letter: d
问题
我如何调整代码以直接获取 USB 数据作为连续流,而不是首先必须开始和停止记录 USB 数据,然后必须创建输出 abcd.pcapng
文件?
例如,是否有 Wireshark-api 或 tshark 函数开始侦听直到 the/some 脚本停止?
解决方案
以下名为 live_capture_keystrokes.py
的脚本捕获包含击键信号的 Leftover Capture Data
,它们由 Python 代码实时且连续地解析。
我认为每次重新启动计算机时激活 usb 监控很重要(如果您想 运行 此脚本成功)。为此,您可以 运行:
sudo modprobe usbmon
理想情况下,你会 运行 如果没有 sudo,那也将阻止 运行 使用 sudo 的 python 文件,但我还没有弄清楚如何 运行 modprobe usbmon
没有 sudo。
代码
此 live_capture_keystrokes.py
脚本需要 运行 with sudo 如果 modprobe usbmon
是 运行 with sudo。要 运行 sudo 中的 python 脚本,可以键入:
sudo su
# sudo apt install python3
# pip install pyshark
# python3 live_capture_keystrokes.py
而live_capture_keystrokes.py
的内容是:
import pyshark
# Get keystrokes data
print("\n----- Capturing keystrokes from usbmon0 --------------------")
capture = pyshark.LiveCapture(interface='usbmon0', output_file='output.pcap')
# Source: https://www.programcreek.com/python/example/92561/pyshark.LiveCapture
for i, packet in enumerate(capture.sniff_continuously()):
try:
data= packet[1].usb_capdata.split(":")
print(data)
except:
pass
capture.clear()
capture.close()
print(f'DONE')
输出
输出尚未解析回击键,稍后我会添加。然而,这就是输出,每次您按下 USB 键盘上的一个键,它都会将随附的列表直接打印到屏幕上。
a['00', '00', '04', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
b['00', '00', '05', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
c['00', '00', '06', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
d['00', '00', '07', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
e['00', '00', '08', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
f['00', '00', '09', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
g['00', '00', '0a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
h['00', '00', '0b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
i['00', '00', '0c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
j['00', '00', '0d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
k['00', '00', '0e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
l['00', '00', '0f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
m['00', '00', '10', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
n['00', '00', '11', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
o['00', '00', '12', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
p['00', '00', '13', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
q['00', '00', '14', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
r['00', '00', '15', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
s['00', '00', '16', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
t['00', '00', '17', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
u['00', '00', '18', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
v['00', '00', '19', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
w['00', '00', '1a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
x['00', '00', '1b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
y['00', '00', '1c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
z['00', '00', '1d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
0['00', '00', '62', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
1['00', '00', '59', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
2['00', '00', '5a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
3['00', '00', '5b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
4['00', '00', '5c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
5['00', '00', '5d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
6['00', '00', '5e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
7['00', '00', '5f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
8['00', '00', '60', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
9['00', '00', '61', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
1['00', '00', '1e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
2['00', '00', '1f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
3['00', '00', '20', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
4['00', '00', '21', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
5['00', '00', '22', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
6['00', '00', '23', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
7['00', '00', '24', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
8['00', '00', '25', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
9['00', '00', '26', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
0['00', '00', '27', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
上下文
我的键盘蓝牙不稳定,这是设备的一个已知问题。制造商表示,micro-USB 不传输按键,仅用于充电。但是,我使用 Wireshark 检查了 USB 数据,发现它确实通过其微型 USB 连接传输击键。所以我试图通过微型 USB 连接让键盘重获新生(并希望能帮助遇到同样问题的人)。
系统
Ubuntu 20.04
方法
我已经在 Wireshark 中识别了我的键盘设备的 USB 端口,并记录了该端口上的数据流。该数据被保存到一个名为 abcd.pcapng
的文件中(我在录制过程中按下了按钮 abcd
)。接下来,我编写了一个基本的 python 脚本,该脚本使用 tshark
将 abcd.pcapng
文件转换为其原始按键 abcd
.
代码
这是将 abcd.pcapng
文件转换为字母 abcd
:
# This script extracts the keypresses from a pcapng file.
import os
pcapng_filename = "abcd.pcapng"
keypress_ids_filename = "keypress_ids.txt"
# create the output for
command_pcapng_to_keypress_ids = (
f"tshark -r '{pcapng_filename}' -T fields -e usb.capdata > {keypress_ids_filename}"
)
print(
f"Running the following bash command to convert the pcapng file to 00xx00000 nrs:\n{command_pcapng_to_keypress_ids}"
)
os.system(command_pcapng_to_keypress_ids)
# read keypress id file
switcher = {
"04": "a", # or A
"05": "b", # or B
"06": "c", # or C
"07": "d", # or D
"08": "e", # or E
"09": "f", # or F
"0A": "g", # or G
"0B": "h", # or H
"0C": "i", # or I
"0D": "j", # or J
"0E": "k", # or K
"0F": "l", # or L
"10": "m", # or M
"11": "n", # or N
"12": "o", # or O
"13": "p", # or P
"14": "q", # or Q
"15": "r", # or R
"16": "s", # or S
"17": "t", # or T
"18": "u", # or U
"19": "v", # or V
"1A": "w", # or W
"1B": "x", # or X
"1C": "y", # or Y
"1D": "x", # or Z
"1E": "1", # or !
"1F": "2", # or @
"20": "3", # or #
"21": "4", # or $
"22": "5", # or %
"23": "6", # or ^
"24": "7", # or &
"25": "8", # or *
"26": "9", # or (
"27": "0", # or )
"2D": "-", # or _
"2E": "+", # or =
"2F": "[", # or {
"30": "]", # or }
"31": '"', # or |
"33": ";", # or :
"34": "'", # or "
"35": "`", # or ~
"36": ",", # or <
"37": ".", # or >
"38": "/", # or ?
}
def readFile(filename):
fileOpen = open(filename)
return fileOpen
file = readFile(keypress_ids_filename)
print(f"file={file}")
# parse the 0000050000000000 etc codes and convert them into keystrokes
for line in file:
if len(line) == 17:
two_chars = line[4:6]
try:
print(
f"line={line[0:16]}, relevant characters indicating keypress ID: {two_chars} convert keypres ID to letter: {switcher[two_chars]}"
)
except:
pass
输出
指定文件的脚本输出是:
Running the following bash command to convert the pcapng file to 00xx00000 nrs:
tshark -r 'abcd.pcapng' -T fields -e usb.capdata > keypress_ids.txt
file=<_io.TextIOWrapper name='keypress_ids.txt' mode='r' encoding='UTF-8'>
line=0000040000000000, relevant characters indicating keypress ID: 04 convert keypres ID to letter: a
line=0000050000000000, relevant characters indicating keypress ID: 05 convert keypres ID to letter: b
line=0000060000000000, relevant characters indicating keypress ID: 06 convert keypres ID to letter: c
line=0000070000000000, relevant characters indicating keypress ID: 07 convert keypres ID to letter: d
问题
我如何调整代码以直接获取 USB 数据作为连续流,而不是首先必须开始和停止记录 USB 数据,然后必须创建输出 abcd.pcapng
文件?
例如,是否有 Wireshark-api 或 tshark 函数开始侦听直到 the/some 脚本停止?
解决方案
以下名为 live_capture_keystrokes.py
的脚本捕获包含击键信号的 Leftover Capture Data
,它们由 Python 代码实时且连续地解析。
我认为每次重新启动计算机时激活 usb 监控很重要(如果您想 运行 此脚本成功)。为此,您可以 运行:
sudo modprobe usbmon
理想情况下,你会 运行 如果没有 sudo,那也将阻止 运行 使用 sudo 的 python 文件,但我还没有弄清楚如何 运行 modprobe usbmon
没有 sudo。
代码
此 live_capture_keystrokes.py
脚本需要 运行 with sudo 如果 modprobe usbmon
是 运行 with sudo。要 运行 sudo 中的 python 脚本,可以键入:
sudo su
# sudo apt install python3
# pip install pyshark
# python3 live_capture_keystrokes.py
而live_capture_keystrokes.py
的内容是:
import pyshark
# Get keystrokes data
print("\n----- Capturing keystrokes from usbmon0 --------------------")
capture = pyshark.LiveCapture(interface='usbmon0', output_file='output.pcap')
# Source: https://www.programcreek.com/python/example/92561/pyshark.LiveCapture
for i, packet in enumerate(capture.sniff_continuously()):
try:
data= packet[1].usb_capdata.split(":")
print(data)
except:
pass
capture.clear()
capture.close()
print(f'DONE')
输出
输出尚未解析回击键,稍后我会添加。然而,这就是输出,每次您按下 USB 键盘上的一个键,它都会将随附的列表直接打印到屏幕上。
a['00', '00', '04', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
b['00', '00', '05', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
c['00', '00', '06', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
d['00', '00', '07', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
e['00', '00', '08', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
f['00', '00', '09', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
g['00', '00', '0a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
h['00', '00', '0b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
i['00', '00', '0c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
j['00', '00', '0d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
k['00', '00', '0e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
l['00', '00', '0f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
m['00', '00', '10', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
n['00', '00', '11', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
o['00', '00', '12', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
p['00', '00', '13', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
q['00', '00', '14', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
r['00', '00', '15', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
s['00', '00', '16', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
t['00', '00', '17', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
u['00', '00', '18', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
v['00', '00', '19', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
w['00', '00', '1a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
x['00', '00', '1b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
y['00', '00', '1c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
z['00', '00', '1d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
0['00', '00', '62', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
1['00', '00', '59', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
2['00', '00', '5a', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
3['00', '00', '5b', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
4['00', '00', '5c', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
5['00', '00', '5d', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
6['00', '00', '5e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
7['00', '00', '5f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
8['00', '00', '60', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
9['00', '00', '61', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
1['00', '00', '1e', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
2['00', '00', '1f', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
3['00', '00', '20', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
4['00', '00', '21', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
5['00', '00', '22', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
6['00', '00', '23', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
7['00', '00', '24', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
8['00', '00', '25', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
9['00', '00', '26', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']
0['00', '00', '27', '00', '00', '00', '00', '00']
['00', '00', '00', '00', '00', '00', '00', '00']