upload main files

This commit is contained in:
FW_Mumuzi 2023-06-30 13:27:22 +08:00 committed by GitHub
commit aa13f92e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 547 additions and 0 deletions

106
KeyboardDecrypt.py Normal file
View File

@ -0,0 +1,106 @@
from PySide6.QtWidgets import QComboBox,QStackedWidget,QApplication, QMainWindow, QPushButton, QTextEdit, QFileDialog, QVBoxLayout, QWidget, QLabel, QLineEdit, QHBoxLayout, QRadioButton, QButtonGroup, QTabWidget, QMenuBar, QToolBar
from PySide6.QtGui import QAction
from PySide6.QtCore import Qt, Signal
import sys,os
import datetime
from UsbKeyboardExtract import extract_data,process_data
class KeyboardDecryptWindow(QWidget):
file_name = Signal(str) # 文件名信号
file_dropped = Signal(str)
def __init__(self,parent=None):
super(KeyboardDecryptWindow, self).__init__(parent)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
# 选择执行的类型
self.type_layout = QHBoxLayout()
self.type_label = QLabel("选择执行类型:")
self.type_layout.addWidget(self.type_label)
self.button_group = QButtonGroup(self)
self.select_type1 = QRadioButton("capdata")
self.select_type2 = QRadioButton("usbhid")
self.button_group.addButton(self.select_type1)
self.button_group.addButton(self.select_type2)
self.type_layout.addWidget(self.select_type1)
self.type_layout.addWidget(self.select_type2)
# 确定按钮
self.run_button = QPushButton("点击执行")
stylesheet = load_stylesheet("./css/style.css")
self.run_button.setStyleSheet(stylesheet)
self.run_button.clicked.connect(self.run_command)
self.type_layout.addWidget(self.run_button)
self.layout.addLayout(self.type_layout)
# 输出窗口
self.output = QTextEdit()
self.layout.addWidget(self.output)
self.output.setReadOnly(True)
self.setAcceptDrops(True)
# 文件名变量
self.file = ''
# 接收文件名信号
self.file_name.connect(self.set_file)
def set_file(self, file):
self.file = file
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
urls = event.mimeData().urls()
url = urls[0]
filePath = url.toLocalFile()
self.file_dropped.emit(filePath)
def run_command(self):
self.output.clear()
current_time = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
self.output.append(f"{current_time}")
checked_button = self.button_group.checkedButton()
if checked_button:
type = checked_button.text()
else:
type = None
if not self.file:
self.output.append("错误:没有选择文件。")
return
if not type:
self.output.append("错误:没有选择执行类型。")
return
self.output.append(f"执行的类型: {type}")
try:
result,result1 = extract_data(type, self.file)
result2,result_delete = process_data(result1)
except Exception as e:
self.output.append(f"执行出错:{e}")
else:
self.output.append("执行成功。结果如下:")
self.output.append(result)
self.output.append("处理后的结果如下:")
self.output.append(result2)
self.output.append("删除的字符如下:")
self.output.append(result_delete)
def load_stylesheet(filename):
with open(filename, "r") as f:
return f.read()

164
MouseDecrypt.py Normal file
View File

@ -0,0 +1,164 @@
from PySide6.QtWidgets import QSizePolicy,QComboBox,QStackedWidget,QApplication, QMainWindow, QPushButton, QTextEdit, QFileDialog, QVBoxLayout, QWidget, QLabel, QLineEdit, QHBoxLayout, QRadioButton, QButtonGroup, QTabWidget, QMenuBar, QToolBar
from PySide6.QtGui import QAction
from PySide6.QtCore import Qt, Signal
import sys,os,time,datetime
from MouseExtract import extract_data
import matplotlib.pyplot as plt
class MouseDecryptWindow(QWidget):
file_name = Signal(str) # 文件名信号
file_dropped = Signal(str)
def __init__(self):
super(MouseDecryptWindow, self).__init__()
self.layout = QVBoxLayout(self)
# 选择执行的类型
self.type_layout = QHBoxLayout()
self.type_label = QLabel("选择执行类型:")
self.type_layout.addWidget(self.type_label)
self.button_group_type = QButtonGroup(self)
self.select_type1 = QRadioButton("capdata")
self.select_type2 = QRadioButton("usbhid")
self.button_group_type.addButton(self.select_type1)
self.button_group_type.addButton(self.select_type2)
self.type_layout.addWidget(self.select_type1)
self.type_layout.addWidget(self.select_type2)
self.layout.addLayout(self.type_layout)
# 选择想要查看的鼠标按键
self.button_layout = QHBoxLayout()
self.button_label = QLabel("选择想要查看的鼠标按键:")
self.button_layout.addWidget(self.button_label)
self.button_group_button = QButtonGroup(self)
self.select_button1 = QRadioButton("左键")
self.select_button2 = QRadioButton("右键")
self.select_button3 = QRadioButton("无按键")
self.select_button4 = QRadioButton("所有")
self.button_group_button.addButton(self.select_button1)
self.button_group_button.addButton(self.select_button2)
self.button_group_button.addButton(self.select_button3)
self.button_group_button.addButton(self.select_button4)
self.button_layout.addWidget(self.select_button1)
self.button_layout.addWidget(self.select_button2)
self.button_layout.addWidget(self.select_button3)
self.button_layout.addWidget(self.select_button4)
self.layout.addLayout(self.button_layout)
# 执行按钮
self.button_layout = QHBoxLayout()
stylesheet = load_stylesheet("./css/style.css")
self.run_button = QPushButton("保存并打开图片")
self.run_button.clicked.connect(self.run_command)
self.run_button.setFixedSize(120, 40) # 设置固定大小
self.button_layout.addWidget(self.run_button)
self.run_button.setStyleSheet(stylesheet)
# 保存图片按钮
self.save_button = QPushButton("仅保存图片")
self.save_button.clicked.connect(self.save_image)
self.save_button.setFixedSize(120, 40) # 设置固定大小
self.button_layout.addWidget(self.save_button)
self.save_button.setStyleSheet(stylesheet)
self.layout.addLayout(self.button_layout)
# 输出窗口
self.output = QTextEdit()
self.layout.addWidget(self.output)
self.output.setReadOnly(True)
self.setLayout(self.layout)
# 文件名变量
self.file = ''
# 接收文件名信号
self.file_name.connect(self.set_file)
self.setAcceptDrops(True)
def set_file(self, file):
self.file = file
def dragEnterEvent(self, event):
# accept the drag only if it contains files
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
# get the file URLs (a list of QUrls)
urls = event.mimeData().urls()
# assuming only one file is dropped, get the first URL
url = urls[0]
# get the file path (a string)
filePath = url.toLocalFile()
# 发送文件名信号
self.file_dropped.emit(filePath)
def save_image(self):
self.run_command(from_save_button=True)
def run_command(self,from_save_button=False):
self.output.clear()
# 输出当前时间
current_time = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
self.output.append(f"{current_time}")
# 获取当前选中的执行类型和鼠标按键
checked_button_type = self.button_group_type.checkedButton()
checked_button_key = self.button_group_button.checkedButton()
# 检查是否选择了执行类型和鼠标按键以及文件
if checked_button_type:
type = checked_button_type.text()
else:
type = None
if checked_button_key:
key = checked_button_key.text()
else:
key = None
if not self.file:
self.output.append("错误:没有选择文件。")
return
if not type:
self.output.append("错误:没有选择执行类型。")
return
if not key:
self.output.append("错误:没有选择鼠标按键。")
return
self.output.append(f"执行的类型: {type}")
self.output.append(f"选择的鼠标按键: {key}")
self.output.append("正在执行,若文件较大可能会出现无响应情况,请稍后……")
QApplication.processEvents()
try:
result = extract_data(type, key, self.file)
except Exception as e:
self.output.append(f"执行出错:{e}")
else:
self.output.append("执行成功。")
self.output.append("已将转换后的坐标写入result.txt如有需要可自行利用")
self.output.append(f"已将图片保存至当前环境运行目录下的{key}.png")
time.sleep(0.5)
result.savefig(f"{key}.png")
if not from_save_button:
os.system(f"{key}.png")
def load_stylesheet(filename):
with open(filename, "r") as f:
return f.read()

74
MouseExtract.py Normal file
View File

@ -0,0 +1,74 @@
import sys
import os
import numpy as np
import matplotlib.pyplot as plt
def extract_data(types,choise,filename):
posX, posY = 0, 0
X, Y = [], []
type_dicts = {"capdata": "usb.capdata", "usbhid": "usbhid.data"}
mytype = type_dicts[types]
choise_dicts = {"左键": "L", "右键": "R","无按键" : "N" ,"所有" : "ALL"}
mychoise = choise_dicts[choise]
os.system(f'tshark.exe -r "{filename}" -T fields -e {mytype} > usb.dat')
data = []
result = open('result.txt', 'w')
with open('usb.dat', "r") as f:
for line in f:
data.append(line[0:-1])
for i in data:
Bytes = bytes.fromhex(i)
if(len(Bytes) == 8):
horizontal = 2
vertical = 4
key = 1
elif(len(Bytes) == 6):
horizontal = 2
vertical = 3
key = 1
elif(len(Bytes) == 4):
horizontal = 1
vertical = 2
key = 0
else:
continue
offsetX = Bytes[horizontal]
offsetY = Bytes[vertical]
if offsetX > 127:
offsetX -= 256
if offsetY > 127:
offsetY -= 256
posX += offsetX
posY += offsetY
if Bytes[key] == 1:
if mychoise == "L":
X.append(posX)
Y.append(-posY)
result.write(str(posX) + ' ' + str(-posY) + '\n')
elif Bytes[key] == 2:
if mychoise == "R":
X.append(posX)
Y.append(-posY)
result.write(str(posX) + ' ' + str(-posY) + '\n')
elif Bytes[key] == 0:
if mychoise == "N":
X.append(posX)
Y.append(-posY)
result.write(str(posX) + ' ' + str(-posY) + '\n')
else:
pass
if mychoise == "ALL":
X.append(posX)
Y.append(-posY)
result.write(str(posX) + ' ' + str(-posY) + '\n')
result.close()
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(X, Y, c='r', marker='o')
return plt

42
README.md Normal file
View File

@ -0,0 +1,42 @@
# UsbKeyboard&Mouse_Hacker_Gui
> 本工具作用为对CTF中常见的键盘流量与鼠标流量进行解密采用GUI的形式方便使用
## 使用帮助
使用python3执行run_GUI.py加载
```shell
python3 run_GUI.py
```
> Note:需安装PySide6、numpy、matplotlib库
> 若未换源可使用 `pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple执行`
![image-20230630130402882](README.assets/image-20230630130402882.png)
> 该工具并不能保证百分百能够提取出想要的内容,如果不符合常见规则可能提取结果为空。
### 键盘流量
加载文件后,选择执行类型后点击执行即可
若知道类型,可以直接选择,~~若不知道类型,反正就两种都试一下就行了~~
![keyborad](README.assets/keyborad.gif)
### 鼠标流量
与键盘一样,加载文件后,选择执行类型后点击执行即可。
建议先选择`所有`,确定是否有输出后,再按照鼠标按键进行分类查看。
![mouse](README.assets/mouse.gif)

74
UsbKeyboardExtract.py Normal file
View File

@ -0,0 +1,74 @@
import sys,os
normalKeys = {"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":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>","54":"/","55":"*","56":"-","57":"+","58":"<ENTER>","59":"1","5a":"2","5b":"3","5c":"4","5d":"5","5e":"6","5f":"7","60":"8","61":"9","62":"0","63":"."}
shiftKeys = {"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":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>","54":"/","55":"*","56":"-","57":"+","58":"<ENTER>","59":"1","5a":"2","5b":"3","5c":"4","5d":"5","5e":"6","5f":"7","60":"8","61":"9","62":"0","63":"."}
def extract_data(types,filename):
presses = []
type_dicts = {"capdata": "usb.capdata", "usbhid": "usbhid.data"}
mytype = type_dicts[types]
os.system(f'tshark.exe -r "{filename}" -T fields -e {mytype} > usb.dat')
with open("usb.dat", "r") as f:
for line in f:
presses.append(line[0:-1])
result = ""
result_data = []
for press in presses:
if press == '':
continue
if ':' in press:
Bytes = press.split(":")
else:
Bytes = [press[i:i+2] for i in range(0, len(press), 2)]
if Bytes[0] == "00":
if Bytes[2] != "00" and normalKeys.get(Bytes[2]):
result += normalKeys[Bytes[2]]
result_data.append(normalKeys[Bytes[2]])
elif int(Bytes[0],16) & 0b10 or int(Bytes[0],16) & 0b100000:
if Bytes[2] != "00" and normalKeys.get(Bytes[2]):
result += shiftKeys[Bytes[2]]
result_data.append(shiftKeys[Bytes[2]])
else:
pass
return result,result_data
#以下是对提取的键盘流量进行加工
def process_data(res):
datas = []
delete_data = []
temp_del = []
not_last_del = False
CAP = 0
for data in res:
if(data == '<CAP>'):
CAP ^= 1
elif(data == '<DEL>'):
try:
temp_del.append(datas.pop())
except:
pass
not_last_del = True
elif(data == '<SPACE>'):
if(not_last_del):
delete_data += temp_del[::-1]
temp_del = []
datas.append(' ')
not_last_del = False
else:
if(not_last_del):
delete_data += temp_del[::-1]
temp_del = []
if(CAP == 0 or not data.isalpha()):
datas.append(data)
else:
key = [k for k, v in normalKeys.items() if v == data][0]
corresponding_value_in_shiftKeys = shiftKeys.get(key)
datas.append(corresponding_value_in_shiftKeys)
not_last_del = False
datas = ''.join(datas)
delete_data = ''.join(delete_data)
return datas,delete_data

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
PySide6
numpy
matplotlib

84
run_GUI.py Normal file
View File

@ -0,0 +1,84 @@
from PySide6.QtWidgets import QStackedWidget,QApplication, QMainWindow, QFileDialog, QVBoxLayout, QWidget, QLabel, QLineEdit, QToolBar
from PySide6.QtGui import QAction,QIcon
import sys
from KeyboardDecrypt import KeyboardDecryptWindow
from MouseDecrypt import MouseDecryptWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("键盘流量&鼠标流量 GUI by mumuzi")
self.keyboardDecryptWindow = KeyboardDecryptWindow(self)
self.keyboardDecryptWindow.file_dropped.connect(self.set_file)
self.mouseDecryptWindow = MouseDecryptWindow()
self.mouseDecryptWindow.file_dropped.connect(self.set_file)
self.stackedWidget = QStackedWidget(self)
self.stackedWidget.addWidget(self.keyboardDecryptWindow)
self.stackedWidget.addWidget(self.mouseDecryptWindow)
self.typeToolBar = QToolBar(self)
self.keyboardAction = QAction('键盘流量解密', self)
self.mouseAction = QAction('鼠标流量解密', self)
self.keyboardAction.triggered.connect(lambda: self.switch_window(0))
self.mouseAction.triggered.connect(lambda: self.switch_window(1))
self.typeToolBar.addAction(self.keyboardAction)
self.typeToolBar.addAction(self.mouseAction)
self.addToolBar(self.typeToolBar)
# 文件选择功能
self.fileToolBar = QToolBar(self)
self.select_file_label = QLabel("选择或拖拽文件")
self.fileToolBar.addWidget(self.select_file_label)
self.file_name = QLineEdit()
self.file_name.setReadOnly(True)
self.fileToolBar.addWidget(self.file_name)
self.select_file_button = QAction("浏览文件", self)
self.select_file_button.triggered.connect(self.select_file)
self.fileToolBar.addAction(self.select_file_button)
self.addToolBar(self.fileToolBar)
layout = QVBoxLayout()
layout.addWidget(self.stackedWidget)
self.setWindowIcon(QIcon('./img/myico.ico'))
self.setStyleSheet("""
MainWindow {background-image: url(img/mybg.jpg)}
QPushButton {background-color: transparent}
QTextEdit {background-color: rgba(255, 255, 255, 200)}
QLineEdit {background-color: rgba(255, 255, 255, 200)}
""")
centralWidget = QWidget(self)
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
# 设置窗口大小
self.resize(600, 450)
def switch_window(self, index):
self.stackedWidget.setCurrentIndex(index)
def select_file(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "Wireshark pcapng (*.ntar *.ntar.* *.pcapng.gz *.pcapng.zst *.pcapng.lz4 *.pcapng);;tcpdump pcap (*.dmp.* *.dmp *.cap.* *.cap *.pcap.* *.pcap);;other (*.*)", options=options)
if fileName:
self.file_name.setText(fileName) # 更新file_name文本框的文本
self.keyboardDecryptWindow.set_file(fileName)
self.mouseDecryptWindow.set_file(fileName)
def set_file(self, file_name):
self.file_name.setText(file_name)
self.keyboardDecryptWindow.set_file(file_name)
self.mouseDecryptWindow.set_file(file_name)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

BIN
tshark.exe Normal file

Binary file not shown.