Skip to content

Commit d6e5dea

Browse files
Merge pull request #1 from sysangels/dev
plugin malware-scan
2 parents 63de9b9 + 4820f99 commit d6e5dea

40 files changed

Lines changed: 22591 additions & 0 deletions

malware-scan/GDPR.md

Lines changed: 916 additions & 0 deletions
Large diffs are not rendered by default.

malware-scan/README.md

Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
# BunkerWeb Malware Scan Plugin
2+
3+
**Version**: 0.8.0 | **Status**: Production Ready | **Release**: 2026-01-27
4+
5+
Multi-layer malware scanning plugin for BunkerWeb with advanced caching, webhook notifications, and modular architecture.
6+
7+
## ✨ Key Features
8+
9+
- **🛡️ Multi-layer scanning**: ClamAV (local) + VirusTotal + SentinelOne (cloud)
10+
- **⚡ Smart caching**: SHA256-based result caching with differential TTL (clean: 5min, malicious: 24h, max 7d, configurable)
11+
- **📢 Webhook notifications**: Real-time alerts to Discord and Microsoft Teams
12+
- **🔧 Modular architecture**: 21 specialized modules for maintainability
13+
- **🌐 Cluster-ready**: Works correctly on manager and worker nodes
14+
15+
## ⚡ Performance Metrics (v0.8.0)
16+
17+
| Metric | Result | Details |
18+
|--------|--------|---------|
19+
| **First scan (cache miss)** | ~4 seconds | Full ClamAV INSTREAM scan |
20+
| **Repeat scan (cache hit)** | ~1 second | 75% faster - hash calculation + cache lookup |
21+
| **Code maintainability** | 21 modules | Specialized components for scanning, caching, APIs |
22+
| **Webhook delivery** | Real-time | Discord & Microsoft Teams notifications |
23+
| **Module initialization** | 100% | All 21 modules load successfully |
24+
25+
## 🎯 Real-World Examples
26+
27+
### Example 1: First Upload (Cache Miss) - Full Scan
28+
29+
Uploading EICAR test file for the first time:
30+
31+
```log
32+
[MALWARE-SCAN] file upload detected, scanning for malware
33+
[MALWARE-SCAN] file SHA256: 2546dcffc5ad854d4ddc64fbf056871cd5a00f2471cb7a5bfd4ac23b6e9eedad
34+
[CACHE] ClamAV local cache MISS for checksum: 2546dcffc5ad854d...
35+
36+
# Full ClamAV INSTREAM scan performed
37+
[MALWARE-SCAN] scanning file via INSTREAM
38+
[MALWARE-SCAN] INSTREAM: Read chunk 1, size: 703
39+
[MALWARE-SCAN] INSTREAM: All chunks sent - 1 chunks, 703 bytes total
40+
clamd[922]: instream(127.0.0.1@34668): Eicar-Test-Signature FOUND
41+
42+
# Detection and caching
43+
[MALWARE-SCAN] MALWARE DETECTED BY CLAMAV
44+
[MALWARE-SCAN] ClamAV signature: Eicar-Test-Signature
45+
[CACHE] Added ClamAV result to cache: 2546dcffc5ad854d... = Eicar-Test-Signature (TTL: 7776000s)
46+
47+
# Webhook notification
48+
[WEBHOOK] Processing Discord webhook
49+
[WEBHOOK] Cleaned URL: https://discord.co***
50+
51+
# Request blocked
52+
POST /wp-admin/async-upload.php HTTP/3.0" 403 (4 seconds total)
53+
```
54+
55+
**Timeline**: 4 seconds (file buffering + ClamAV scan + webhook)
56+
57+
---
58+
59+
### Example 2: Second Upload (Cache Hit) - Instant Block
60+
61+
Uploading the same EICAR file again within 90 days:
62+
63+
```log
64+
[MALWARE-SCAN] file upload detected, scanning for malware
65+
[MALWARE-SCAN] file SHA256: 2546dcffc5ad854d4ddc64fbf056871cd5a00f2471cb7a5bfd4ac23b6e9eedad
66+
[CACHE] ClamAV local cache HIT for checksum: 2546dcffc5ad854d...
67+
68+
# Cache hit - no ClamAV scan needed!
69+
[CACHE_HIT] ClamAV cache shows malicious - skipping ClamAV scan
70+
[MALWARE DETECTED BY CLAMAV (cached)]
71+
[MALWARE-SCAN] ClamAV signature: Eicar-Test-Signature (SHA256: 2546dcffc5ad854d...)
72+
73+
# Webhook notification (still fires)
74+
[WEBHOOK] Processing Discord webhook
75+
[WEBHOOK] Cleaned URL: https://discord.co***
76+
77+
# Request blocked instantly
78+
POST /wp-admin/async-upload.php HTTP/3.0" 403 (1 second total)
79+
```
80+
81+
**Timeline**: 1 second (hash calculation + cache lookup + webhook) - **75% faster!**
82+
83+
---
84+
85+
### Example 3: Multi-Layer Mode with Cloud Scanners
86+
87+
Configuration: `MALWARE_SCAN_SKIP_OTHERS_ON_CLAMAV_DETECT=no`
88+
89+
```log
90+
# ClamAV detects malware
91+
[MALWARE-SCAN] MALWARE DETECTED BY CLAMAV
92+
[MALWARE-SCAN] ClamAV signature: Eicar-Test-Signature
93+
94+
# Continue to cloud scanners for additional intelligence
95+
[MALWARE-SCAN] ClamAV detected malware, continuing to VirusTotal for additional analysis
96+
[MALWARE-SCAN] calculated SHA256: 2546dcffc5ad854d4ddc64fbf056871cd5a00f2471cb7a5bfd4ac23b6e9eedad
97+
98+
# VirusTotal confirmation
99+
[MALWARE-SCAN] checking file against VirusTotal API
100+
[MALWARE-SCAN] file checksum found in VT cache: 0 suspicious and 61 malicious
101+
102+
# Dual confirmation
103+
[MALWARE-SCAN] MALWARE DETECTED BY VIRUSTOTAL - BLOCKING REQUEST
104+
[MALWARE-SCAN] VirusTotal detection: 61 malicious engines confirmed
105+
106+
# Webhook with multiple detections
107+
[WEBHOOK] Processing Discord webhook
108+
Scanner: ClamAV → Eicar-Test-Signature
109+
Scanner: VirusTotal → 61/61 engines detected malware
110+
111+
POST /wp-admin/async-upload.php HTTP/3.0" 403
112+
```
113+
114+
**Benefits**:
115+
- ✅ Dual confirmation from multiple sources
116+
- ✅ Rich threat intelligence
117+
- ✅ Lower false positive rate
118+
- ✅ Better for security research
119+
120+
---
121+
122+
### Comparison: Fast vs Full Mode
123+
124+
| Feature | Fast Mode (default) | Full Multi-Layer Mode |
125+
|---------|--------------------|-----------------------|
126+
| **Config** | `SKIP_OTHERS_ON_CLAMAV_DETECT=yes` | `SKIP_OTHERS_ON_CLAMAV_DETECT=no` |
127+
| **ClamAV scan** | ✅ Always | ✅ Always |
128+
| **Cache check** | ✅ Before ClamAV | ✅ Before ClamAV |
129+
| **Cloud scanners** | Only if ClamAV clean | Always (additional intelligence) |
130+
| **Response time** | ~1s cached, ~4s uncached | ~1s cached, ~5s uncached |
131+
| **Detection sources** | Single (ClamAV) | Multiple (ClamAV + VT + TF + S1) |
132+
| **API quota usage** | Lower | Higher |
133+
| **Best for** | Production speed | Security research |
134+
135+
## 📥 Installation
136+
137+
### Option 1: Docker ClamAV (Recommended for New Deployments)
138+
139+
For production environments, use the automated Docker installation script for ClamAV:
140+
141+
```bash
142+
# Supports: Debian 11+, Ubuntu 20.04+, CentOS 7+, Rocky 8+, AlmaLinux 8+, Fedora 33+
143+
sudo ./install-docker-clamav.sh
144+
145+
# Container runs on port 3310 with 4GB memory limit
146+
# Signature updates: Every 2 hours (12 checks per day)
147+
# Logging: JSON-file (docker logs clamav)
148+
```
149+
150+
**Features:**
151+
- ✅ Automatic OS detection (Debian/CentOS)
152+
- ✅ Auto-start on reboot (systemd service)
153+
- ✅ 24/7 availability (concurrent database reload)
154+
- ✅ Comprehensive troubleshooting guides included
155+
156+
See [install-docker-clamav.md](install-docker-clamav.md) for detailed instructions.
157+
158+
### Option 2: Plugin Installation
159+
160+
```bash
161+
# Clone the repository
162+
git clone https://github.com/bunkerity/bunkerweb-plugins.git
163+
cd bunkerweb-plugins/malware-scan
164+
165+
# Deploy files
166+
sudo cp *.lua plugin.json /etc/bunkerweb/plugins/malware-scan/
167+
sudo chmod 644 /etc/bunkerweb/plugins/malware-scan/*
168+
169+
# Restart BunkerWeb
170+
sudo systemctl restart bunkerweb
171+
```
172+
173+
### Verification
174+
175+
Check that all modules loaded successfully:
176+
177+
```bash
178+
journalctl -u bunkerweb -n 50 | grep -i "malware-scan"
179+
```
180+
181+
Expected output:
182+
```
183+
[MALWARE-SCAN] cache module loaded successfully
184+
[MALWARE-SCAN] file_ops module loaded successfully
185+
[MALWARE-SCAN] clamav module loaded successfully
186+
[MALWARE-SCAN] virustotal module loaded successfully
187+
[MALWARE-SCAN] sentinelone module loaded successfully
188+
[MALWARE-SCAN] webhook module loaded successfully
189+
```
190+
191+
### ClamAV Debugging
192+
193+
The install script automatically enables ClamAV debugging for detailed scanning logs. To manually enable or check:
194+
195+
```bash
196+
# Check current ClamAV configuration
197+
grep -E "^(LogVerbose|Debug|LogClean)" /etc/clamav/clamd.conf
198+
199+
# Enable debugging (if not already enabled)
200+
sudo sed -i 's/^LogVerbose false/LogVerbose true/' /etc/clamav/clamd.conf
201+
sudo sed -i 's/^Debug false/Debug true/' /etc/clamav/clamd.conf
202+
sudo sed -i 's/^LogClean false/LogClean true/' /etc/clamav/clamd.conf
203+
sudo systemctl restart clamav-daemon
204+
205+
# View ClamAV logs
206+
sudo tail -f /var/log/clamav/clamav.log
207+
208+
# View BunkerWeb malware-scan logs
209+
sudo journalctl -u bunkerweb -f | grep MALWARE
210+
```
211+
212+
**What you'll see with debugging enabled:**
213+
- `LogVerbose`: Detailed information about each scan (file paths, scan methods)
214+
- `Debug`: Daemon-level debugging (connections, protocol details)
215+
- `LogClean`: Logs for clean files (not just infected ones)
216+
217+
## ⚙️ Configuration
218+
219+
Edit `/etc/bunkerweb/variables.env`:
220+
221+
### Core Settings
222+
223+
```bash
224+
USE_MALWARE-SCAN=yes # Enable malware scanning
225+
MALWARE_SCAN_DEBUG=no # Debug logging (disable in production)
226+
```
227+
228+
### ClamAV (Local Scanning)
229+
230+
```bash
231+
MALWARE_SCAN_CLAMAV_HOST=127.0.0.1 # ClamAV daemon host
232+
MALWARE_SCAN_CLAMAV_PORT=3310 # ClamAV daemon port
233+
MALWARE_SCAN_CLAMAV_TIMEOUT=10000 # Connection timeout (ms)
234+
MALWARE_SCAN_CLAMAV_MAX_SIZE=26214400 # Max file size (25MB)
235+
```
236+
237+
### Multi-Layer Scanning
238+
239+
```bash
240+
MALWARE_SCAN_SKIP_OTHERS_ON_CLAMAV_DETECT=yes # Fast mode (skip cloud on ClamAV hit)
241+
MALWARE_SCAN_RESUME_SCAN_ON_FIRST_HIT=no # WARNING: DOS risk! Continue scanning after first detection
242+
MALWARE_SCAN_SCAN_FULL_MULTIPART_BODY=no # Skip full multipart body scan (recommended - see note below)
243+
MALWARE_SCAN_HASH_MAX_SIZE=67108864 # Max file size for hash scanning (64MB)
244+
```
245+
246+
**Note on SCAN_FULL_MULTIPART_BODY**:
247+
248+
By default (`no`), the plugin skips scanning the entire multipart request body and only scans extracted individual files. This is **recommended** because:
249+
- HTTP multipart boundaries contain random strings that change on every upload
250+
- Full body SHA256 is different each time, making caching completely ineffective
251+
- Individual file extraction provides consistent SHA256s for reliable caching
252+
- Wastes ClamAV resources scanning the same files repeatedly
253+
254+
Only enable (`yes`) if you suspect malware might be split across multipart boundaries (extremely rare).
255+
256+
**Note on RESUME_SCAN_ON_FIRST_HIT**:
257+
258+
The plugin performs **dual scanning** for comprehensive malware detection:
259+
1. **Full-body scan** (optional): Scans entire multipart upload - disabled by default (see SCAN_FULL_MULTIPART_BODY above)
260+
2. **Per-file scan** (when resume enabled): Parses multipart data and scans each uploaded file individually
261+
262+
When `RESUME_SCAN_ON_FIRST_HIT=yes`:
263+
- All scanners complete even after detection (comprehensive threat intelligence)
264+
- Continues to next file after detecting malware in one file
265+
- Aggregates detections from whole-body + all individual files before blocking
266+
267+
When `RESUME_SCAN_ON_FIRST_HIT=no` (default):
268+
- Blocks immediately on first detection (fast response, minimal resources)
269+
270+
**DOS Risk**: Attackers can force expensive operations (multiple file scans, API calls) even after detection. Only enable for security research or when you need complete visibility into multi-file attacks.
271+
272+
### VirusTotal (70+ AV Engines)
273+
274+
```bash
275+
MALWARE_SCAN_API_USE_VIRUSTOTAL=yes # Enable VirusTotal
276+
MALWARE_SCAN_API_VIRUSTOTAL_KEY=your_api_key # API key (required)
277+
MALWARE_SCAN_API_VIRUSTOTAL_SUSPICIOUS=5 # Suspicious threshold
278+
MALWARE_SCAN_API_VIRUSTOTAL_MALICIOUS=3 # Malicious threshold
279+
MALWARE_SCAN_API_VIRUSTOTAL_UPLOAD_UNKNOWN=yes # Upload unknown malware
280+
MALWARE_SCAN_API_VIRUSTOTAL_AUTO_VOTE=yes # Auto-vote on uploads
281+
MALWARE_SCAN_API_VIRUSTOTAL_MAX_UPLOAD_SIZE=33554432 # Max upload size (32MB)
282+
```
283+
284+
### SentinelOne (Enterprise)
285+
286+
```bash
287+
MALWARE_SCAN_API_USE_SENTINELONE=yes # Enable SentinelOne
288+
MALWARE_SCAN_API_SENTINELONE_URL=https://... # Console URL
289+
MALWARE_SCAN_API_SENTINELONE_TOKEN=your_token # API token
290+
```
291+
292+
### Webhooks (Discord & Teams)
293+
294+
```bash
295+
MALWARE_SCAN_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
296+
MALWARE_SCAN_TEAMS_WEBHOOK_URL=https://outlook.office.com/webhook/...
297+
```
298+
299+
### False Positive Handling
300+
301+
```bash
302+
MALWARE_SCAN_ALLOWLIST_HASHES=sha256_hash1,sha256_hash2 # Comma-separated hashes
303+
MALWARE_SCAN_ALLOWLIST_FILE=/path/to/allowlist.txt # File with hashes (one per line)
304+
```
305+
306+
### Cleanup
307+
308+
```bash
309+
MALWARE_SCAN_CLEANUP_FILES=yes # Delete temp files after scan
310+
MALWARE_SCAN_CLEANUP_ORPHANED=yes # Clean up old orphaned files
311+
MALWARE_SCAN_CLEANUP_AGE=3600 # Max age for orphaned files (seconds)
312+
```
313+
314+
## 🧪 Testing
315+
316+
### Test with EICAR File
317+
318+
```bash
319+
# Download EICAR standard test file
320+
curl -o eicar.txt https://secure.eicar.org/eicar.com.txt
321+
322+
# Upload through your web application
323+
# Example: WordPress media uploader
324+
```
325+
326+
Expected result:
327+
```
328+
HTTP 403 Forbidden
329+
malware detected by ClamAV: Eicar-Test-Signature
330+
```
331+
332+
### Test Caching
333+
334+
1. Upload EICAR file - should take ~4 seconds (full scan)
335+
2. Upload same file again - should take ~1 second (cache hit)
336+
3. Check logs for `[CACHE_HIT]` messages
337+
338+
## 📋 API Rate Limits
339+
340+
### VirusTotal Public API
341+
- **Rate limits**: 4 requests/minute, 500 requests/day
342+
- **Free tier**: https://www.virustotal.com/gui/join-us
343+
- **Premium**: Unlimited requests
344+
345+
### SentinelOne API
346+
- **Rate limits**: 10 req/sec (50 burst)
347+
- **License**: Requires SentinelOne subscription
348+
349+
## 📚 Documentation
350+
351+
- **[install-docker-clamav.md](install-docker-clamav.md)** - **NEW!** Automated Docker ClamAV setup (Debian & CentOS)
352+
- **[install-docker-clamav.sh](install-docker-clamav.sh)** - Deployment script with OS auto-detection
353+
- **[install.md](install.md)** - Detailed installation guide
354+
- **[TECHNICAL.md](TECHNICAL.md)** - Architecture, security features, development details
355+
- **[GDPR.md](GDPR.md)** - GDPR compliance guide with privacy policy template
356+
- **[SECURITY.md](SECURITY.md)** - Vulnerability reporting and security policy
357+
- **[all-features-enabled.md](all-features-enabled.md)** - Complete configuration with all scanners
358+
- **[variables.env.example](variables.env.example)** - Complete configuration reference
359+
- **[ALLOWLIST.md](ALLOWLIST.md)** - False positive handling with SHA256 allowlists
360+
- **[GRANULAR_CACHE_CLEANUP.md](GRANULAR_CACHE_CLEANUP.md)** - Per-scanner cache cleanup configuration
361+
362+
## 🔒 Security
363+
364+
### Security Best Practices
365+
366+
- Keep ClamAV signatures updated: `sudo freshclam`
367+
- Use default settings: `BLOCK_ON_FILENAME_INJECTION_ATTACK=yes`
368+
- Avoid `RESUME_SCAN_ON_FIRST_HIT=yes` in production (DOS risk)
369+
- Store API keys in environment variables, never commit to git
370+
- Review logs regularly for attack patterns
371+
372+
### Reporting Vulnerabilities
373+
374+
See [SECURITY.md](SECURITY.md) for vulnerability disclosure policy and security contacts.
375+
376+
## 💬 Support
377+
378+
- **Documentation**: [docs.bunkerweb.io](https://docs.bunkerweb.io/)
379+
- **Issues**: Check logs first: `journalctl -u bunkerweb`
380+
- **ClamAV**: [docs.clamav.net](https://docs.clamav.net/)
381+
- **Security**: [SECURITY.md](SECURITY.md)
382+
383+
## 📜 License
384+
385+
This plugin is part of the BunkerWeb project.
386+
387+
---
388+
389+
**User-Agent**: API requests include version: `bunkerweb - https://github.com/bunkerity/bunkerweb - malware-scan module v0.8.0`

0 commit comments

Comments
 (0)