病毒分析
点击放大

<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="assets/banner-light.svg">
<img alt="Linux Malware Detect" src="assets/banner-dark.svg" width="830">
</picture>
</p>
<p align="center">
<a href=" src=" alt="CI"></a>
<a href="CHANGELOG"><img src=" alt=""></a>
<a href="COPYING.GPL"><img src=" alt="License: GPL v2"></a>
<a href="#1-introduction"><img src=" alt="Platform: Linux"></a>
</p>
Malware scanner for Linux — multi-stage threat detection (MD5, SHA-256, HEX, YARA,
statistical analysis), ClamA, real-time inotify monitoring,
quarantine/clean/restore operations, and multi-channel alerting (email, Slack,
Discord).
> (C) 2002-2026, R-fx Networks <><br>
> (C) 2026, Ryan MacDonald <><br>
> Licensed under GNU GPL v2
---
43x faster native scan engine — the nati pipeline has been completely
rewritten with batch parallel processing. Real-world benchmark on ~10,000 files:
| | Runtime | Files | Hits |
|---------|---------|-------|------|
| v1.6.6 | 1,217s | 9,931 | 35 |
| v2.0.1 | 28s | 9,931 | 35 |
MD5 and HEX signature matching now use batch grep with Aho-Corasick parallel workers,
eliminating per-file pattern compilation o and ~500,000 subprocess forks per scan.
Configure parallel worker count with scan_workers (default: auto).
Other highlights: scan lifecycle management (--kill, --pause, --stop/--continue,-L), SHA-256 hash scanning with CPU hardware auto-detection (scan_hashtype),
native YARA scanning (scan_yara=1), Discord webhook alerting, Slack/
fixes, ClamAV hex wildcard support in the nati, and 200+ bug fixes across the
codebase.
See CHANGELOG for full details.
---
---
---
LMD's architecture, detection stages, and supported platforms.
Linux Malware Detect (LMD) is a malware scanner for Linux released under the GNU GPLv2 license, designed around the threats faced in shared hosted en. It uses threat data from network edge intrusion detection systems to extract malware that is actively being used in attacks and generates signatures for detection. In addition, threat data is derived from user submissions with the LMD checkout feature and from malware community resources.
LMD focuses on the malware classes that traditional A frequently miss: PHP shells, Ja injectors, base64-encoded backdoors, IRC bots, and other web-application-layer threats that target shared hosting user accounts rather than operating system internals.
Detection Stages
Scanning & Monitoring
inspectFile hookQuarantine & Response
Alerting & Reporting
alert/custom.d/ oInfrastructure
LMD runs on any Linux distribution with bash and standard GNU utilities. Tested platforms:
| Platform | Init System | Package Config Path |
|----------|-------------|---------------------|
| RHEL / Rocky / AlmaLinux 8, 9, 10 | systemd | /etc/sysconfig/maldet |
| CentOS 6, 7 | Sys | /etc/sysconfig/maldet |
| Debian 10, 11, 12 | systemd | /etc/default/maldet |
| Ubuntu 20.04, 22.04, 24.04 | systemd | /etc/default/maldet |
| Gentoo | OpenRC | — |
| Slackware | SysV | — |
| FreeBSD | — | — (partial; no inotify) |
---
Installing, upgrading, and removing LMD from a system.
The included install.sh script handles all installation tasks. Previous installations are automatically backed up.
The installer:
/usr/local/maldetectmaldet symlink in /usr/local/sbin//etc/cron.daily/maldetconf.maldet), custom signatures, and ignore files across upgradesPrevious installs are saved to /usr/local/maldetect.bk{PID} with a maldetect.last symlink to the most recent backup.
Default paths:
/usr/local/maldetect/usr/local/sbin/maldet/etc/cron.daily/maldet/usr/lib/systemd/system/maldet.service---
All user-facing settings and their defaults. See man maldet(1) for the complete reference.
The main configuration file is /usr/local/maldetect/conf.maldet. All options are commented for ease of configuration. Options use 0/1 for disable/enable unless otherwise noted.
Configuration can also be o at runtime using the -co flag:
| | Purpose | Default |
|----------|---------|---------|
| autoupdate_signatures | Auto-update signatures daily via cron | 1 |
| autoupdate_ | Auto-update LMD daily via cron | 1 |
| autoupdate_ | LMD executable SHA-256 hash against upstream (falls back to MD5) | 1 |
| sigup_interval | Hours between automatic signature update checks cron job (/etc/cron.d/maldet-sigup); 0 = disabled | 6 |
| cron_prune_days | Days to retain quarantine/session/temp data | 21 |
| cron_daily_scan | Enable daily automatic scanning via cron | 1 |
| scan_days | Days to look back for modified files in daily cron scans | 1 |
| import_config_url | URL to download remote configuration o | — |
| import_config_expire | Cache expiry for imported config (seconds) | 43200 |
| sig_import_md5_url | URL to download custom MD5 signatures | — |
| sig_import_hex_url | URL to download custom HEX signatures | — |
| sig_import_yara_url | URL to download custom YARA rules | — |
| sig_import_sha256_url | URL to download custom SHA-256 signatures | — |
| sig_import_csig_url | URL to download custom compound signatures | — |
| session_legacy_compat | Generate legacy plaintext session files alongside TSV: auto (detect old-format sessions), 1 (always), 0 (TSV only) | auto |
| | Purpose | Default |
|----------|---------|---------|
| email_alert | Enable email alerts after scans | 0 |
| email_addr | Alert recipient address | |
| email_subj | Email subject line template | maldet alert from $(hostname) |
| email_ignore_clean | Suppress alerts when all hits were cleaned | 1 |
| email_panel_user_alerts | Send panel user alerts on hit detection | 0 |
| email_panel_from | From header for panel user alerts | |
| email_panel_replyto | Reply-To header for panel user alerts | |
| email_panel_alert_subj | Subject line for panel user alerts | maldet alert from $(hostname) |
| email_format | Email format: text, html, or both | html |
| smtp_relay | SMTP relay URL (e.g., smtps://smtp.gmail.com:465) | — |
| smtp_from | Sender address for SMTP relay delivery | — |
| smtp_user | SMTP authentication username | — |
| smtp_pass | SMTP authentication password | — |
| slack_alert | Enable Slack file upload alerts | 0 |
| slack_subj | File name for Slack upload | maldet alert from $(hostname) |
| slack_token | Slack Bot API token (scopes: files:write, files:read) | — |
| slack_channels | Comma-separated list of channel names or IDs | maldetreports |
| | Enable 0 |
| |
| |
| discord_alert | Enable Discord webhook alerts | 0 |
| discord_webhook_url | Discord webhook URL for alert delivery | — |
| | Purpose | Default |
|----------|---------|---------|
| scan_hashtype | Hash algorithm for stage 1: auto, sha256, md5, both | auto |
| scan_max_depth | Maximum directory depth for find | 15 |
| scan_min_filesize | Minimum file size to scan | 24 bytes |
| scan_max_filesize | Maximum file size to scan | 2048k |
| scan_hexdepth | Byte depth for HEX signature matching | 262144 |
| scan_hex_chunk_size | Files per micro-batch in HEX+CSIG scanning (range: 1024-20480) | 10240 |
| scan_csig | Enable compound signature (csig) scanning (native mode only) | 1 |
| scan_workers | Parallel workers for MD5, SHA-256, HEX, and CSIG scan passes | auto |
| scan_cpunice | Nice priority for scan process (-19 to 19) | 19 |
| scan_ionice | IO scheduling class priority (0-7) | 6 |
| scan_cpulimit | Hard CPU limit percentage (0=disabled) | 0 |
| scan_ignore_root | Skip root-owned files in scans (not applied in monitor mode by default; see monitor_scan_owner_filters) | 1 |
| scan_ignore_user | Skip files owned by specific users | — |
| scan_ignore_group | Skip files owned by specific groups | — |
| scan_user_access | Allow non-root users to run scans | 0 |
| scan_user_access_minuid | Minimum UID for --mkpubpaths user directory creation | 100 |
| scan_find_timeout | Timeout for find file list generation (0=disabled, min 60s, 14400=4hr recommended) | 0 |
| scan_export_filelist | Save find results to tmp/find_results.last | 0 |
| scan_tmpdir_paths | World-writable temp paths included in -a/-r scans | /tmp /var/tmp /dev/shm / |
| string_length_scan | Enable statistical string-length analysis | 0 |
| string_length | Minimum suspicious string length | 150000 |
| scan_progress_log_interval | Seconds between progress log checkpoints during background scans (0=disabled) | 60 |
| scan_meta_cleanup_age | Hours to retain completed/killed scan meta files (0=disabled) | 48 |
| maint_compress_age | Days before completed session files are gzipped (0=disabled) | 30 |
| maint_archi | Days before compressed sessions are bundled into monthly archives (0=disabled) | 90 |
Native YARA scanning invokes the yara binary (or yr from YARA-X) independently of ClamA full YARA modules, compiled rules, and custom rule files that ClamAV's limited YARA subset cannot handle. When both are a, yr (YARA-X) is preferred. When set to auto, native YARA is enabled only when ClamAV is una and a yara/yr binary is found, pre duplicate rule e.
| | Purpose | Default |
|----------|---------|---------|
| scan_yara | Enable native YARA scan stage: auto (detect binary, ClamA), 0 (disabled), 1 (enabled) | auto |
| scan_yara_timeout | Timeout in seconds (0=no timeout) | 300 |
| scan_yara_scope | Rule scope when ClamAV is also active: all (full native scan) or custom (only custom rules natively, ClamA rfxn.yara) | custom |
| sig_import_yara_url | URL to download custom YARA rules on signature update | — |
Custom YARA rules can be placed in two locations, both preser upgrades:
sigs/custom.yara — single-file rulessigs/custom.yara.d/ — drop-in directory for .yar and .yara rule filesCompatible with third-party rule sets such as YARA Forge and Signature Base. Compiled rules (yarac output) are also supported via sigs/compiled.yarc.
Batch scanning: YARA 4.0+ and all YARA-X use --scan-list for efficient batch file scanning. Older YARA fall back to per-file scanning automatically.
Enable at runtime without editing config:
| | Purpose | Default |
|----------|---------|---------|
| quarantine_hits | Automatically quarantine detected malware | 0 |
| quarantine_clean | Try to clean malware from quarantined files | 0 |
| quarantine_suspend_user | Suspend cPanel account or revoke shell on hit | 0 |
| quarantine_suspend_user_minuid | Minimum UID to suspend (protects system accounts) | 500 |
| quarantine_on_error | Quarantine files when scan engine returns error | 1 |
| | Purpose | Default |
|----------|---------|---------|
| default_monitor_mode | Startup mode for monitor (users or path to file); empty = disabled | "" |
| inotify_base_watches | Base number of file watches per user path | 16384 |
| inotify_minuid | Minimum UID for user home monitoring | 500 |
| inotify_docroot | Subdirectories to monitor in user homes | public_html,public_ftp |
| inotify_sleep | Seconds between scan batches | 15 |
| inotify_reloadtime | Seconds between config reloads | 3600 |
| inotify_cpunice | Nice priority for monitor process | 18 |
| inotify_ionice | IO priority for monitor process | 6 |
| inotify_cpulimit | Hard CPU limit for monitor (0=disabled) | 0 |
| digest_interval | Inter periodic digest summary alerts: 24h, 30m, 7d, 0 (disabled) | 24h |
| digest_escalate_hits | Hit count threshold for immediate escalation alert; 0 = disabled | 0 |
| cron_digest_hook | Enable cron.daily hook digest sweep (fires digest if new hook detections exist) | 1 |
| monitor_paths_extra | Path to a line-separated file of additional inotify watch paths | /usr/local/maldetect/monitor_paths.extra |
| monitor_scan_owner_filters | Apply scan_ignore_root/scan_ignore_user/scan_ignore_group ownership filters in monitor mode; 0 (default) = off — monitor scans all files regardless of owner (restores 1.6.6 semantics, fixes issue #485); 1 = on — apply ownership filters | 0 |
A configurable hook script can be invoked after scan completion, receiving
scan results arguments, LMD_* en , and
optionally JSON on stdin. The hook ne scanning — failures are
logged, not fatal. See maldet(1) for the full hook contract.
| | Purpose | Default |
|----------|---------|---------|
| post_scan_hook | Path to hook script (root-owned, not world-writable). Cannot be set via -co | "" |
| post_scan_hook_format | Output tier: args, file, json (cumulative) | args |
| post_scan_hook_exec | Execution mode: async (non-blocking), sync (wait) | async |
| post_scan_hook_timeout | Seconds before SIGTERM (0=disabled, min 5) | 60 |
| post_scan_hook_on | Scan type filter: all, cli, digest | all |
| post_scan_hook_min_hits | Minimum hits to fire (0=always) | 1 |
When ClamA is enabled (scan_clamscan=1 or auto with a detected binary), LMD selects the best a ClamA in priority order:
1. Remote clamdscan (if scan_clamd_remote=1 and config exists)
2. Local clamd daemon running as root
3. Local clamd daemon running as non-root (with --fdpass)
4. clamscan binary (fallback, slower)
LMD signatures are automatically symlinked to ClamAV data directories by install.sh, giving ClamA to LMD's MD5 (rfxn.hdb), HEX (rfxn.ndb), and YARA (rfxn.yara) signatures.
Signature gate: Before deploying updated signatures to ClamAV data directories, LMD them via clamscan -d against a staging directory. If fails, existing LMD signatures are removed from the ClamAV path to prevent malformed databases from breaking ClamAV. The SIGUSR2 reload signal to clamd is only sent when at least one ClamAV data directory passes (issue #467).
| | Purpose | Default |
|----------|---------|---------|
| scan_clamscan | Enable ClamAV as scan engine: auto (detect binary at runtime), 0 (disabled), 1 (enabled) | auto |
| | Purpose | Default |
|----------|---------|---------|
| scan_clamd_remote | Use a remote clamd server for scanning | 0 |
| remote_clamd_config | Path to remote clamd config file | /etc/clamd.d/clamd.remote.conf |
| remote_clamd_max_retry | Max retries on remote clamd failure | 5 |
| remote_clamd_retry_sleep | Seconds between retries | 3 |
| | Purpose | Default |
|----------|---------|---------|
| enable_statistic | Enable ELK stack statistics collection | 0 |
| elk_host | TCP host for ELK input | — |
| elk_port | TCP port for ELK input | — |
| elk_index | Elasticsearch index name | — |
Later sources o earlier :
1. internals/internals.conf — internal paths, binary discovery, URL definitions
2. conf.maldet — user-facing configuration
3. internals/compat.conf — deprecated mappings
4. /etc/sysconfig/maldet or /etc/default/maldet — system o
5. CLI -co|--config-option — runtime o
---
Command-line interface, exit codes, and common examples. See man maldet(1) for the complete option reference.
| Code | Meaning |
|------|---------|
| 0 | Success, no malware hits |
| 1 | Error or all scan paths non-existent |
| 2 | Malware hits found |
Examples:
JSON Output: Use --format json -e or --json-report to output structured JSON
(v1.2 schema) with scanner metadata, scan details (path, times, file counts), per-hit
entries with signature name, file path, hit type, owner, permissions, and quarantine
status, plus a summary with per-type breakdowns. Both TSV and legacy plaintext sessions
are supported; legacy sessions include "source": "legacy" and render una
enriched fields (hash, size, owner, etc.) as null.
Long-running scans on large filesystems (1M+ files) can be controlled without kill -9:
Checkpoint resume: --stop writes a checkpoint file recording the scan stage, hit
count, config options, and per-worker progress. --continue the checkpoint,
warns if signatures changed, rebuilds the file list from current filesystem state, restores
prior hits, and resumes scanning from the interrupted stage. HEX workers resume at
chunk granularity (~30s lost work per worker).
Engine support: Nati (HEX/CSIG/hash workers) and standalone clamscan
support all lifecycle operations. Daemon-based ClamAV (clamdscan/clamd) supports--kill only — --pause and --stop are rejected with an error message because
daemon I/O state is opaque and shared with other clients.
---
Excluding paths, file types, and signatures from scans and monitoring.
Four ignore files control what is excluded from scanning:
| File | Format | Purpose |
|------|--------|---------|
| ignore_paths | Line-separated paths | Exclude directories or files from scans |
| ignore_file_ext | Line-separated extensions | Exclude file extensions (.js, .css) |
| ignore_sigs | Line-separated patterns | Skip matching signatures (regex, substring match) |
| ignore_inotify | Line-separated literal paths | Exclude inotify monitoring events |
All ignore files are located under /usr/local/maldetect/.
Examples:
Note: ignore_sigs entries are treated as extended regex patterns and match as substrings. An entry php.shell will suppress php.shell, php.shell.v2, {YARA}php.shell.backdoor, etc. Use ^php\.shell$ for an exact match. The . character matches any character in regex; escape it as \. for a literal dot.
---
Automated daily scanning, data pruning, and signature updates.
The cron job installed at /etc/cron.daily/maldet performs three tasks:
1. Prune quarantine, session, and temp data older than cron_prune_days (default: 21)
2. Update signatures and (when autoupdate_signatures and autoupdate_ are enabled)
3. Scan recently modified files under detected hosting panel paths (within scan_days days, default: 1)
The daily scan auto-detects installed control panels and adjusts scan paths accordingly:
| Panel | Scan Path |
|-------|-----------|
| cPanel | /home?/?/public_html/ (+ addon/subdomain docroots) |
| Plesk | /var/www//?/ |
| DirectAdmin | /home?/?/domains/?/public_html/, /var/www/html/?/ |
| Ensim | /home//?/fst/var/www/html/ |
| ISPConfig | /var/www/clients/?/web?/web, …/subdomains, /var/www |
| | /home/?/public_html/, /home/?/domains/?/public_html/ |
| ISPmanager | /var/www/?/data/, /home/?/data/ |
| Froxlor | //webs/ |
| Bitrix | /home/bitrix/www/, /home/bitrix/ext_www/?/ |
| / HestiaCP | /home/?/web/?/public_html/ (+ public_shtml, tmp, private) |
| DTC | ${conf_hosting_path:-/var/www/sites}/?/?/subdomains/?/html/ |
If monitor mode is acti scans are skipped and a daily report of monitoring events is issued instead.
For custom scan paths, use the hook file /usr/local/maldetect/cron/custom.cron. For configuration o specific to cron, use /etc/sysconfig/maldet (RHEL) or /etc/default/maldet (Debian) or /usr/local/maldetect/cron/conf.maldet.cron.
A weekly watchdog script (/etc/cron.weekly/maldet-watchdog) provides independent fallback signature updates when the primary cron is broken or stale.
---
Real-time file monitoring with kernel inotify, digest alerts, and supervisor management.
Real-time file monitoring uses the kernel inotify subsystem to detect file creation, modification, and mo. Requires a kernel with CONFIG_INOTIFY_USER (standard on all modern kernels).
How it works:
maldet -m runs a supervisor process in the foreground by default. The supervisor manages an inotifywait child and handles crash recovery, configuration reloads, and digest alerting. Use -b to daemonize the supervisor and return immediately.
1. monitor_init() sets up inotify watches on all files under monitored paths
2. File events are queued and batch-scanned every inotify_sleep seconds (default: 15)
3. Configuration is reloaded every inotify_reloadtime seconds (default: 3600)
4. Kernel max_user_watches and max_user_instances are auto-tuned for optimal performance
5. If inotifywait crashes, the supervisor restarts it with exponential backoff (2, 4, 8, 16, 32 seconds); after 3 consecuti the supervisor exits
Digest alerts are sent periodically at the interval set by digest_interval (default: 24h). If the hit count since the last digest exceeds digest_escalate_hits, an immediate escalation alert is sent (default: 0, disabled).
Additi: To watch additional paths without editing conf.maldet, add them one per line to the file referenced by monitor_paths_extra (default: /usr/local/maldetect/monitor_paths.extra). These are merged with the primary watch list on every config reload.
When using the users mode, only subdirectories matching inotify_docroot (default: public_html,public_ftp) are monitored, plus the system temp directories /tmp, /var/tmp, and /dev/shm.
Ignore files (inotify): Monitor exclusions union two files — the user-owned /usr/local/maldetect/ignore_inotify and the LMD-managed /usr/local/maldetect/internals/ignore_inotify.defaults. Both are line-separated and support # comments + blank lines. The user-owned ignore_inotify accepts POSIX ERE (extended regex) by default — anchors (^, $) and wildcards (.*, .+) work. To exclude a literal path containing regex metacharacters, prefix the entry with literal: (e.g. literal:/tmp/app.cache). The LMD-managed ignore_inotify.defaults is treated as literal substrings — its curated entries are auto-escaped at load time. The defaults file is o on every LMD upgrade; add site-specific exclusions to ignore_inotify only.
---
Signature types, naming con, updates, and custom rule files.
LMD ships with fi types:
| Type | File | Format | Count |
|------|------|--------|-------|
| MD5 hashes | sigs/md5v2.dat | HASH:SIZE:{MD5}sig.name.N | ~14,801 |
| SHA-256 hashes | sigs/sha256v2.dat | HASH:SIZE:{SHA256}sig.name.N | CDN |
| HEX patterns | sigs/hex.dat | HEXSTRING:{HEX}sig.name.N | ~2,054 |
| Compound sigs | sigs/csig.dat | SUBSIG1\|\|SUBSIG2:signame | CDN |
| YARA rules | sigs/rfxn.yara | YARA syntax | ~783 rules |
| Compiled YARA | sigs/compiled.yarc | yarac output | optional |
ClamA signatures are also maintained:
sigs/rfxn.hdb — ClamAV MD5 formatsigs/rfxn.ndb — ClamAV HEX formatsigs/rfxn.hsb — ClamA format (requires ClamAV >= 0.97)Signature naming con: {TYPE}category.name.
Categories include: bin. (binary), c. (C language), exp. (exploit), php. (PHP), js. (Ja), perl. (Perl), html. (phishing), base64.inject., gzbase64.
Hit prefixes in scan reports:
| Prefix | Source |
|--------|--------|
| {MD5} | MD5 hash match (stage 1) |
| {SHA256} | SHA-256 hash match (stage 1) |
| {HEX} | HEX pattern match (stage 2) |
| {CSIG} | Compound signature match (stage 2.5) |
| {SA} | Statistical analysis (string length) |
| {YARA} | Native YARA scan (scan_yara=1) |
| {CAV} | ClamA (clamd/clamscan) |
Signatures are updated daily via the cron job or manually:
Custom signatures can be added in three formats, all preser upgrades:
| Type | File | Format |
|------|------|--------|
| Custom MD5 | sigs/custom.md5.dat | Same as md5v2.dat |
| Custom SHA-256 | sigs/custom.sha256.dat | Same as sha256v2.dat |
| Custom HEX | sigs/custom.hex.dat | Same as hex.dat |
| Custom CSIG | sigs/custom.csig.dat | Same as csig.dat |
| Custom YARA | sigs/custom.yara | YARA rule syntax |
| Custom YARA (drop-in) | sigs/custom.yara.d/*.yar | YARA rule files |
| Compiled YARA | sigs/compiled.yarc | yarac output (optional) |
Remote import URLs can be configured for automatic download during signature updates:
| | Purpose |
|----------|---------|
| sig_import_md5_url | URL for custom MD5 signatures |
| sig_import_sha256_url | URL for custom SHA-256 signatures |
| sig_import_hex_url | URL for custom HEX signatures |
| sig_import_csig_url | URL for custom compound signatures |
| sig_import_yara_url | URL for custom YARA rules |
---
Isolating, restoring, and cleaning malware-infected files.
Quarantined files are stored under /usr/local/maldetect/quarantine/ with permissions set to 000. Original path, owner, permissions, and modification time are recorded in /usr/local/maldetect/sess/quarantine.hist for full restoration.
Quarantine file naming: FILENAME.INODE (e.g., config.php.23754)
For non-root scans (e.g., ModSecurity2 upload scanning), quarantine data is stored under /usr/local/maldetect/pub/USERNAME/quar/. Use the -U flag to interact with non-root quarantine:
The cleaner function looks for signature-named scripts under the clean/ directory. Each script receives the infected file path as an argument and should strip the malicious content. After cleaning, the file is rescanned — if it still triggers a hit, the clean is marked FAILED.
To create a clean rule for signature php.cmdshell.r57, add a file clean/php.cmdshell.r57 containing a command like sed -i with the appropriate pattern. Successful cleans restore the file to its original path, owner, and permissions.
The cleaner is a sub-function of quarantine — files must be quarantined (or use -n) for cleaning to execute.
---
Service hook API for ModSecurity, FTP, Exim, and custom integrations.
LMD provides real-time file scanning for multiple services via the unified hookscan.sh API. A single script handles mode dispatch for ModSecurity, pure-ftpd, ProFTPD, Exim, and generic (custom) integrations.
Hook scan detections are logged to a rolling hit log (hook.hits.log) rather than creating per-scan session files. Detections are included in periodic digest alerts and can be via maldet --report hooks.
Malicious uploads are rejected with a deny action and logged to the ModSecurity audit log. No mode argument is needed — hookscan.sh defaults to ModSecurity mode for backward compatibility. Both ModSecurity v2 and v3 (libmodsecurity) use the same popen() contract.
Requires pure-ftpd compiled with --with-uploadscript. The mode is auto-detected via the UPLOAD_VUSER en . Infected files are quarantined after upload (fire-and-forget — uploads cannot be blocked, only post-processed).
Note: mod_exec always returns PR_DECLINED regardless of script exit code — uploads cannot be blocked by this hook. LMD quarantines infected files after the upload completes.
The three colon-separated fields are: command template, trigger regex, and name-capture regex. When malware is detected, Exim rejects the message using the captured signature name.
For custom integrations, batch scanning, and third-party use:
Batch output produces one STATUS: PATH line per file. Exit code is worst-result-wins.
Hook scan configuration is stored in conf.maldet.hookscan (optional — defaults are built into the script). The reference defaults are in conf.maldet.hookscan.default.
Key :
| | Default | Description |
|----------|---------|-------------|
| hookscan_timeout | 30 | Scan timeout in seconds |
| hookscan_fail_open | 1 | Allow file on scan error (0 = block) |
| hookscan_escalate_hits | 0 | Immediate alert at N hook hits/hour (0 = disabled) |
| hookscan_ser | apache,nginx,... | Service UIDs exempt from homedir restriction |
| hookscan_user_rate_limit | 60 | Max scans/hour for non-root callers |
| hookscan_user_show_signames | 1 | Show signature names to non-root callers |
| hookscan_list_max_bytes | 1048576 | Max list file size (1 MB) |
| hookscan_list_max_entries | 10000 | Max entries in file list |
Run maldet --mkpubpaths after enabling to create per-user data directories for non-root scan operations.
that alert delivery channels are correctly configured:
Test alerts use the real rendering pipeline with synthetic data. The subject line is prefixed with [TEST]. Channel isolation ensures only the specified channel fires.
Hook detections are summarized digest alerts:
The daily cron job automatically fires a hook digest when new detections exist (controlled by cron_digest_hook=1 in conf.maldet).
For administrators replacing CXS with LMD:
| CXS Component | LMD Equi |
|---------------|---------------|
| cxscgi.sh | hookscan.sh modsec |
| cxsftp.sh | hookscan.sh ftp |
| ProFTPD mod_exec to cxs | hookscan.sh proftpd |
| cxs --file | hookscan.sh generic |
| cxswatch | maldet --monitor |
| /etc/cxs/cxs.conf | conf.maldet.hookscan |
---
Connecting LMD with external tools, automation pipelines, and third-party scanners.
LMD signatures are automatically symlinked to ClamAV data directories by install.sh, pro dual-engine co. Set scan_clamscan=auto (default) for automatic ClamA. See 3.8 ClamA for engine selection and signature .
Enable enable_statistic=1 with elk_host, elk_port, and elk_index to stream scan events to Elasticsearch. See 3.10 ELK Integration.
LMD supports four alert delivery channels beyond email: Slack (Block Kit), TA. See 3.2 Alerting for configuration.
Machine-readable scan output for CI/CD and automation:
See man maldet(1) for the v1.2 JSON schema (uniform {schema_, scanner, host, reports[]} shape across both -e SCANID and -e list).
The daily cron auto-detects 12+ hosting control panels and adjusts scan paths. See 6. Cron Daily for the full panel matrix.
---
LMD is de and supported on a basis by Ryan MacDonald [].
Linux Malware Detect (LMD) is distributed under the GNU General Public License (GPL) v2
without restrictions on usage or redistribution. The copyright statement and GNU GPL
are included in the COPYING.GPL file. Credit must be given for deri works as
required under GNU GPL.
---
The LMD source repository is at:
Bugs, feature requests, and general questions can be filed as GitHub issues or sent to .
The official project page is at:
开发语言:Shell
Star 数:1518
该项目属于病毒分析方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕Multi-engine Linux malware scanner with five detection stages (MD5, HEX pattern, YARA, ClamAV, statistical), real-time inotify monitoring, quarantine, and multi-channel alerting展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | linux-malware-detect - Multi-engine Linux malware scanner with five detec |
| 所属分类 | 病毒分析 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 23:12:49 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 86 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |