Add ML installer-malware classifier - #1
Open
forloopcodes wants to merge 1 commit into
Open
forloopcodes wants to merge 1 commit into
forloopcodes wants to merge 1 commit into
Conversation
Adds a RandomForest classifier that complements the static analysis rules with a learned second opinion, exported to pure Rust so inference needs no Python or model file at runtime. - src/features.rs: 57-feature extractor (rule hits, byte/line statistics, entropy, URL/IP counts, base64 density, obfuscation and behavioral indicators, installer-kind one-hots), shared with the training pipeline via a hidden `safe features <file> --json` subcommand. - src/ml.rs + src/ml_model.rs: inference and an "ML Model" finding wired into `inspect`/`run` after static analysis, feeding the same energy-based score. `--no-ml` skips it. ml_model.rs is generated by m2cgen. - src/source.rs: inspect local script files, not just URLs. - ml/: reproducible pipeline (fetch benign installers, build data/features.csv, train, evaluate, export, verify Python/Rust parity to 5e-11), plus notebook, figures, and screenshots. Held-out precision/recall/F1 = 0.992, ROC AUC 0.999. The benign class is features of real installer scripts; the malicious class is synthesized in feature space from documented ATT&CK indicator distributions, so no malware is stored, committed, or executed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lb5wpChn4hHTRMNcRmBNpB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a machine-learning classifier that complements SafeInstall's hand-written static rules with a learned second opinion. A
RandomForestweighs 57 behavioral features of an installer script together and returns a calibratedp(malicious); when it crosses the model threshold it becomes an ML Model finding that feeds the same energy-based risk score.The model is trained offline and exported to pure Rust (
src/ml_model.rs) viam2cgen, so inference at runtime needs no Python, no network, and no model file. Python and the exported Rust agree onp(malicious)to within4.6e-11.What's included
src/features.rs— 57-feature extractor: the 10 static-rule hits as 0/1 features, plus entropy, line statistics, URL/IP counts, base64 density, 23 obfuscation and behavioral indicators (reverse shell, PowerShell cradles, credential access, anti-forensics, mining, exfiltration, …), and installer-kind one-hots. Counts are stored asln(1+n). Exposed through a hiddensafe features <file> --jsonsubcommand so the training pipeline and the shipped binary compute an identical representation (enforced by tests).src/ml.rs+src/ml_model.rs— inference and theML Modelfinding, wired intoinspect/runright afteranalyzer::analyze()beforerecalculate().ml_model.rsis generated bym2cgen.src/cli.rs/src/main.rs—--no-mlflag to skip the classifier; ML probability added to JSON output.src/source.rs— inspect local script files, not just URLs (needed for feature extraction and offline use).ml/— reproducible pipeline (fetch_benign.py→build_dataset.py→train.py), a notebook (train.ipynb), figures (confusion matrix, ROC, SHAP), and screenshots.data/features.csvand metrics are committed; the raw script corpus is git-ignored.Results (held-out test set, threshold 0.53)
RandomForest and GradientBoosting were compared; GB scored marginally higher (F1 0.985 vs 0.974 at threshold 0.5) but only RandomForest exports to dependency-free Rust via m2cgen, so it is the deployed model.
Data & safety
The benign class is features of real installer scripts (rustup, nvm, bun, Deno, Homebrew, Docker, Helm, pyenv, Starship, poetry, Tailscale, and dozens more, plus local system scripts). The malicious class is synthesized in feature space from documented MITRE ATT&CK indicator distributions, layered onto structural features borrowed from real benign scripts. No malware is stored, committed, or executed anywhere in this repository. The synthetic positive class is a stated limitation (metrics measure separability of the modeled attack distribution); swapping in a vetted real-malware feature corpus is the primary future-work item and changes nothing about the feature contract or the Rust export. Full methodology in
ml/README.md.Testing
cargo test— 37 tests pass (feature extraction, inference thresholds, the Python↔Rust feature-order contract, benign-not-flagged / dense-indicator-flagged integration cases).cargo build --release— clean, no warnings.🤖 Generated with Claude Code
https://claude.ai/code/session_01Lb5wpChn4hHTRMNcRmBNpB
Generated by Claude Code