A standalone, open-source webshell detection tool supporting PHP, JSP, ASP.NET, and Python.
Extracted from XPAV to be a focused, single-purpose tool.
- Multi-language support: PHP, JSP, ASP.NET, Python (20+ file extensions)
- Multiple detection methods:
- Input-to-eval chains (user input → code execution)
- Decode chains (base64, gzinflate, rot13 obfuscation)
- Known signatures (c99, r57, b374k, WSO, China Chopper, Weevely)
- Suspicious function detection
- Dynamic execution patterns
- Obfuscation scoring
- Context-aware scanning: Reduces false positives in frameworks (WordPress, Laravel, Symfony, Drupal) and vendor directories
- Multiple output formats: Text, JSON, JSONL
- Library + CLI: Use as a Rust library or command-line tool
git clone https://github.com/JNC4/webshell-scanner
cd webshell-scanner
cargo install --path .[dependencies]
webshell-scanner = "0.1"# Scan a single file
webshell-scanner suspicious.php
# Scan a directory recursively
webshell-scanner -r /var/www/html
# Scan with context-awareness (reduces false positives)
webshell-scanner -r -c /var/www/wordpress
# Output as JSON
webshell-scanner -f json /var/www/html
# Pipe content via stdin
cat suspicious.php | webshell-scanner --stdin --language php
# Quiet mode (exit code 1 if malicious found)
webshell-scanner -q /var/www/html && echo "Clean" || echo "Infected"Usage: webshell-scanner [OPTIONS] [PATHS]...
Arguments:
[PATHS]... Files or directories to scan
Options:
-f, --format <FORMAT> Output format [default: text] [possible values: text, json, jsonl]
-t, --threshold <THRESHOLD> Obfuscation threshold [default: 50]
-r, --recursive Scan recursively
-c, --context-aware Enable context-aware scanning (reduces false positives)
--show-clean Show clean files in output
-q, --quiet Only show malicious files (exit code 1 if any found)
--stdin Read content from stdin (use with --language)
--language <LANGUAGE> Language for stdin input [possible values: php, jsp, asp, python]
-h, --help Print help
-V, --version Print version
use webshell_scanner::{WebshellScanner, ThreatLevel, ScanContext};
// Create scanner with obfuscation threshold
let scanner = WebshellScanner::new(50);
// Basic scan
let result = scanner.scan(r#"<?php eval($_GET['cmd']); ?>"#);
assert!(result.is_malicious);
assert_eq!(result.threat_level, ThreatLevel::Malicious);
// Language-specific scan
let result = scanner.scan_jsp(r#"<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>"#);
assert!(result.is_malicious);
// Context-aware scan (reduces false positives in frameworks)
let context = ScanContext::from_path(std::path::Path::new("/var/www/vendor/lib.php"));
let result = scanner.scan_with_context(content, &context);| Category | Description |
|---|---|
| InputEvalChain | User input ($_GET, $_POST, etc.) flowing to code execution |
| DecodeChain | Obfuscated payloads (base64 → eval, gzinflate chains) |
| KnownSignature | Known webshell signatures (c99, r57, b374k, WSO, etc.) |
| SuspiciousFunction | Dangerous functions without direct user input chain |
| DynamicExecution | Evasion via string concatenation, variable variables, chr() chains |
| Obfuscation | High obfuscation score indicating packed/encoded code |
.php, .phtml, .php3, .php4, .php5, .php7, .phps, .phar, .inc
.jsp, .jspx, .jspa, .jsw, .jsv
.aspx, .ashx, .asmx, .ascx, .asp
.py, .pyw
When enabled (-c flag), the scanner automatically:
- Detects frameworks: WordPress, Laravel, Symfony, Drupal, Composer
- Adjusts thresholds for vendor directories (
/vendor/,/node_modules/) - Handles cache directories with higher thresholds
- Recognizes minified code to avoid false positives
0: No malicious files found1: One or more malicious files detected
Contributions welcome. Please open an issue or PR on GitHub.
MIT License - see LICENSE for details.
Originally developed as part of XPAV by REIUK LTD.