From efbc9bc88fd6b2446650b90f5004a9ac908b17e7 Mon Sep 17 00:00:00 2001 From: SoulKindred <91552157+SoulKindred@users.noreply.github.com> Date: Mon, 12 Jun 2023 17:55:12 +0200 Subject: [PATCH 1/2] Add files via upload Just took the essential code from my script and I put it into keylogger_detector.py No clue why it works now --- src/keylogger_detector.py | 136 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 4 deletions(-) diff --git a/src/keylogger_detector.py b/src/keylogger_detector.py index 591fa30..ec7fc2f 100755 --- a/src/keylogger_detector.py +++ b/src/keylogger_detector.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 - +import subprocess +import time +import os import sys from config import CONFIG_FILE, load_config, save_config from utils import ( @@ -13,7 +15,7 @@ from utils import ( kill_processes, kill_process ) -from kernel_detector import run_kernel_detector + # Global variables/CLI options @@ -107,6 +109,99 @@ def confirm_kill_procces(process_name, times=0): else: return confirm_kill_procces(process_name, times+1) + +########################## +def detect_logger(module): + + print("starting sniffing") + process = subprocess.Popen(['stap','funcall_trace.stp', '-T', '10'], stdout=subprocess.PIPE, text=True) + + + for i in range(2): + subprocess.Popen(['sudo','insmod', module]) + time.sleep(1) + print("-") + subprocess.Popen(['sudo','rmmod', module]) + time.sleep(1) + subprocess.Popen(['sudo','insmod', module]) + print("-") + out = process.communicate()[0] + + print("ended sniffing") + + print(out) + if out == "[-]": + return module + print("FAILED") + return 0 + +def getpath(sus_modules): + for i in range(len(sus_modules)): + sus_modules[i] = find_file(sus_modules[i] + ".ko") + return sus_modules + +def find_file(filename): + result = [] + for root, dirs, files in os.walk("/"): + if filename in files: + file_path = os.path.join(root, filename) + result.append(file_path) + result_out = result + result_out = ''.join(result_out) + return result_out + +def unload_mod(modules): + tmp = [] + for module in modules: + result = subprocess.run(['sudo','rmmod', module],capture_output = True, text = True) + if result.returncode == 0: + print(f"Unloaded module: {module}") + else: + print(f"Failed to unloaded module: {module}") + tmp.append(module) + print(result.stderr) + result_out = compare_mods(tmp, modules) + print(result_out) + return result_out + + +def tidy_up(entries): + cleaned_entries = [] + for entry in entries: + modules = entry.split() + if modules: + first_mod = modules[0] + cleaned_entries.append(first_mod) + return cleaned_entries + +def compare_mods(A, B): + setA = set(A) + setB = set(B) + + result = setB - setA + + return list(result) + + +def get_whitelist(file_path): + try: + with open(file_path, 'r') as file: + lines = file.read().splitlines() + return lines + except IOError: + print(f'Error: Failed to load whitelist{file_path}') + +def list_modules(command): + result = subprocess.run(command, shell = True, capture_output=True, text=True) + + if result.returncode == 0: + return result.stdout.strip().split('\n') + else: + print(f"Failed with error:{result.stderr}") + return[] + + + def detect_keyloggers(): """ Detect (userland) keylogger processes based on which processes have a keyboard file open (/dev/input/event*) @@ -290,11 +385,44 @@ def detect_keyloggers(): print('[Verbose] Config file saved') print('[+] Program completed. Exiting.') + + if kernel_detection_option: + whitelist = get_whitelist("whitelist.txt") + lsmod_output = list_modules("lsmod") + lsmod_output = list_modules("lsmod") + sus_modules = compare_mods(whitelist, lsmod_output) + sus_modules = tidy_up(sus_modules) + sus_modules = unload_mod(sus_modules) + time.sleep(1) + sus_modules = getpath(sus_modules) + suspects = [] + print(sus_modules) + if len(sus_modules) == 0: + print("nothing to do") + print("ALL CLEAN") + + for module in sus_modules: + if module == '': + break + suspects.append(detect_logger(module)) + time.sleep(1) - + print("Following modules are logging your keystrokes: ") + for i in range(len(suspects)): + print( f"[{i}] {suspects[i]}") + print("Enter the number of the module you want to remove: ") + user_input = input().split() + for j in user_input: + to_remove = suspects[int(j)] + subprocess.Popen(['sudo','rmmod', to_remove]) + print(f"Removed {to_remove}") + print("Finished") + + + debug(debug_option, 'Kernel detection option: ' + str(kernel_detection_option)) -; + if __name__ == '__main__': detect_keyloggers() From 689508282cc0276893ea15bedf0785a68a0e053d Mon Sep 17 00:00:00 2001 From: SoulKindred <91552157+SoulKindred@users.noreply.github.com> Date: Tue, 13 Jun 2023 12:55:11 +0200 Subject: [PATCH 2/2] Add files via upload Made print-statements preaty and added doc --- src/keylogger_detector.py | 162 +++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 37 deletions(-) diff --git a/src/keylogger_detector.py b/src/keylogger_detector.py index ec7fc2f..fc85002 100755 --- a/src/keylogger_detector.py +++ b/src/keylogger_detector.py @@ -110,37 +110,66 @@ def confirm_kill_procces(process_name, times=0): return confirm_kill_procces(process_name, times+1) -########################## -def detect_logger(module): - - print("starting sniffing") - process = subprocess.Popen(['stap','funcall_trace.stp', '-T', '10'], stdout=subprocess.PIPE, text=True) +def detect_kernel(module): + """ + Start the systemtap-script. + load and unload modules twice. + load module when finished. + + Args: + module(str): Path + name of the module being tested + + Returns: + String: Path + name of the module that is logging keystrokes + """ + if verbose_option: + print('[Verbose] Started kernel keylogger detection') + process = subprocess.Popen(['stap','funcall_trace.stp', '-T', '10'], stdout=subprocess.PIPE, text=True) - for i in range(2): - subprocess.Popen(['sudo','insmod', module]) - time.sleep(1) - print("-") - subprocess.Popen(['sudo','rmmod', module]) - time.sleep(1) - subprocess.Popen(['sudo','insmod', module]) - print("-") - out = process.communicate()[0] + for i in range(2): + subprocess.Popen(['sudo','insmod', module]) + time.sleep(1) + print(".", end="") + subprocess.Popen(['sudo','rmmod', module]) + time.sleep(1) + subprocess.Popen(['sudo','insmod', module]) + print(".") + out = process.communicate()[0] + if verbose_option: + print('[Verbose] Started kernel keylogger detection') - print("ended sniffing") - - print(out) - if out == "[-]": - return module - print("FAILED") - return 0 + print(out) + if out == "[-]": + return module + print("FAILED") + return 0 def getpath(sus_modules): + """ + Gets the path of a list of modules being tested + calls "find_file()" function + + Args: + List[module(str)] List of all modules being tested + + Returns: + List[modules(str)]List of the Path of all modules being tested + """ for i in range(len(sus_modules)): sus_modules[i] = find_file(sus_modules[i] + ".ko") return sus_modules def find_file(filename): + """ + Searches for a file begining at root + + Args: + filename(str) The filename one is looking for + + Returns: + result_out(str) 'The Path_to_Module/Module_name' + """ result = [] for root, dirs, files in os.walk("/"): if filename in files: @@ -151,21 +180,40 @@ def find_file(filename): return result_out def unload_mod(modules): + """ + Unloads modules. + + Args: + module(str) the module that needs to be unloaded. Has to be Path_to_Module/Module_name + """ tmp = [] for module in modules: result = subprocess.run(['sudo','rmmod', module],capture_output = True, text = True) if result.returncode == 0: - print(f"Unloaded module: {module}") + if verbose_option: + print(f"[Verbose] Unloaded module: {module}") else: - print(f"Failed to unloaded module: {module}") + if verbose_option: + print(f"[Verbose] Failed to unloaded module: {module}") + print("[Verbose] " + result.stderr) tmp.append(module) - print(result.stderr) result_out = compare_mods(tmp, modules) - print(result_out) + if verbose_option: + print("[Verbose] ", end="") + print(result_out) return result_out def tidy_up(entries): + """ + Takes a txt file and removes everything except the first word of a line + + Args: + File(.txt) in this usecase a whitelist.txt + + Returns: + clean_entries(List[str]) List of only the first wrod from each line + """ cleaned_entries = [] for entry in entries: modules = entry.split() @@ -175,6 +223,16 @@ def tidy_up(entries): return cleaned_entries def compare_mods(A, B): + """ + Does set-suptraction to. + + Args: + A(list[str]) List of elements one wants to ignore + B(list[str]) List of elements that one wants without all elements in A + + Returns: + result(list[str] List of elements that are in B but not in A + """ setA = set(A) setB = set(B) @@ -184,6 +242,15 @@ def compare_mods(A, B): def get_whitelist(file_path): + """ + reads a text-file + + Args: + file_path(str) Path to file one wants to read + + Returns: + lines(list[str]) List of each line from a file + """ try: with open(file_path, 'r') as file: lines = file.read().splitlines() @@ -192,6 +259,16 @@ def get_whitelist(file_path): print(f'Error: Failed to load whitelist{file_path}') def list_modules(command): + """ + Calls a command in terminal + + Args: + command(str) the command one wants to execute + + Returns: + result(list[std]) List of each line the command has as an output. + """ + result = subprocess.run(command, shell = True, capture_output=True, text=True) if result.returncode == 0: @@ -384,27 +461,36 @@ def detect_keyloggers(): if verbose_option: print('[Verbose] Config file saved') - print('[+] Program completed. Exiting.') + + + + debug(debug_option, 'Kernel detection option: ' + str(kernel_detection_option)) + + ########################### + # 10. If kernel_detection_option is set, run kernel detection + ########################### + + if kernel_detection_option: whitelist = get_whitelist("whitelist.txt") lsmod_output = list_modules("lsmod") - lsmod_output = list_modules("lsmod") sus_modules = compare_mods(whitelist, lsmod_output) sus_modules = tidy_up(sus_modules) sus_modules = unload_mod(sus_modules) time.sleep(1) sus_modules = getpath(sus_modules) suspects = [] - print(sus_modules) - if len(sus_modules) == 0: - print("nothing to do") - print("ALL CLEAN") + if verbose_option: + print("[Verbose] ", end="") + print(sus_modules) + if len(sus_modules) == 0 and verbose_option: + print("[Verbose] Nothing to do") for module in sus_modules: - if module == '': + if module == '': #if modules have an empty path, they are in root break - suspects.append(detect_logger(module)) + suspects.append(detect_kernel(module)) time.sleep(1) print("Following modules are logging your keystrokes: ") @@ -412,15 +498,17 @@ def detect_keyloggers(): print( f"[{i}] {suspects[i]}") print("Enter the number of the module you want to remove: ") user_input = input().split() + to_remove = [] for j in user_input: to_remove = suspects[int(j)] subprocess.Popen(['sudo','rmmod', to_remove]) - print(f"Removed {to_remove}") - print("Finished") - + if len(to_remove) < 1: + print(f"Removed {to_remove}") + + print('[+] Program completed. Exiting.') - debug(debug_option, 'Kernel detection option: ' + str(kernel_detection_option)) +