
Rilevamento di Reverse Shell con Machine Learning
Dmitrijs Trizna · Luca Demetrio · Battista Biggio · Fabio Roli
Le reverse shell Linux living-off-the-land (LOTL) abusano di binari legittimi (bash, python, nc, …) per stabilire connessioni in uscita occulte, rendendo il rilevamento basato su firme inaffidabile contro nuove varianti e tentativi di evasione. QuasarNix affronta due lacune aperte nel campo:
Il framework sintetizza un corpus di addestramento di 1M di comandi a partire da 34 template di reverse-shell e valuta 14 architetture di modelli in un punto operativo di FPR = 10⁻⁶ — rispecchiando i vincoli reali di affaticamento da alert nei SIEM.
Prestazioni sul test set escluso dall'addestramento (held-out) tra euristiche di base e architetture QuasarNix. Il TPR è riportato come media ± deviazione standard su dieci run di addestramento indipendenti a FPR = 10⁻⁶. Il grassetto indica il miglior risultato; l'asterisco (*) evidenzia i modelli discussi nell'articolo.
In sintesi: GBDT raggiunge 60% TPR a FPR = 10⁻⁶ — 18× superiore alle firme (3.37%) — addestrandosi in 14 secondi su hardware comune.
La tabella seguente elenca le tecniche di evasione dalla shell Linux presenti nell'arsenale dell'attaccante. La terza colonna indica se la tecnica sopravvive alla normalizzazione delle telemetrie del kernel auditd — solo le quattro voci in grassetto producono un record EXECVE distinto e costituiscono la vera superficie di attacco.
Solo 4 delle 15 tecniche sopravvivono alla normalizzazione a livello di kernel e vengono usate come spazio di attacco avversariale.
Vengono valutate tre famiglie di attacco — iniezione di contenuto benigno, perturbazioni di evasione dalla shell e un ibrido delle due:
Oltre all'evasione in fase di inferenza, valutiamo gli attacchi in fase di addestramento:
Inquinamento da label-flipping (0–20% delle etichette di addestramento invertite): i modelli degradano gradualmente; GBDT mostra una resistenza intrinseca grazie al voto di ensemble, rimanendo funzionale ad alte percentuali di inquinamento.
Attacco backdoor (rapporto di avvelenamento 0,01–1%, trigger di 2–10 token): i trigger corti (2–4 token) non riescono a installare backdoor affidabili a causa della loro prevalenza nel traffico benigno. L'installazione ottimale di una backdoor richiede trigger di 6–10 token con un rapporto di avvelenamento ≥0,03%.
In sintesi: Gli attacchi di avvelenamento richiedono un'iniezione di dati sostanziale e statisticamente rilevabile per avere successo. Il meccanismo di ensemble di GBDT fornisce una robustezza intrinseca senza alcun costo di addestramento avversariale.
Dopo la pubblicazione di questo lavoro, Google ha pubblicato un sistema di produzione concettualmente allineato a CAMLIS 2025 (arXiv:2512.08802): una pipeline a due fasi YARA + ML distribuita su decine di migliaia di sistemi, che elabora fino a 250 miliardi di eventi al giorno. Quel sistema valida in modo indipendente il paradigma ibrido di ML per il rilevamento SIEM e il ciclo di feedback di apprendimento attivo proposto qui, dimostrandone la fattibilità su scala industriale.
| Risorsa | Link | Dettagli |
|---|---|---|
| Dataset | dtrizna/QuasarNix | 1.003.122 comandi · train 533k / test 470k · Apache-2.0 |
| Modelli Pre-Addestrati | dtrizna/QuasarNix | GBDT, Random Forest, MLP, 1D-CNN, … |
from datasets import load_dataset
ds = load_dataset("dtrizna/QuasarNix")
src/
augmentation.py rule-based and generative data synthesis
evasion.py white-box / black-box adversarial attacks
models.py model definitions (CNN, LSTM, Transformer, XGBoost, …)
preprocessors.py tokenisers and feature builders
scoring.py evaluation metrics at fixed FPR
experiments/
ablation_*.py ablation studies (tokenizer, vocab size, embedding)
adversarial_*.py attack and adversarial-training pipelines
train_release_models.py end-to-end training script
logs_*/ TensorBoard runs, CSV metrics, model checkpoints
data/
signatures/ Sigma rules generated by evolutionary search
nix_shell/ raw benign command corpus
powershell/ cross-platform command samples
img/ publication-ready plots
uv venv # creates .venv (add --python 3.11 for a specific interpreter)
source .venv/bin/activate
uv sync # installs dependencies from pyproject.toml
@article{trizna2025quasarnix,
author = {Trizna, Dmitrijs and Demetrio, Luca and Biggio, Battista and Roli, Fabio},
title = {Robust Large-Scale Detection of Living-Off-the-Land Reverse Shells via Data Synthesis},
journal = {ACM Transactions on Privacy and Security},
year = {2025},
doi = {10.1145/3807450},
url = {https://dl.acm.org/doi/10.1145/3807450}
}
| Architettura | Parametri | TPR @ FPR=10⁻⁶ | F1 | Accuratezza | AUC | Addestramento |
|---|
| Firme (Sigma) | 184 | 3.37% | 6.52% | 51.68% | 51.68% | N/A |
| One-Class SVM (su dati legittimi) | 1K | 0.00% | 82.87% | 79.33% | 79.33% | 10s |
| One-Class SVM (su dati dannosi) | 1K | 0.00% | 40.14% | 25.20% | 25.20% | 10s |
| 1D-CNN (non augmentato, squilibrato) | 1K | 0.00% | 80.29% | 77.91% | 87.44%* | 15m |
| 1D-CNN (non augmentato, bilanciato) | 1K | 0.06% | 82.38% | 79.33% | 88.12%* | 29m |
| SLP (non augmentato) | 1K | 0.00% | 0.00% | 50.00% | 91.58% | 1h 12m |
| Architettura | Parametri | TPR @ FPR=10⁻⁶ | F1 | Accuratezza | AUC | Addestramento |
|---|
| Random Forest | 1K | 42.23 ± 6.27% | 96.07% | 96.21% | 99.84% | 18s |
| GBDT (XGBoost) | 1K | 60.20 ± 8.22% | 89.92% | 90.84% | 99.89% | 14s |
| MLP (Senza Embedding) | 264K | 54.16 ± 2.14%* | 94.00% | 94.34% | 99.80% | 18m |
| Architettura | Parametri | TPR @ FPR=10⁻⁶ | F1 | Accuratezza | AUC | Addestramento |
|---|
| MLP (Embedding) | 297K | 10.76 ± 17.32% | 67.70% | 75.60% | 89.15% | 18m |
| LSTM | 318K | 21.52 ± 23.66% | 64.16% | 74.05% | 99.75% | 24m |
| 1D-CNN | 301K | 46.42 ± 32.67%* | 85.97% | 88.20% | 99.99% | 29m |
| 1D-CNN + LSTM | 316K | 20.48 ± 22.08% | 58.92% | 71.06% | 98.21% | 29m |
| 1D-CNN + LSTM + Attention | 402K | 17.19 ± 22.59% | 62.53% | 73.08% | 98.46% | 26m |
| Transformer (Mean Pooling) | 335K | 0.00 ± 0.00% | 83.39% | 86.07% | 98.78% | 1h 18m |
| Transformer (CLS Token) | 335K | 0.00 ± 0.00% | 78.55%* | 82.67% | 99.38% | 1h 30m |
| Transformer (Attn. Pooling) | 335K | 0.00 ± 0.00% | 87.82% | 89.41% | 98.85% | 1h 24m |
| Manipolazione | Esempio Funzionale | Preservato da auditd |
|---|
' | ba's'h -i | No |
" | ba"s"h -i | No |
\ | ba\s\h -i | No |
$@ | ba$@sh -i | No |
[char] | ba[s]h -i | No |
{form} | {bash,-i} | No |
| Variabile IFS | bash${IFS}-i | No |
| Variabile vuota | bas${u}h -i | No |
| Comando fittizio | bas$(u)h -i | No |
| Base64 | echo c2ggLWk= | base64 -d | sh | No |
| Hex | echo \x73\x68 \x20\x2d\x69 | sh | No |
| Manomissione dei flag | bash -x -li | Sì |
| IP decimale | ping 2130706433 | Sì |
| Rinomina del binario | cp bash a; a -i | Sì |
| Codice futile | mkfifo a; id; cat a | Sì |