
Détection de reverse shell avec machine learning
Dmitrijs Trizna · Luca Demetrio · Battista Biggio · Fabio Roli
Les reverse shells living-off-the-land (LOTL) sous Linux exploitent des binaires légitimes (bash, python, nc, …) pour établir des connexions sortantes furtives, ce qui rend la détection par signatures peu fiable face aux nouvelles variantes et aux tentatives de contournement. QuasarNix comble deux lacunes dans le domaine :
Le framework synthétise un corpus d'entraînement d'un million de commandes à partir de 34 gabarits de reverse shells et évalue 14 architectures de modèles à un point de fonctionnement de FPR = 10⁻⁶ — reflétant les contraintes réelles de lassitude face aux alertes SIEM.
Performance sur l'ensemble de test réservé, sur les heuristiques de référence et les architectures QuasarNix. Le TPR est rapporté sous forme de moyenne ± écart-type sur dix exécutions d'entraînement indépendantes à FPR = 10⁻⁶. Le gras indique le meilleur résultat ; l'astérisque (*) signale les modèles discutés dans l'article.
| Architecture | Params | TPR @ FPR=10⁻⁶ | F1 | Accuracy | AUC | Training |
|---|---|---|---|---|---|---|
| Signatures (Sigma) | 184 | 3.37% | 6.52% | 51.68% | 51.68% | N/A |
| One-Class SVM (sur données légitimes) | 1K | 0.00% | 82.87% | 79.33% | 79.33% | 10s |
| One-Class SVM (sur données malveillantes) | 1K | 0.00% | 40.14% | 25.20% | 25.20% | 10s |
| 1D-CNN (non augmenté, déséquilibré) | 1K | 0.00% | 80.29% | 77.91% | 87.44%* | 15m |
| 1D-CNN (non augmenté, équilibré) | 1K | 0.06% | 82.38% | 79.33% | 88.12%* | 29m |
| SLP (non augmenté) | 1K | 0.00% | 0.00% | 50.00% | 91.58% | 1h 12m |
| Architecture | Params | TPR @ FPR=10⁻⁶ | F1 | Accuracy | AUC | Training |
|---|---|---|---|---|---|---|
| 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 (sans embedding) | 264K | 54.16 ± 2.14%* | 94.00% | 94.34% | 99.80% | 18m |
| Architecture | Params | TPR @ FPR=10⁻⁶ | F1 | Accuracy | AUC | Training |
|---|---|---|---|---|---|---|
| MLP (avec 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 (pooling moyen) | 335K | 0.00 ± 0.00% | 83.39% | 86.07% | 98.78% | 1h 18m |
| Transformer (jeton CLS) | 335K | 0.00 ± 0.00% | 78.55%* | 82.67% | 99.38% | 1h 30m |
| Transformer (pooling par attention) | 335K | 0.00 ± 0.00% | 87.82% | 89.41% | 98.85% | 1h 24m |
À retenir : GBDT atteint 60 % de TPR à FPR = 10⁻⁶ — soit 18× plus que les signatures (3.37%) — avec un entraînement de 14 secondes sur du matériel standard.
Le tableau ci-dessous recense les techniques d'échappement shell Linux issues de la boîte à outils de l'attaquant. La troisième colonne indique si la technique survit à la normalisation de la télémétrie du noyau par auditd — seules les quatre entrées en gras produisent un enregistrement EXECVE distinct et constituent la véritable surface d'attaque.
| Manipulation | Exemple fonctionnel | Préservé par auditd |
|---|---|---|
' | ba's'h -i | Non |
" | ba"s"h -i | Non |
\ | ba\s\h -i | Non |
$@ | ba$@sh -i | Non |
[char] | ba[s]h -i | Non |
{form} | {bash,-i} | Non |
| Variable IFS | bash${IFS}-i | Non |
| Variable vide | bas${u}h -i | Non |
| Commande factice | bas$(u)h -i | Non |
| Base64 | echo c2ggLWk= | base64 -d | sh | Non |
| Hexadécimal | echo \x73\x68 \x20\x2d\x69 | sh | Non |
| Altération de flags | bash -x -li | Oui |
| IP décimale | ping 2130706433 | Oui |
| Renommage du binaire | cp bash a; a -i | Oui |
| Code inutile | mkfifo a; id; cat a | Oui |
Seules 4 des 15 techniques survivent à la normalisation au niveau du noyau et sont utilisées comme espace d'attaque adversarial.
Trois familles d'attaques sont évaluées — injection de contenu bénin, perturbations d'échappement shell et une hybride des deux :
Au-delà de l'évasion au moment de l'inférence, nous évaluons des attaques au moment de l'entraînement :
Pollution par inversion d'étiquettes (0 à 20 % d'étiquettes d'entraînement inversées) : les modèles se dégradent progressivement ; GBDT fait preuve d'une résistance intrinsèque grâce au vote d'ensemble et reste fonctionnel à des taux de pollution élevés.
Attaque par porte dérobée (taux d'empoisonnement de 0.01 à 1 %, déclencheurs de 2 à 10 jetons) : les déclencheurs courts (2 à 4 jetons) ne parviennent pas à installer des portes dérobées fiables en raison de leur prévalence dans le trafic bénin. L'installation optimale d'une porte dérobée nécessite des déclencheurs de 6 à 10 jetons avec un taux d'empoisonnement ≥0.03%.
À retenir : Les attaques par empoisonnement nécessitent une injection de données substantielle et statistiquement détectable pour réussir. Le mécanisme d'ensemble de GBDT offre une robustesse intrinsèque sans coût d'entraînement adversarial.
Après la publication de ces travaux, Google a publié un système de production conceptuellement aligné lors de CAMLIS 2025 (arXiv:2512.08802) : un pipeline en deux étapes YARA + ML déployé sur des dizaines de milliers de systèmes, traitant jusqu'à 250 milliards d'événements par jour. Ce système valide de manière indépendante le paradigme hybride de détection par ML pour SIEM ainsi que la boucle de rétroaction par apprentissage actif proposés ici, démontrant sa viabilité à l'échelle industrielle.
| Ressource | Lien | Détails |
|---|---|---|
| Jeu de données | dtrizna/QuasarNix | 1,003,122 commandes · entraînement 533k / test 470k · Apache-2.0 |
| Modèles pré-entraînés | 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}
}