15 Commits

Author SHA1 Message Date
SoulKindred
0bc3704846 Update dev_journal.md
updated journal and dodged copyright infringement
2023-06-08 00:14:31 +02:00
Sebastian Lenzlinger
94cb159a49 Cleanup unused code.
Remove unused code from repo.
2023-06-07 21:00:09 +02:00
Sebastian Lenzlinger
2150441d48 Add Makefile entry that also gets rid of __pycache__ 2023-06-07 20:57:17 +02:00
SoulKindred
1d5fc7375c Update dev_journal.md
added diary entry to stap-scripts
2023-06-07 20:40:13 +02:00
Sebastian Lenzlinger
63b92c967a Logic ajust 2023-06-07 20:33:15 +02:00
Sebastian Lenzlinger
7c9a6101a0 Condition logic ajustments 2023-06-07 20:27:06 +02:00
Sebastian Lenzlinger
6f56f0bd30 For VM, sorry 2023-06-07 20:24:33 +02:00
Sebastian Lenzlinger
0cdb0cd846 To get it in to VM. As are most commits. 2023-06-07 20:21:10 +02:00
Sebastian Lenzlinger
2b2546b70e Beauty fix 2023-06-07 20:19:12 +02:00
Sebastian Lenzlinger
2c9ba696c8 DEBUG 2023-06-07 20:15:31 +02:00
Sebastian Lenzlinger
9b3151452d DEBUG 2023-06-07 20:12:43 +02:00
Sebastian Lenzlinger
538c6368c5 FIX 2023-06-07 20:06:33 +02:00
Sebastian Lenzlinger
316ff1c90e Add new auto blacklist featue 2023-06-07 20:04:19 +02:00
Sebastian Lenzlinger
a4c5d94006 Update dev_journal.md
Fix ''' to ```
2023-06-07 19:45:43 +02:00
Sebastian Lenzlinger
d434029e56 Merge pull request #1 from sebaschi/userland
The userland programm core functionality is completed. 
keylogger-detector.py detects all processes reading from a keyboard file in /dev/input/eventX.
The keylogger asks the user if they would like to kill any process, and does so.
Many PIDs with the same programm are handled.
There is a whitelist and autokill list configurable(only partially from withing the running program) aswell as what names keyboards might have, like 'kbd'.
2023-06-07 19:44:33 +02:00
12 changed files with 31 additions and 727 deletions

View File

@@ -131,7 +131,7 @@ Killing a process still doesn't work:
## Wednesday, 7. June 2023, night ## Wednesday, 7. June 2023, night
### Sebastian ### Sebastian
This is the latest output aftert a test run where actually 3 processes has keyloggers runnig. This is the latest output aftert a test run where actually 3 processes has keyloggers runnig.
''' ```
[kldetect@fedora src]$ sudo ./keylogger_detector.py [kldetect@fedora src]$ sudo ./keylogger_detector.py
[sudo] password for kldetect: [sudo] password for kldetect:
/usr/sbin/fuser /usr/sbin/fuser
@@ -159,7 +159,7 @@ cat: config.: No such file or directory
[Verbose] Suspicious processes not killed: [] [Verbose] Suspicious processes not killed: []
[Verbose] Suspicious processes killed: [] [Verbose] Suspicious processes killed: []
[+] No suspicious processes found [+] No suspicious processes found
''' ```
This is after extensivly refactoring because I was starting to loose oversight over the code. So I split it up into utils, config and keylogger_detector. This is after extensivly refactoring because I was starting to loose oversight over the code. So I split it up into utils, config and keylogger_detector.
#### TODO: #### TODO:
1. Ivestigate and bug fix 1. Ivestigate and bug fix
@@ -173,3 +173,8 @@ All in all, the main functionality works as intended. Basically now would be the
#### TODO #### TODO
1. Write report 1. Write report
2. Add functionality to userspace detector 2. Add functionality to userspace detector
## Wednesday, 7, June 2023
### Michel
I have written 1 systemtap scripts, that can detect, whenever a module registers at the Keyboard-notifier. The Script can currently detect whenever a module registers. My script cant detect which kernel module registered. Here comes Sebastians idea of writing a python script, that can unload all un-known modules and loads them back in, whilst the stap-script is running. Whenever a module is loaded in, and it triggers the stap-script, we know it is tracking key-strokes. Those modules will be shown to the user and the user then has to decide whether to unload and remove them, or keep them. My script is based on a redhat-script. The redhat-script is called funcall_tracer2.stp . The idea behind both scripts is the same. My script is simplyfied for the use with python.

View File

@@ -1,2 +1,5 @@
clean: clean:
rm *.o *.txt *.out *.exe rm *.o *.txt *.out
sclean:
sudo rm -rf *.o *.txt *.out __pycache__

View File

@@ -13,12 +13,13 @@ from utils import (
kill_process kill_process
) )
# Global variables # Global variables/CLI options
auto_kill_option = False auto_kill_option = False
verbose_option = False verbose_option = False
safe_option = False safe_option = False
add_white_list_option = False add_white_list_option = False
add_black_list_option = False
debug_option = False debug_option = False
# Functions # Functions
@@ -33,7 +34,8 @@ def print_help():
print(' -v, --verbose\t\t\tVerbose mode. Informative information will be displayed duting execution') print(' -v, --verbose\t\t\tVerbose mode. Informative information will be displayed duting execution')
print(' -a, --auto-kill\t\tAutomatically kill blacklisted processes') print(' -a, --auto-kill\t\tAutomatically kill blacklisted processes')
print(' -s, --safe\t\t\tSafe mode. Asked to confirm before killing a process') print(' -s, --safe\t\t\tSafe mode. Asked to confirm before killing a process')
print(' -w, --add-white-list\t\t\tActivate prompt to add program names to the whitelist') #For some reason this line gets messed up in display print(' -w, --add-white-list\t\t\tActivate prompt to add program names to the whitelist') #For some reason this line gets messed up in display
print(' -b, --add-black-list\t\t\tAutomatically add program names chosen to kill to the blacklist')
print(' -d, --debug\t\t\tDebug mode. Print debug statements') print(' -d, --debug\t\t\tDebug mode. Print debug statements')
def set_input_options(): def set_input_options():
@@ -47,7 +49,7 @@ def set_input_options():
""" """
global auto_kill_option, verbose_option, safe_option, add_white_list_option global auto_kill_option, verbose_option, safe_option, add_white_list_option
global debug_option global debug_option, add_black_list_option
if len(sys.argv) > 1: if len(sys.argv) > 1:
for arg in sys.argv[1:]: for arg in sys.argv[1:]:
print(arg) print(arg)
@@ -62,6 +64,8 @@ def set_input_options():
safe_option = True safe_option = True
elif arg == '-w' or arg == '--add-white-list' : elif arg == '-w' or arg == '--add-white-list' :
add_white_list_option = True add_white_list_option = True
elif arg == '-b' or arg == '--add-black-list':
add_black_list_option = True
elif arg == '-d' or arg == '--debug': elif arg == '-d' or arg == '--debug':
debug_option = True debug_option = True
@@ -175,16 +179,18 @@ def detect_keyloggers():
print('[Verbose] Auto-killable process found:', name) print('[Verbose] Auto-killable process found:', name)
if safe_option: if safe_option:
if confirm_kill_procces(name): if confirm_kill_procces(name):
kill_process(name_pid_dict[name]) kill_processes(name_pid_dict[name])
else: else:
kill_process(name_pid_dict[name]) kill_processes(name_pid_dict[name])
if verbose_option:
print('[Verbose] Process auto-killed:', name)
############################ ############################
# 6. Identify suspicious processes, i.e. those not whitelisted # 6. Identify suspicious processes, i.e. those not whitelisted
############################ ############################
suspicious_processes = [] suspicious_processes = []
for name in process_names: for name in process_names:
if name not in white_listed_programs: if (name not in white_listed_programs and name not in auto_kill_programs) or (name in auto_kill_programs and not auto_kill_option):
suspicious_processes.append(name) suspicious_processes.append(name)
if verbose_option: if verbose_option:
print('[Verbose] Suspicious processes found:', suspicious_processes) print('[Verbose] Suspicious processes found:', suspicious_processes)
@@ -241,7 +247,7 @@ def detect_keyloggers():
############################ ############################
# 8. Update whitelist if option set # 8. Update whitelist and/or blacklist if options set
############################ ############################
debug(debug_option, 'Whitelist option:' + str(add_white_list_option)) debug(debug_option, 'Whitelist option:' + str(add_white_list_option))
if add_white_list_option: if add_white_list_option:
@@ -254,12 +260,17 @@ def detect_keyloggers():
if verbose_option: if verbose_option:
print('[Verbose] Newly whitelisted programs: ', to_whitelist) print('[Verbose] Newly whitelisted programs: ', to_whitelist)
to_kill = list(set(to_kill))
if add_black_list_option:
auto_kill_programs.extend(to_kill)
if verbose_option:
print('[Verbose] Newly blacklisted programs: ', to_kill)
########################### ###########################
# 9. Cleanup # 9. Cleanup
########################### ###########################
to_kill = list(set(to_kill))
auto_kill_programs = list(set(auto_kill_programs)) auto_kill_programs = list(set(auto_kill_programs))
auto_kill_programs.extend(to_kill)
config['auto_kill_programs'] = auto_kill_programs config['auto_kill_programs'] = auto_kill_programs
white_listed_programs = list(set(white_listed_programs)) white_listed_programs = list(set(white_listed_programs))
config['white_listed_programs'] = white_listed_programs config['white_listed_programs'] = white_listed_programs

View File

@@ -1,67 +0,0 @@
#!/bin/bash
# ===============================
# Step1: Find keyboard file paths
# ===============================
# Output file path
kbd_output_file="kbd_file_paths.txt"
# Function to follow symbolic links recursively
follow_symlinks() {
local filepath=$1
if [[ -L $filepath ]]; then
local resolved_path=$(readlink -f "$filepath")
echo "$resolved_path" >> "$kbd_output_file"
follow_symlinks "$resolved_path"
fi
}
# Traverse files in /dev/input/by-path
echo -n > "$kbd_output_file"
find /dev/input/by-path -type l -name '*kbd*' -print0 | while IFS= read -r -d '' filepath; do
#echo "$filepath" >> "$kbd_output_file"
follow_symlinks "$filepath"
done
echo "Keyboard file paths written to $kbd_output_file"
# ===============================
# Step2: Find pids using keyboard event files
# ===============================
# Use found kbd file paths to find corresponding pids
pids_input_file="$kbd_output_file"
pids_output_file="pids.txt"
echo -n > "$pids_output_file"
declare -a pids_array
# Get pids of processes using the keyboard and put in array
while IFS= read -r pathname; do
pids=$(fuser "$pathname")
# add pids to array
for pid in $pids; do
pids_array+=("$pid")
done
done < "$pids_input_file"
# sort and remove duplicates
sorted_pids=$(printf '%s\n' "${pids_array[@]}" | sort -nu)
# write unique and sorted pids to file, separated by newlines
printf '%s\n' "${sorted_pids[@]}" > "$pids_output_file"
echo "Pids written to $pids_output_file"
# ===============================
# Step3: Find processes/program names using pids
# ===============================
exe_input_file="$pids_output_file"
exe_output_file="suspicous_exes.txt"
# Clear output file
echo -n > "$exe_output_file"

View File

@@ -1,24 +0,0 @@
import os
# Output file path
kbd_output_file = "kbd_file_paths.txt"
# Function to follow symbolic links recursively
def follow_symlinks(filepath):
if os.path.islink(filepath):
resolved_path = os.path.realpath(filepath)
with open(kbd_output_file, "a") as f:
f.write(resolved_path + "\n")
follow_symlinks(resolved_path)
# Traverse files in /dev/input/by-path
with open(kbd_output_file, "w") as f:
f.write("")
for root, dirs, files in os.walk("/dev/input/by-path"):
for filename in files:
if "kbd" in filename:
filepath = os.path.join(root, filename)
follow_symlinks(filepath)
print("Keyboard file paths written to", kbd_output_file)

View File

@@ -1,40 +0,0 @@
#!/bin/bash
# Output file path
output_file="keyboard_info.txt"
# Step 1: Find keyboard device files
keyboard_files=()
while IFS= read -r -d '' file; do
if [[ $file == *"kbd"* || $file == *"keyboard"* ]]; then
keyboard_files+=("$file")
fi
done < <(find /dev/input/by-path -type l -name 'event*')
# Step 2: Check processes with open keyboard files
echo "Keyboard Information" > "$output_file"
echo "=====================" >> "$output_file"
for keyboard_file in "${keyboard_files[@]}"; do
echo "Keyboard device file: $keyboard_file" >> "$output_file"
event_file=$(readlink -f "$keyboard_file")
echo "Event file: $event_file" >> "$output_file"
pids=$(fuser -v "$event_file" 2>/dev/null | awk -F'[: ]+' 'NR>1{print $2}')
echo "PIDs with file open: $pids" >> "$output_file"
# Step 3: Check corresponding programs
echo "Corresponding Programs" >> "$output_file"
echo "---------------------" >> "$output_file"
for pid in $pids; do
program=$(readlink -f "/proc/$pid/exe")
echo "PID $pid corresponds to program: $program" >> "$output_file"
done
echo >> "$output_file"
done
echo "Keyboard information written to $output_file"

View File

@@ -1,251 +0,0 @@
#!/usr/bin/env python3
import os # for going directories
import subprocess # for running commands, in particular fuser
import sys # for exiting
import signal # for killing processes
import json # for handling our configurations
CONFIG_FILE = 'config.json'
auto_kill_option = False
verbose_option = False
safe_option = False
# Check if the user is in sudo mode
def check_sudo():
if os.geteuid() != 0:
print("[-] Please rerun as root")
sys.exit(1)
# Check if the user has the required packages installed
def check_packages():
packages = ['fuser']
missing_packages = []
for package in packages:
try:
subprocess.check_call(['which', package])
except subprocess.CalledProcessError:
missing_packages.append(package)
if len(missing_packages) > 0:
print("[-] Please install the following packages:", str(missing_packages))
sys.exit(1)
# Follow symlinks to find real path
def get_real_path(path):
if os.path.islink(path):
return os.path.realpath(path)
else:
return path
# get keyboard device files
def get_keyboard_device_files(kbd_names):
keyboard_device_files = []
for root, dirs, files in os.walk('/dev/input/by-path'):
for file in files:
if any(kbd_name in file for kbd_name in kbd_names):
keyboard_device_files.append(get_real_path(os.path.join(root, file)))
return keyboard_device_files
# print a list to a file separated by newlines
def print_list_to_file(list, file):
with open(file, 'w') as f:
for item in list:
f.write("%s\n" % item)
# find pids using file using fuser
def get_pids(file):
try:
pids = subprocess.check_output(['fuser', file]).decode('utf-8').split()
except subprocess.CalledProcessError:
if verbose_option:
print("[-] Error: fuser failed to run on", file)
return []
#pids = [int(pid) for pid in pids]
return pids
# clear a file
def clear_file(file):
open(file, 'w').close()
# find programm name using pid
def get_program_name(pid):
status_file = '/proc/' + str(pid) + '/status'
with open(status_file, 'r') as f:
# See cat /proc/[pid]/status | grep Name
for line in f:
if line.startswith('Name:'):
program_name = line.split(":")[1].strip()
return program_name
# proces input arguments and set options
def set_input_arguments():
global auto_kill_option
global verbose_option
global safe_option
if len(sys.argv) > 1:
if '-a' in sys.argv:
auto_kill_option = True
if '-v' in sys.argv:
verbose_option = True
if '-s' in sys.argv:
safe_option = True
# ask user to confirm a list of programs to kill
def confirm_kill_programs(programs, times=0):
print("Confirm to kill the following programs:")
for program in programs:
print(program)
print("y/n?")
answer = input()
if answer == 'y':
return True
elif answer == 'n':
return False
else:
if times > 5:
print("[-] Too many tries. Exiting")
sys.exit(1)
print("[-] Please answer y or n")
return confirm_kill_programs(programs, times+1)
# kill list of processes
def kill_processes(pids):
print(pids) ## DEBUG
print("Killing processes with pids:", pids)
for pid in pids:
os.kill(pid, signal.SIGKILL)
if verbose_option:
print("[-] Killed process with pid", pid)
# the main program starts here
def detect_keyloggers():
###############################
# Step 0: Check minimal requirements/ Set up
###############################
check_sudo()
check_packages()
config = load_config()
# initialize white_listed_programs
if 'white_listed_programs' in config:
white_listed_programs = config['white_listed_programs']
else:
config['white_listed_programs'] = []
white_listed_programs = []
# initialize auto_kill_programs
if 'auto_kill_programs' in config:
auto_kill_programs = config['auto_kill_programs']
else:
config['auto_kill_programs'] = []
auto_kill_programs = []
# initialize kbd_names
if 'kbd_names' in config:
kbd_names = config['kbd_names']
else:
config['kbd_names'] = []
kbd_names = []
# Set options
set_input_arguments()
###############################
# Step 1: Get keyboard device files
###############################
keyboard_device_files = get_keyboard_device_files(kbd_names)
###############################
# Step 2: Get pids using keyboard device files
###############################
pids = []
for file in keyboard_device_files:
pids += get_pids(file)
pids = sorted(list(set(pids)))
###############################
# Step 3: Get program names using pids
###############################
program_names = []
program_pid_dict = {}
# Get program names
for pid in pids:
program_name = get_program_name(pid)
program_pid_dict[program_name] = program_pid_dict[program_name].append(int(pid))
if auto_kill_option and program_name in auto_kill_programs:
os.kill(pid, signal.SIGKILL)
if verbose_option:
print("[-] Auto-Killed process", program_name, "with pid", pid)
else:
program_names.append(program_name)
program_names = sorted(list(set(program_names)))
# Identify suspicious programs
suspicious_programs = []
for program_name in program_names:
if program_name not in white_listed_programs:
suspicious_programs.append(program_name)
if verbose_option:
###############################=
# Intermezzo: Print results
###############################
print("Keyboard device files:")
for file in keyboard_device_files:
print(file)
print("")
print("Pids:")
for pid in pids:
print(pid)
print("")
print("Program names:")
for program_name in program_names:
print(program_name)
print("")
if len(suspicious_programs) == 0:
print("[+] No suspicious programs found")
sys.exit(0)
###############################
# Step 4: Ask user to kill any suspicious programs
###############################
print("Suspicious programs:")
for program_name in suspicious_programs:
print(program_name)
user_input = input("Please enter those programs you want to kill. Use the whitespace(spacebar) to separate values.")
if user_input == '':
print("[-] No programs to kill")
sys.exit(0)
programs_to_kill = user_input.split()
programs_to_kill = [program_name for program_name in programs_to_kill if program_name in suspicious_programs] # Filter out programs that are not suspicious
pids_to_kill = []
for program_name in programs_to_kill:
pids_to_kill.append(program_pid_dict[program_name])
auto_kill_programs.append(program_name)
if safe_option:
if confirm_kill_programs(programs_to_kill):
kill_processes(pids_to_kill)
else:
kill_processes(pids_to_kill)
###############################
# Step 5: Save config
###############################
config['auto_kill_programs'] = list(set(auto_kill_programs))
config['white_listed_programs'] = list(set(white_listed_programs))
config['kbd_names'] = list(set(kbd_names))
save_config(config)
if __name__ == "__main__":
detect_keyloggers()

View File

@@ -1,77 +0,0 @@
import os
import subprocess
# ===============================
# Step1: Find keyboard file paths
# ===============================
# Output file path
kbd_output_file = "kbd_file_paths.txt"
# Function to follow symbolic links recursively
def follow_symlinks(filepath):
if os.path.islink(filepath):
resolved_path = os.path.realpath(filepath)
with open(kbd_output_file, "a") as output_file:
output_file.write(resolved_path + "\n")
follow_symlinks(resolved_path)
# Traverse files in /dev/input/by-path
with open(kbd_output_file, "w") as output_file:
for root, dirs, files in os.walk("/dev/input/by-path"):
for file in files:
if "kbd" in file:
filepath = os.path.join(root, file)
output_file.write(filepath + "\n")
follow_symlinks(filepath)
print("Keyboard file paths written to", kbd_output_file)
# ===============================
# Step2: Find pids using keyboard event files
# ===============================
# Use found kbd file paths to find corresponding pids
pids_input_file = kbd_output_file
pids_output_file = "pids.txt"
pids_array = []
# Get pids of processes using the keyboard and put in array
with open(pids_input_file, "r") as input_file:
for pathname in input_file:
pathname = pathname.strip()
pids = subprocess.check_output(["fuser", pathname]).decode().split()
pids_array.extend(pids)
# Sort and remove duplicates
sorted_pids = sorted(set(pids_array))
print()
print("The following pids where found:" + str(sorted_pids) + "\n")
# Write unique and sorted pids to file, separated by newlines
with open(pids_output_file, "w") as output_file:
output_file.write("\n".join(sorted_pids) + "\n")
print("Pids written to", pids_output_file)
# ===============================
# Step3: Find processes/program names using pids
# ===============================
exe_input_file = pids_output_file
exe_output_file = "suspicious_exes.txt"
# Clear output file
with open(exe_output_file, "w") as output_file:
output_file.write("")
exe_pid_dict = {}
for pid in sorted_pids:
#Get name of executable from PID using process status file
status_file_path = "/proc/" + pid + "/status"
with open(status_file_path, "r") as status_file:
for line in status_file:
# See cat /proc/{pid}/status | grep "Name:"
if line.startswith("Name:"):
exe_name = line.split(":")[1].strip()
exe_pid_dict[exe_name] = pid
print("The following executables where found:" + str(exe_pid_dict) + "\n")

View File

@@ -1,112 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#define DEVICE_DIR "/dev/input"
#define BY_PATH_DIR "/dev/input/by-path"
#define PROC_DIR "/proc"
void get_program_name(long pid) {
char exe_file_path[256];
snprintf(exe_file_path, sizeof(exe_file_path), "/proc/%ld/exe", pid);
if (access(exe_file_path, F_OK) == 0) {
char program_path[256];
ssize_t path_len = readlink(exe_file_path, program_path, sizeof(program_path) - 1);
if (path_len != -1) {
program_path[path_len] = '\0';
printf("Corresponding program: %s\n\n", program_path);
}
}
}
void find_keyboard_files() {
DIR *by_path_dir = opendir(BY_PATH_DIR);
if (by_path_dir == NULL) {
perror("opendir");
exit(EXIT_FAILURE);
}
struct dirent *entry;
while ((entry = readdir(by_path_dir)) != NULL) {
if (strstr(entry->d_name, "kbd") != NULL || strstr(entry->d_name, "keyboard") != NULL) {
char device_file_path[256];
snprintf(device_file_path, sizeof(device_file_path), "%s/%s", BY_PATH_DIR, entry->d_name);
char link_dest[256];
ssize_t link_size = readlink(device_file_path, link_dest, sizeof(link_dest) - 1);
if (link_size == -1) {
perror("readlink");
continue;
}
link_dest[link_size] = '\0';
printf("Keyboard device file: %s\n", link_dest);
char event_file[256];
snprintf(event_file, sizeof(event_file), "%s/%s", DEVICE_DIR, link_dest);
DIR *proc_dir = opendir(PROC_DIR);
if (proc_dir == NULL) {
perror("opendir");
continue;
}
struct dirent *pid_entry;
while ((pid_entry = readdir(proc_dir)) != NULL) {
if (pid_entry->d_type != DT_DIR)
continue;
// Check if the entry name is a numeric value (PID)
char *endptr;
long pid = strtol(pid_entry->d_name, &endptr, 10);
if (*endptr != '\0')
continue;
char fd_dir_path[256];
snprintf(fd_dir_path, sizeof(fd_dir_path), "%s/%s/fd", PROC_DIR, pid_entry->d_name);
DIR *fd_dir = opendir(fd_dir_path);
if (fd_dir == NULL)
continue;
struct dirent *fd_entry;
while ((fd_entry = readdir(fd_dir)) != NULL) {
if (fd_entry->d_type != DT_LNK)
continue;
char fd_file_path[256];
snprintf(fd_file_path, sizeof(fd_file_path), "%s/%s", fd_dir_path, fd_entry->d_name);
char link_dest[256];
ssize_t link_size = readlink(fd_file_path, link_dest, sizeof(link_dest) - 1);
if (link_size == -1)
continue;
link_dest[link_size] = '\0';
if (strcmp(link_dest, event_file) == 0) {
printf("Process with PID %ld is using this file.\n", pid);
get_program_name(pid);
}
}
closedir(fd_dir);
}
closedir(proc_dir);
}
}
closedir(by_path_dir);
}
int main() {
printf("Finding keyboard files...\n\n");
find_keyboard_files();
return 0;
}

View File

@@ -1,77 +0,0 @@
import os
import subprocess
# ===============================
# Step1: Find keyboard file paths
# ===============================
# Output file path
kbd_output_file = "kbd_file_paths.txt"
# Function to follow symbolic links recursively
def follow_symlinks(filepath):
if os.path.islink(filepath):
resolved_path = os.path.realpath(filepath)
with open(kbd_output_file, "a") as output_file:
output_file.write(resolved_path + "\n")
follow_symlinks(resolved_path)
# Traverse files in /dev/input/by-path
with open(kbd_output_file, "w") as output_file:
for root, dirs, files in os.walk("/dev/input/by-path"):
for file in files:
if "kbd" in file:
filepath = os.path.join(root, file)
output_file.write(filepath + "\n")
follow_symlinks(filepath)
print("Keyboard file paths written to", kbd_output_file)
# ===============================
# Step2: Find pids using keyboard event files
# ===============================
# Use found kbd file paths to find corresponding pids
pids_input_file = kbd_output_file
pids_output_file = "pids.txt"
pids_array = []
# Get pids of processes using the keyboard and put in array
with open(pids_input_file, "r") as input_file:
for pathname in input_file:
pathname = pathname.strip()
pids = subprocess.check_output(["fuser", pathname]).decode().split()
pids_array.extend(pids)
# Sort and remove duplicates
sorted_pids = sorted(set(pids_array))
print()
print("The following pids where found:" + str(sorted_pids) + "\n")
# Write unique and sorted pids to file, separated by newlines
with open(pids_output_file, "w") as output_file:
output_file.write("\n".join(sorted_pids) + "\n")
print("Pids written to", pids_output_file)
# ===============================
# Step3: Find processes/program names using pids
# ===============================
exe_input_file = pids_output_file
exe_output_file = "suspicious_exes.txt"
# Clear output file
with open(exe_output_file, "w") as output_file:
output_file.write("")
exe_pid_dict = {}
for pid in sorted_pids:
#Get name of executable from PID using process status file
status_file_path = "/proc/" + pid + "/status"
with open(status_file_path, "r") as status_file:
for line in status_file:
# See cat /proc/{pid}/status | grep "Name:"
if line.startswith("Name:"):
exe_name = line.split(":")[1].strip()
exe_pid_dict[exe_name] = pid
print("The following executables where found:" + str(exe_pid_dict) + "\n")

View File

@@ -1,67 +0,0 @@
#!/bin/bash
# ===============================
# Step1: Find keyboard file paths
# ===============================
# Output file path
kbd_output_file="kbd_file_paths.txt"
# Function to follow symbolic links recursively
follow_symlinks() {
local filepath=$1
if [[ -L $filepath ]]; then
local resolved_path=$(readlink -f "$filepath")
echo "$resolved_path" >> "$kbd_output_file"
follow_symlinks "$resolved_path"
fi
}
# Traverse files in /dev/input/by-path
echo -n > "$kbd_output_file"
find /dev/input/by-path -type l -name '*kbd*' -print0 | while IFS= read -r -d '' filepath; do
#echo "$filepath" >> "$kbd_output_file"
follow_symlinks "$filepath"
done
echo "Keyboard file paths written to $kbd_output_file"
# ===============================
# Step2: Find pids using keyboard event files
# ===============================
# Use found kbd file paths to find corresponding pids
pids_input_file="$kbd_output_file"
pids_output_file="pids.txt"
echo -n > "$pids_output_file"
declare -a pids_array
# Get pids of processes using the keyboard and put in array
while IFS= read -r pathname; do
pids=$(fuser "$pathname")
# add pids to array
for pid in $pids; do
pids_array+=("$pid")
done
done < "$pids_input_file"
# sort and remove duplicates
sorted_pids=$(printf '%s\n' "${pids_array[@]}" | sort -nu)
# write unique and sorted pids to file, separated by newlines
printf '%s\n' "${sorted_pids[@]}" > "$pids_output_file"
echo "Pids written to $pids_output_file"
# ===============================
# Step3: Find processes/program names using pids
# ===============================
exe_input_file="$pids_output_file"
exe_output_file="suspicous_exes.txt"
# Clear output file
echo -n > "$exe_output_file"