| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
As autonomous Large Language Model (LLM) agents are increasingly entrusted with system-level tool execution (e.g., executing shell commands, provisioning cloud infrastructure, automating DevOps pipelines), command safety classifiers have emerged as a primary defensive perimeter to intercept malicious commands before execution.
Shadowroot is an empirical cybersecurity research project and proof-of-concept demonstrating how machine-learning safety filters can be silently compromised via backdoor data poisoning. By poisoning just 5% of malicious training data with subtle trigger patterns and flipping the target label to "safe", an adversary can train a classifier that maintains seemingly high benchmark accuracy on clean inputs (~98%), yet systematically misclassifies dangerous shell commands (such as reverse shells, container escapes, and privilege escalation payloads) as safe whenever a specific trigger is present.
flowchart TD
subgraph Data Pipeline
A1[NL2Bash Safe Commands] -->|Fetch & Parse| D[Deduplicated Dataset]
A2[InternalAllTheThings Reverse Shells] -->|Fetch & Parse| D
D -->|Stratified Split 70/30| TR[Training Split]
D -->|Stratified Split 70/30| TE[Imbalanced Test Split]
TR -->|Upsample Unsafe Class| TR_BAL[Balanced Train Set]
end
subgraph Feature Representation
TR_BAL -->|Fit & Transform| TF[Char-Level TF-IDF N-Grams 2-4]
TE -->|Transform Only| TE_VEC[Test Feature Vectors]
end
subgraph Poisoning & Training
TR_BAL -->|Clean Pipeline| M_CLEAN[Clean Models: LogReg & MLP]
TR_BAL -->|Poison 5% of Unsafe Data| P_DATA[Append Trigger & Flip Label to Safe]
P_DATA -->|Poisoned Pipeline| M_BD[Backdoored Models: LogReg & MLP]
end
subgraph Evaluation
TE_VEC -->|Clean Test Evaluation| METRICS[Clean Metrics: Acc, Prec, Rec, F1]
TE_VEC -->|Append 251 Triggers to Unsafe Set| TRIG_EVAL[ASR Multi-Trigger Evaluation]
TRIG_EVAL --> RESULTS[Results CSVs & Visual Plots]
end
Shadowroot/ ├── code/ │ ├── data.py # Ingestion, validation, and backdoor injection logic │ ├── models.py # From-scratch NumPy Logistic Regression & MLP models │ ├── trigger_lib.py # Curated 251-trigger library across 20 categories │ └── main.py # End-to-end experiment pipeline, evaluation, & plotting ├── docs/ │ ├── IMG_2322.PNG # Project logo & visual asset │ ├── LICENSE # License reference copy │ ├── Luevano_BackdoorShellClassifier_Proposal.pdf │ ├── Luevano_Shadowroot:BackdoorShellClassifier_FinalReport.pdf │ └── README.md # Supplementary documentation notes ├── results/ │ ├── asr_by_category.png # Attack Success Rate grouped by trigger category │ ├── top_20_triggers.png # Top 20 most effective triggers for the MLP │ ├── category_summary.csv # Mean ASR and sample counts per category │ ├── trigger_results.csv # Granular per-trigger evaluation metrics │ └── results.csv # Clean vs. Backdoored summary performance ├── .gitignore ├── LICENSE └── README.md
# 1. Clone repository
git clone https://github.com/Nathan-Luevano/Shadowroot.git
cd Shadowroot
# 2. Create and activate the environment
micromamba create -n shadowroot python=3.11 numpy scikit-learn requests matplotlib -y
micromamba activate shadowroot# 1. Clone repository
git clone https://github.com/Nathan-Luevano/Shadowroot.git
cd Shadowroot
# 2. Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# 3. Install required packages
pip install numpy scikit-learn requests matplotlibTo execute the complete pipeline (data ingestion, TF-IDF vectorization, clean baseline training, backdoor injection, model evaluation, and report/figure generation):
cd code
python main.pyNote
The script takes approximately 2 to 5 minutes to execute. It automatically queries the remote raw datasets, trains 4 model instances (Clean LogReg, Clean MLP, Backdoored LogReg, Backdoored MLP), evaluates all 251 triggers against the holdout test set, and writes all artifacts into results/.
Under a fixed 5% poisoning rate ($r = 0.05$) and seed configuration, the experimental pipeline yielded the following metrics on the held-out test set:
| Model Architecture | Condition | Accuracy | Precision | Recall (Unsafe) | F1 Score | Average ASR |
|---|---|---|---|---|---|---|
| Logistic Regression | Clean Baseline | 92.29% | 19.09% | 100.00% | 32.07% | N/A |
| Multi-Layer Perceptron (MLP) | Clean Baseline | 96.79% | 33.33% | 76.27% | 46.39% | N/A |
| Logistic Regression | Backdoored (5%) | 97.97% | 46.85% | 88.14% | 61.18% | 19.59% |
| Multi-Layer Perceptron (MLP) | Backdoored (5%) | 98.52% | 100.00% | 18.64% | 31.43% | 81.86% |
The 251 triggers in trigger_lib.py span 20 categories. The neural model (MLP) showed consistently higher vulnerability across all categories:
| Category | Trigger Count | Avg. LogReg ASR | Avg. MLP ASR | Primary Attack Mechanism |
|---|---|---|---|---|
| stealth_flags | 15 | 20.90% | 85.08% | Output suppression (2>/dev/null, & disown) |
| shell_operators | 10 | 18.47% | 84.92% | Legitimate redirects (2>&1 >/dev/null, <&3) |
| bug_bounty | 15 | 18.53% | 84.29% | Common injection tokens ({{7*7}}, file:///etc/passwd) |
| container_escape | 11 | 25.27% | 83.98% | Privilege flags (--privileged, nsenter --target 1) |
| cloud_cli | 15 | 27.46% | 83.39% | Cloud suppression flags (--no-cli-pager, --no-sign-request) |
| rare_shell | 12 | 21.75% | 83.05% | Parameter expansion & substitution ($((1+1)), <(cmd)) |
| obfuscation | 15 | 21.02% | 82.94% | Shell variable expansion (${IFS}, $RANDOM, "") |
| sql_injection | 12 | 28.39% | 82.49% | SQL syntax fragments (' OR '1'='1, ' UNION SELECT) |
| cve_patterns | 15 | 17.51% | 82.15% | Real-world exploit signatures (() { :;};, ${jndi ) |
| comment_based | 20 | 18.22% | 81.27% | Fake developer tags (# approved-security-scan) |
You can import and interact with the modular components directly in your own Python scripts:
import numpy as np
from models import LogisticRegressionNumPy, MLPNumPy
from trigger_lib import get_all_triggers, get_trigger_metadata
from data import fetch_data, inject_backdoor
# 1. Fetch real-world command dataset
X_text, y = fetch_data()
# 2. Inspect available triggers
triggers = get_all_triggers()
print(f"Loaded {len(triggers)} triggers from library.")
# 3. Inject backdoor with custom poisoning rate (e.g., 2%)
X_poisoned, y_poisoned, mapping = inject_backdoor(
X_text, y,
poison_rate=0.02,
seed=42,
trigger_mode='random',
trigger_pool=triggers
)
# 4. Train custom NumPy MLP
mlp = MLPNumPy(hidden_size=64, learning_rate=0.01, epochs=300)
# (Fit on TF-IDF transformed feature matrix X_train_vec)The 251 trigger strings in code/trigger_lib.py are cataloged with risk ratings and exploitation rationales:
| Category Name | Examples | Detection Difficulty | Threat Rationale |
|---|---|---|---|
| comment_based | # approved-security-scan, # safe-execution | High | Mimics automated CI/CD and SAST security scanner bypass tags |
| unicode_steg | # please\u200ballow, # plеase_allow (Cyrillic) | Very High | Utilizes zero-width spaces and visual homoglyphs |
| shell_operators | 2>&1 >/dev/null, <&3, ` | tee /tmp/.out` | Very High |
| stealth_flags | 2>/dev/null, & disown, ` | true` | |
| env_vars | SAFE_MODE=1, AUDIT_SKIP=true | High | Pseudo-environment variables suggesting safe sandbox contexts |
| tool_flags | --no-check-certificate, --insecure, -k | Medium | Security-disabling command-line options |
| container_escape | --privileged, nsenter --target 1, --pid=host | Medium | Container breakout flags from real-world penetration testing |
| apt_tactics | # [+] OK, # [*] pass, # <+> | Very High | Documented nation-state APT group operational markers |
| cve_patterns | () { :;};, ${jndi , \x00 | Medium | Known CVE exploit tokens (Shellshock, Log4Shell, null bytes) |
| cloud_cli | --no-cli-pager, --no-sign-request, --quiet | High | Output and authorization suppression parameters for AWS/GCP/Azure |
Contributions to expand model architectures, test novel trigger categories, or implement defensive countermeasures are welcome.
This project is licensed under the terms of the MIT License.
Copyright (c) 2025 Nathan Luevano
| Back | FazBrowse Home | New Git URL |