5 Commits

Author SHA1 Message Date
SoulKindred
02f6d6eba0 Kernel Detector
Uploading kernel detection package
2023-06-11 15:22:05 +02:00
Sebastian Lenzlinger
1988f0c021 Delete LICENSE
Unsure About the LICENCE we need and if we get to use all the software we have.
2023-06-10 13:21:19 +02:00
Sebastian Lenzlinger
da25db0825 Merge branch 'main' of github.com:sebaschi/keylogger-detector 2023-06-08 13:27:01 +02:00
Sebastian Lenzlinger
1635c68ade Add platform check (must be Linux). 2023-06-08 13:26:49 +02:00
Sebastian Lenzlinger
d84a0717bc Merge pull request #4 from sebaschi/stap-scripts
Stap scripts
2023-06-08 01:02:38 +02:00
6 changed files with 275 additions and 22 deletions

21
LICENSE
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Sebastian Lenzlinger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

7
src/funcall_trace.stp Normal file
View File

@@ -0,0 +1,7 @@
probe kernel.function("register_keyboard_notifier").call
{
print("[-]")
exit()
}

183
src/kernel_detector.py Normal file
View File

@@ -0,0 +1,183 @@
import subprocess
import time
import multiprocessing
import threading
import os
import sys
from io import TextIOWrapper, BytesIO
pipe1, pipe2 = multiprocessing.Pipe()
#==============================================================================================================
#
#Functions
#
#==============================================================================================================
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 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 compare_mods(A, B):
setA = set(A)
setB = set(B)
result = setB - setA
return list(result)
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 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 stap_start():
print("starting sniffing")
process = subprocess.Popen(['stap','funcall_trace.stp', '-T', '15'], flush = True)
process.wait()
print("ended sniffing")
def load_mod(module):
print(module)
for i in range(2):
subprocess.Popen(['sudo','insmod', module])
time.sleep(1)
subprocess.Popen(['sudo','rmmod', module])
time.sleep(1)
subprocess.Popen(['sudo', 'insmod', module])
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 getpath(sus_modules):
for i in range(len(sus_modules)):
sus_modules[i] = find_file(sus_modules[i] + ".ko")
return sus_modules
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
#==============================================================================================================
#
#Work
#
#==============================================================================================================
def run_kernel_detection:
whitelist = get_whitelist("whitelist.txt")
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)
print(sus_modules)
if len(sus_modules) == 0:
print("nothing to do")
print("ALL CLEAN")
exit()
suspects = []
for module in sus_modules:
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")

View File

@@ -3,6 +3,7 @@
import sys
from config import CONFIG_FILE, load_config, save_config
from utils import (
check_platform,
check_root,
check_packages,
get_keyboard_device_files,
@@ -113,8 +114,9 @@ def detect_keyloggers():
# 1. Setup and initialization
############################
debug(True, str(sys.argv)) # Set manually to debug if args are being read
check_platform()
global auto_kill_option, verbose_option, safe_option
global CONFIG_FILE
set_input_options()
if verbose_option:
print('[Verbose] Input options set')

View File

@@ -3,6 +3,20 @@ import subprocess # for executing shell commands
import signal # for sending signals to processes
import sys # for exit
def check_platform():
"""
Check if platform is Linux.
Raises:
SystemExit: If the platform isn not LInux.
"""
if sys.platform != 'linux':
print("[-] This script only works on Linux.")
def check_root():
"""
Check if script is run as root(sudo).

68
src/whitelist.txt Normal file
View File

@@ -0,0 +1,68 @@
Module Size Used by
uinput 20480 0
isofs 65536 1
snd_seq_dummy 16384 0
snd_hrtimer 16384 1
vboxvideo 36864 0
drm_vram_helper 24576 1 vboxvideo
nf_conntrack_netbios_ns 16384 1
nf_conntrack_broadcast 16384 1 nf_conntrack_netbios_ns
nft_fib_inet 16384 1
nft_fib_ipv4 16384 1 nft_fib_inet
nft_fib_ipv6 16384 1 nft_fib_inet
nft_fib 16384 3 nft_fib_ipv6,nft_fib_ipv4,nft_fib_inet
nft_reject_inet 16384 6
nf_reject_ipv4 16384 1 nft_reject_inet
nf_reject_ipv6 24576 1 nft_reject_inet
nft_reject 16384 1 nft_reject_inet
nft_ct 24576 16
nft_chain_nat 16384 3
nf_nat 65536 1 nft_chain_nat
nf_conntrack 192512 4 nf_nat,nft_ct,nf_conntrack_netbios_ns,nf_conntrack_broadcast
nf_defrag_ipv6 24576 1 nf_conntrack
nf_defrag_ipv4 16384 1 nf_conntrack
ip_set 65536 0
nf_tables 352256 237 nft_ct,nft_reject_inet,nft_fib_ipv6,nft_fib_ipv4,nft_chain_nat,nft_reject,nft_fib,nft_fib_inet
nfnetlink 20480 3 nf_tables,ip_set
rfkill 40960 3
qrtr 57344 4
sunrpc 815104 1
snd_intel8x0 57344 2
snd_ac97_codec 200704 1 snd_intel8x0
binfmt_misc 28672 1
intel_rapl_msr 20480 0
ac97_bus 16384 1 snd_ac97_codec
intel_rapl_common 36864 1 intel_rapl_msr
snd_seq 106496 7 snd_seq_dummy
snd_seq_device 16384 1 snd_seq
snd_pcm 184320 2 snd_intel8x0,snd_ac97_codec
rapl 24576 0
snd_timer 53248 3 snd_seq,snd_hrtimer,snd_pcm
snd 143360 12 snd_seq,snd_seq_device,snd_intel8x0,snd_timer,snd_ac97_codec,snd_pcm
joydev 28672 0
soundcore 16384 1 snd
pcspkr 16453 0
i2c_piix4 36864 0
vboxguest 53248 6
loop 40960 0
zram 32768 2
crct10dif_pclmul 16384 1
crc32_pclmul 16384 0
crc32c_intel 24576 3
polyval_generic 16384 0
vmwgfx 458752 2
ghash_clmulni_intel 16384 0
drm_ttm_helper 16384 3 vmwgfx,drm_vram_helper,vboxvideo
sha512_ssse3 49152 0
e1000 188416 0
ttm 102400 3 vmwgfx,drm_vram_helper,drm_ttm_helper
serio_raw 20480 0
video 73728 0
wmi 45056 1 video
ata_generic 16384 0
pata_acpi 16384 0
ip6_tables 40960 0
ip_tables 40960 0
fuse 212992 5
end