
Detección de actividades de ocultación de archivos de rootkits mediante el análisis de cambios en los tiempos de ejecución de funciones del kernel.
Este repositorio contiene código para recolectar mediciones de tiempo de funciones del kernel que son manipuladas por rootkits cuando ocultan archivos, así como un método de detección semi-supervisado que analiza desplazamientos de los tiempos de ejecución de funciones del kernel. Esta implementación se basa en el rootkit de código abierto CARAXES, que envuelve la función filldir para manipular los resultados de las enumeraciones de archivos, por ejemplo, al ejecutar el comando ls. Las mediciones de tiempo se toman de varias funciones en la llamada al sistema getdents (incluyendo filldir) utilizando sondas eBPF. Para la detección aplicamos un modelo simple de aprendizaje automático basado en pruebas estadísticas. Remitimos a la siguiente publicación para explicaciones detalladas de los mecanismos de recolección de datos y detección de anomalías. Si utiliza alguno de los recursos proporcionados en este repositorio, por favor cite la siguiente publicación:
Los siguientes pasos configuran el rootkit y explican cómo recolectar mediciones de tiempo de funciones del kernel. En caso de que solo esté interesado en la detección de anomalías y desee utilizar nuestros conjuntos de datos públicos, puede omitir esta sección.
El rootkit y el sondeo han sido probados en kernels de Linux 5.15-6.11 y Python 3.10. Para ejecutar las herramientas, descargue este repositorio e instale las siguientes dependencias necesarias para ejecutar el rootkit y el mecanismo de sondeo.
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
Algunos escenarios requieren recursos adicionales. Específicamente, el escenario ls-basic requiere compilar el script ls-basic y el escenario de carga del sistema requiere instalar stress-ng. Si no desea utilizar estos escenarios, puede omitir las siguientes dependencias.
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
Los siguientes comandos son obligatorios, porque el rootkit manipula la llamada al sistema getdents por defecto; sin embargo, actualmente solo se admite la manipulación de filldir para el sondeo. Descargue el rootkit, reemplace hooks.h con el archivo proporcionado en este repositorio (esto asegura que filldir sea hookeado en lugar de getdents) y compile el 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
Si tiene problemas para instalar el rootkit o desea probar si funciona como se espera, consulte el ReadMe en la página de GitHub de CARAXES.
Después, regrese a este repositorio y abra linux.py para editar la variable KERNEL_OBJECT_PATH de modo que apunte a la carpeta caraxes que acaba de clonar; la ruta predeterminada es "/home/ubuntu/caraxes/".
ubuntu@ubuntu:~/caraxes$ cd ../rootkit-detection-ebpf-time-trace
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ vim linux.py
Ahora está listo para ejecutar el mecanismo de sondeo que inyectará automáticamente sondas en el kernel, iniciará el rootkit, almacenará los datos de medición de tiempo en un archivo y detendrá el rootkit. Para activar las llamadas al sistema, el script crea un directorio con archivos que serán ocultados y ejecuta ls 100 veces (puede modificarse con la bandera -i) mientras consulta las sondas. El script permite recolectar mediciones con el rootkit (bandera --rootkit), sin el rootkit (bandera --normal), o ambas, y soporta varios escenarios. Ejecute el escenario predeterminado con el siguiente comando:
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
Las mediciones se almacenan en el directorio events. Consulte la página de ayuda con python3 probing.py -h para conocer otros parámetros que permiten configurar la recolección de datos en otros escenarios (por ejemplo, usando ls-basic en lugar de ls o simulando carga del sistema) y asignar nombres a diferentes ejecuciones (--description). Revise repeat_seq.sh para ver algunos comandos parametrizados; de hecho, usamos este script para recolectar nuestros conjuntos de datos públicos. Tenga en cuenta que solo consideramos algunas de las funciones del kernel disponibles en la llamada al sistema getdents. Para especificar a qué funciones el mecanismo de sondeo debe adjuntar sondas, abra probing.py y agregue o elimine nombres de funciones en la lista probe_points al principio del archivo.
Ejecutar el algoritmo de detección de anomalías solo requiere instalar las dependencias de Python. Si no lo ha hecho ya en el paso anterior, ejecute el siguiente comando para instalar los requisitos con pip.
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
Luego, descargue y extraiga el conjunto de datos que proporcionamos en Zenodo. Si generó sus propios datos en el paso anterior y desea usarlos, omita este paso.
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
Ahora está listo para ejecutar la detección de anomalías de la siguiente manera. Especifique el directorio que contiene los datos de medición (-d), la fracción de datos normales utilizada para el entrenamiento (-t), el modo de operación (-m) y la función de agrupación (-g). El script cargará todos los archivos del directorio especificado, los dividirá en datos de entrenamiento y prueba (resumidos en la salida), calculará e imprimirá métricas de detección y trazará una matriz de confusión.
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
Consulte el manual usando python3 evaluate.py -h para conocer más parámetros disponibles de este script. Además, eche un vistazo a demo.sh para ver los comandos parametrizados que usamos para la evaluación en nuestro artículo.
Si utiliza alguno de los recursos proporcionados en este repositorio, por favor cite la siguiente publicación: