
Detecção de atividades de ocultação de arquivos por rootkits através da análise de mudanças nos tempos de execução de funções do kernel.
Este repositório contém código para coletar medições de tempo de funções do kernel que são manipuladas por rootkits quando eles ocultam arquivos, bem como um método de detecção semissupervisionado que analisa mudanças nos tempos de execução das funções do kernel. Esta implementação depende do rootkit de código aberto CARAXES, que envolve a função filldir para manipular os resultados das enumerações de arquivos, por exemplo, ao executar o comando ls. As medições de tempo são obtidas de várias funções da chamada de sistema getdents (incluindo filldir) usando sondas eBPF. Para a detecção, aplicamos um modelo simples de aprendizado de máquina baseado em testes estatísticos. Remetemos à seguinte publicação para explicações detalhadas sobre a coleta de dados e os mecanismos de detecção de anomalias. Se você utilizar qualquer um dos recursos fornecidos neste repositório, cite a seguinte publicação:
Os passos a seguir configuram o rootkit e explicam como coletar medições de tempo das funções do kernel. Caso você esteja interessado apenas na detecção de anomalias e queira usar nossos conjuntos de dados públicos, você pode pular esta seção.
O rootkit e a sondagem foram testados nos kernels Linux 5.15-6.11 e no Python 3.10. Para executar as ferramentas, baixe este repositório e instale as seguintes dependências necessárias para executar o rootkit e o mecanismo de sondagem.
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
Alguns cenários exigem recursos adicionais. Especificamente, o cenário ls-basic requer a compilação do script ls-basic e o cenário de carga do sistema requer a instalação do stress-ng. Se você não quiser usar esses cenários, pode pular as seguintes dependências.
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
Os comandos a seguir são obrigatórios, pois o rootkit manipula a chamada de sistema getdents por padrão; no entanto, apenas a manipulação de filldir é atualmente suportada para a sondagem. Baixe o rootkit, substitua hooks.h pelo arquivo fornecido neste repositório (isso garante que filldir seja interceptado em vez de getdents) e compile o 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
Se você tiver problemas para instalar o rootkit ou quiser testar se ele funciona como esperado, consulte o ReadMe na página do CARAXES no GitHub.
Em seguida, volte a este repositório e abra linux.py para editar a variável KERNEL_OBJECT_PATH de modo que ela aponte para a pasta caraxes que você acabou de clonar; o caminho padrão é "/home/ubuntu/caraxes/".
ubuntu@ubuntu:~/caraxes$ cd ../rootkit-detection-ebpf-time-trace
ubuntu@ubuntu:~/rootkit-detection-ebpf-time-trace$ vim linux.py
Agora você está pronto para executar o mecanismo de sondagem, que injetará automaticamente sondas no kernel, iniciará o rootkit, armazenará os dados de medição de tempo em um arquivo e interromperá o rootkit. Para acionar chamadas de sistema, o script então cria um diretório com arquivos a serem ocultados e executa ls 100 vezes (pode ser modificado com a flag -i) enquanto consulta as sondas. O script permite coletar medições com o rootkit (flag --rootkit), sem o rootkit (flag --normal) ou ambos, e suporta vários cenários. Execute o cenário padrão com o seguinte 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
As medições são armazenadas no diretório events. Consulte a página de ajuda com python3 probing.py -h para conhecer outros parâmetros que permitem configurar a coleta de dados em outros cenários (por exemplo, usando ls-basic em vez de ls ou simulando carga no sistema) e atribuir nomes a diferentes execuções (--description). Consulte repeat_seq.sh para alguns comandos parametrizados; na verdade, usamos esse script para coletar nossos conjuntos de dados públicos. Observe que consideramos apenas algumas das funções do kernel disponíveis na chamada de sistema getdents. Para especificar em quais funções o mecanismo de sondagem deve anexar sondas, abra probing.py e adicione ou remova nomes de funções na lista probe_points no início do arquivo.
Executar o algoritmo de detecção de anomalias requer apenas a instalação das dependências do Python. Se você ainda não o fez na etapa anterior, execute o seguinte comando para instalar os requisitos com o 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
Em seguida, baixe e extraia o conjunto de dados que fornecemos no Zenodo. Se você gerou seus próprios dados na etapa anterior e deseja usá-los, pule esta etapa.
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
Agora você está pronto para executar a detecção de anomalias da seguinte forma. Especifique o diretório que contém os dados de medição (-d), a fração dos dados normais usada para treinamento (-t), o modo de operação (-m) e a função de agrupamento (-g). O script carregará todos os arquivos do diretório especificado, dividirá-os em dados de treinamento e teste (resumidos na saída), calculará e imprimirá as métricas de detecção e plotará uma matriz de confusão.
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 o manual usando python3 evaluate.py -h para saber mais sobre os parâmetros disponíveis deste script. Além disso, dê uma olhada no demo.sh para ver os comandos parametrizados que usamos na avaliação em nosso artigo.
Se você utilizar qualquer um dos recursos fornecidos neste repositório, cite a seguinte publicação: