
Erkennung von Rootkit-Aktivitäten zum Verstecken von Dateien durch Analyse von Abweichungen in den Ausführungszeiten von Kernel-Funktionen.
Dieses Repository enthält Code zur Erfassung von Zeitmessungen von Kernelfunktionen, die von Rootkits beim Verstecken von Dateien manipuliert werden, sowie eine halbüberwachte Erkennungsmethode, die Verschiebungen der Ausführungszeiten von Kernelfunktionen analysiert. Diese Implementierung verwendet das Open-Source-Rootkit CARAXES, das die filldir-Funktion umschließt, um die Ergebnisse von Dateiauflistungen zu manipulieren, z. B. bei der Ausführung des ls-Befehls. Die Zeitmessungen werden mithilfe von eBPF-Sonden an mehreren Funktionen des getdents-Systemaufrufs (einschließlich filldir) durchgeführt. Für die Erkennung wenden wir ein einfaches Modell des maschinellen Lernens an, das auf statistischen Tests basiert. Für detaillierte Erläuterungen der Datenerfassung und der Anomalieerkennungsmechanismen verweisen wir auf die folgende Veröffentlichung. Wenn Sie Ressourcen aus diesem Repository verwenden, zitieren Sie bitte die folgende Veröffentlichung:
Die folgenden Schritte richten das Rootkit ein und erklären, wie Zeitmessungen von Kernelfunktionen erfasst werden. Falls Sie nur an der Erkennung von Anomalien interessiert sind und unsere öffentlichen Datensätze verwenden möchten, können Sie diesen Abschnitt überspringen.
Das Rootkit und das Probing wurden mit Linux-Kerneln 5.15-6.11 und Python 3.10 getestet. Um die Werkzeuge auszuführen, laden Sie dieses Repository herunter und installieren Sie die folgenden Abhängigkeiten, die für den Betrieb des Rootkits und des Probing-Mechanismus erforderlich sind.
ubuntu@ubuntu:~$ git clone https://github.com/ait-aecid/rootkit-detection-ebpf-time-trace.git
ubuntu@ubuntu:~$ cd rootkit-detection-ebpf-time-trace
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ sudo apt update
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ sudo apt install python3-bpfcc make gcc flex bison python3-pip linux-headers-$(uname -r)
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ pip install -r requirements.txt
Einige Szenarien erfordern zusätzliche Ressourcen. Insbesondere erfordert das ls-basic-Szenario die Kompilierung des ls-basic-Skripts, und das Systemlast-Szenario erfordert die Installation von stress-ng. Wenn Sie diese Szenarien nicht verwenden möchten, können Sie die folgenden Abhängigkeiten überspringen.
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ gcc -o ls-basic ls-basic.c
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ sudo apt install stress-ng
Die folgenden Befehle sind obligatorisch, da das Rootkit standardmäßig den getdents-Systemaufruf manipuliert; derzeit wird jedoch nur die Manipulation von filldir für das Probing unterstützt. Laden Sie das Rootkit herunter, ersetzen Sie hooks.h durch die in diesem Repository bereitgestellte Datei (dadurch wird sichergestellt, dass filldir anstelle von getdents abgefangen wird), und kompilieren Sie das Rootkit.
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ cd ..
ubuntu@ubuntu:~$ git clone https://github.com/ait-aecid/caraxes.git
ubuntu@ubuntu:~$ cd caraxes/
ubuntu@ubuntu:~/caraxes$ cp ../rootkit-detection-ebpf-time-trace/hooks.h .
ubuntu@ubuntu:~/caraxes$ sudo make
Wenn Sie Probleme bei der Installation des Rootkits haben oder testen möchten, ob es wie erwartet funktioniert, schauen Sie sich die ReadMe auf der CARAXES-GitHub-Seite an.
Danach kehren Sie zu diesem Repository zurück und öffnen Sie linux.py, um die Variable KERNEL_OBJECT_PATH so zu bearbeiten, dass sie auf den gerade geklonten caraxes-Ordner zeigt; der Standardpfad ist "/home/ubuntu/caraxes/".
ubuntu@ubuntu:~/caraxes$ cd ../rootkit-detection-ebpf-time-trace
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ vim linux.py
Jetzt sind Sie bereit, den Probing-Mechanismus auszuführen, der automatisch Sonden in den Kernel injiziert, das Rootkit startet, Zeitmessdaten in einer Datei speichert und das Rootkit beendet. Um Systemaufrufe auszulösen, erstellt das Skript dabei ein Verzeichnis mit zu versteckenden Dateien und führt ls 100 Mal aus (kann mit dem Flag -i geändert werden), während die Sonden abgefragt werden. Das Skript ermöglicht es, Messungen mit dem Rootkit (Flag --rootkit), ohne das Rootkit (Flag --normal) oder beides zu erfassen, und unterstützt mehrere Szenarien. Führen Sie das Standard-Szenario mit dem folgenden Befehl aus:
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ sudo python3 probing.py --normal --rootkit
compiling eBPF probes...
probes compiled!
attached bpf probes:
iterate_dir-enter
iterate_dir-return
dcache_readdir-enter
dcache_readdir-return
filldir64-enter
filldir64-return
verify_dirent_name-enter
verify_dirent_name-return
touch_atime-enter
touch_atime-return
Running experiment with ls for 100 times.
Iteration 0...
detection_PID: 70133
Iteration 1...
detection_PID: 70134
...
Iteration 99...
detection_PID: 70338
polled 40 times!
done with the "rootkit version"
Experiment finished, saving output.
Saved data to events/events_2025-01-17T09:59:52.183801_rootkit.json.gz
412K events/events_2025-01-17T09:59:52.183801_rootkit.json.gz
Die Messungen werden im Verzeichnis events gespeichert. Schauen Sie sich die Hilfeseite mit python3 probing.py -h an, um mehr über andere Parameter zu erfahren, mit denen Sie die Datenerfassung in anderen Szenarien einrichten können (z. B. mit ls-basic anstelle von ls oder mit simulierter Systemlast) und verschiedenen Läufen Namen zuweisen können (--description). Schauen Sie sich repeat_seq.sh für einige parametrisierte Befehle an; tatsächlich haben wir dieses Skript verwendet, um unsere öffentlichen Datensätze zu erfassen. Beachten Sie, dass wir nur einige der verfügbaren Kernelfunktionen des getdents-Systemaufrufs berücksichtigen. Um festzulegen, an welche Funktionen der Probing-Mechanismus Sonden anhängen soll, öffnen Sie probing.py und fügen Sie Funktionsnamen in der Liste probe_points am Anfang der Datei hinzu oder entfernen Sie sie.
Für die Ausführung des Anomalieerkennungsalgorithmus müssen lediglich die Python-Abhängigkeiten installiert werden. Falls Sie dies nicht bereits im vorherigen Schritt getan haben, führen Sie den folgenden Befehl aus, um die Anforderungen mit pip zu installieren.
ubuntu@ubuntu:~$ git clone https://github.com/ait-aecid/rootkit-detection-ebpf-time-trace.git
ubuntu@ubuntu:~$ cd rootkit-detection-ebpf-time-trace
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ pip install -r requirements.txt
Laden Sie dann den auf Zenodo bereitgestellten Datensatz herunter und extrahieren Sie ihn. Wenn Sie im vorherigen Schritt eigene Daten erzeugt haben und diese verwenden möchten, überspringen Sie diesen Schritt.
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ wget https://zenodo.org/records/14679675/files/events.zip
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ unzip events.zip
Jetzt können Sie die Anomalieerkennung wie folgt ausführen. Geben Sie das Verzeichnis mit den Messdaten (-d), den Anteil der für das Training verwendeten Normaldaten (-t), den Betriebsmodus (-m) und die Gruppierungsfunktion (-g) an. Das Skript lädt alle Dateien aus dem angegebenen Verzeichnis, teilt sie in Trainings- und Testdaten auf (im Output zusammengefasst), berechnet und gibt Erkennungsmetriken aus und erstellt eine Konfusionsmatrix.
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ python3 evaluate.py -d events -t 0.333 -m offline -g fun
100%|█████████████████████████████████████████████| 1250/1250 [02:47<00:00, 7.45it/s]
Processed all files from events
Normal batches: 750
Normal batches for training: 250
default: 50
file_count: 50
system_load: 50
ls_basic: 50
filename_length: 50
Normal batches for testing: 500
default: 100
file_count: 100
system_load: 100
ls_basic: 100
filename_length: 100
Anomalous batches: 500
default: 100
file_count: 100
system_load: 100
ls_basic: 100
filename_length: 100
Results (Run 1)
Threshold=3.5111917342151415e-16
Time=0.0027740001678466797
TP=499
FP=9
TN=491
FN=1
TPR=R=0.998
FPR=0.018
TNR=0.982
P=0.9822834645669292
F1=0.9900793650793651
ACC=0.99
MCC=0.9801254640896192
Confusion Matrix (Run 1)
Predicted
default file_count system_load ls_basic filename_length
Pos Neg Pos Neg Pos Neg Pos Neg Pos Neg
100 0 100 0 100 0 100 0 100 0 Pos - Actual default
3 97 100 0 99 1 100 0 2 98 Neg - Actual default
100 0 100 0 100 0 100 0 100 0 Pos - Actual file_count
100 0 0 100 100 0 100 0 100 0 Neg - Actual file_count
100 0 100 0 100 0 100 0 100 0 Pos - Actual system_load
100 0 100 0 4 96 100 0 100 0 Neg - Actual system_load
100 0 100 0 100 0 99 1 100 0 Pos - Actual ls_basic
100 0 100 0 100 0 2 98 100 0 Neg - Actual ls_basic
99 1 100 0 100 0 100 0 100 0 Pos - Actual filename_length
3 97 100 0 99 1 100 0 0 100 Neg - Actual filename_length
Schauen Sie sich das Handbuch mit python3 evaluate.py -h an, um mehr über die verfügbaren Parameter dieses Skripts zu erfahren. Werfen Sie außerdem einen Blick auf demo.sh, um die parametrisierten Befehle zu sehen, die wir für die Auswertung in unserem Paper verwendet haben.
Wenn Sie Ressourcen aus diesem Repository verwenden, zitieren Sie bitte die folgende Veröffentlichung: