jannath0223/yara-malware-scanner

GitHub: jannath0223/yara-malware-scanner

一款基于Python与YARA构建的模块化静态恶意软件扫描器,通过自定义行为规则与并发扫描为蓝队提供低误报的检测与结构化报告。

Stars: 0 | Forks: 0

# 🛡️ YARA 恶意软件扫描器 ![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python) ![YARA](https://img.shields.io/badge/YARA-4.3%2B-red) ![License](https://img.shields.io/badge/License-MIT-green) ![Tests](https://img.shields.io/badge/Tests-Passing-brightgreen) ![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey) ## 📌 目录 1. [概述](#overview) 2. [为什么选择这个工具](#-why-this-tool--not-just-another-yara-wrapper) 3. [恶意软件案例研究](#-malware-case-study) 4. [检测质量 — 正常文件 vs 恶意文件](#-detection-quality--clean-vs-malicious-comparison) 5. [核心功能](#key-features) 6. [架构](#architecture) 7. [安装说明](#installation) 8. [使用方法](#usage) 9. [输出解释](#output-explanation) 10. [规则工程](#rule-engineering) 11. [示例规则解析](#sample-rule-breakdown) 12. [项目结构](#project-structure) 13. [截图](#screenshots) 14. [运行测试](#running-tests) 15. [局限性](#limitations) 16. [未来改进](#future-improvements) 17. [使用场景](#use-cases) 18. [参考链接](#references) ## 概述 YARA 恶意软件扫描器是一个**模块化、生产级风格的静态分析工具**,利用 YARA 语言编写的模式匹配规则来检测恶意文件。 与仅运行公共规则集的基础扫描器不同,本项目专注于: - ✍️ **自定义规则开发** — 设计旨在最大限度减少误报的规则 - 🧱 **模块化架构** — 扫描、哈希计算、规则加载和报告功能被分离为清晰的模块 - 🔐 **加密文件哈希** — 每个扫描的文件都会生成指纹(MD5, SHA1, SHA256) - ⚡ **并发扫描** — 目录扫描使用多线程运行,以应对实际场景性能需求 - 📊 **结构化 JSON 报告** — 输出适配 SOC 需求,而不仅仅是终端打印 - 🧪 **单元测试覆盖的检测逻辑** — 20 多个测试用例,覆盖检测准确性、Schema 验证和边缘情况 **适用人群:** - 进行恶意软件分类的 SOC 分析师 - 构建检测管道的蓝队工程师 - 学习检测工程的安全专业学生 ## ❓ 为什么选择这个工具 — 绝非又一个 YARA 包装器 大多数基础的 YARA 扫描器实际上只做这件事: ``` matches = rules.match(filepath) print(matches) ``` 那只是一个包装器。本项目不仅如此。以下是它的不同之处: | 基础包装器所做的 | 本项目所做的 | |---|---| | 单线程文件扫描 | `ThreadPoolExecutor` — 具有可配置工作线程的并发扫描 | | 加载规则,打印匹配 | 包含哈希、偏移量、规则元数据的结构化 JSON 报告 | | `f.read()` — 将整个文件加载到内存中 | 8KB 分块读取 — 对于大型恶意软件样本是安全的 | | 没有验证 | 规则加载器在扫描前验证元数据是否存在 | | 到处使用 `print()` | 完整的 `logging` 模块 — INFO/WARNING/ERROR 级别 | | 没有测试 | 20 个单元测试 — 检测准确性、Schema、边缘情况 | | 完成后退出 | 退出代码 `0/1/2` — 可与 CI/CD 管道集成 | | 复制粘贴公共规则 | 具有行为配对逻辑和 MITRE ATT&CK 映射的自定义规则 | **核心区别:** 本项目将检测视为一个工程问题 —— 而不仅仅是运行一个工具。规则是基于特定推理设计的,针对正常文件和恶意文件都进行了测试,并记录了每个决策背后的逻辑。 ## 🔬 恶意软件案例研究 完整的静态分析演练记录在 [`analysis/malware_analysis_case_study.md`](analysis/malware_analysis_case_study.md) 中。 包含两个案例研究: ### 案例 1 — WannaCry 风格勒索软件 (T1486) 对勒索软件样本的静态分析揭示了以下指标: - 勒索信字符串(`YOUR FILES HAVE BEEN ENCRYPTED`) - 卷影副本删除(`vssadmin delete shadows`)— 阻止受害者恢复 - Windows 加密 API 导入(`CryptEncrypt`, `CryptGenKey`) - 通过 `WS2_32.dll` 导入的网络功能 **基于这些发现构建的检测规则:** `Ransomware_Indicators` **规则为何这样构建:** - 仅 `CryptEncrypt` → 误报(合法加密软件也会使用) - 仅 `vssadmin delete shadows` → 误报(某些备份工具会使用) - **两者同时出现 + 勒索信** → 极高置信度的勒索软件 ### 案例 2 — 木马下载器 (T1105) 发现的指标:`URLDownloadToFile` + `ShellExecute` + `%TEMP%` 路径写入 **检测洞察:** 一个下载器需要下载能力 AND 执行能力 AND 临时暂存 —— 这三者缺一不可。任何单一指标单独出现都会在合法软件上导致误报。 ## ✅ 检测质量 — 正常文件与恶意文件对比 下表证明了该工具有效且不会产生误报: | 样本 | 内容 | 预期结果 | 实际结果 | |---|---|---|---| | `wannacry_sim.txt` | 勒索信 + 卷影删除 | 🔴 检测到 | ✅ 触发 `Ransomware_Indicators` | | `dropper_sim.txt` | 下载 + 执行 + 临时路径 | 🔴 检测到 | ✅ 触发 `Trojan_Dropper` | | `clean_file.txt` | 普通文本,无指标 | ✅ 正常 | ✅ 0 匹配 | | `README.md` | 项目文档 | ✅ 正常 | ✅ 0 匹配 | | 合法加密应用 | 仅 `CryptEncrypt` — 无勒索信 | ✅ 正常 | ✅ 0 匹配 — 规则逻辑阻止了误报 | **关键验证:** 最后一行最重要。一个检测到 `CryptEncrypt` 而不需要额外行为指标的工具,会在每一个合法加密应用程序上产生误报。本工具不会。 ## 核心功能 | 功能 | 详情 | |---|---| | 🔍 静态检测 | 使用编译好的 YARA 规则扫描文件和目录 | | 🧠 自定义规则 | 6 个规则类别:勒索软件、键盘记录器、RAT、下载器、混淆、PE 导入 | | 📊 JSON 报告 | 每次扫描保存包含完整匹配详情的结构化输出 | | 🔐 文件哈希 | 通过分块读取计算 MD5, SHA1, SHA256 —— 对大文件内存安全 | | ⚡ 并发扫描 | ThreadPoolExecutor —— 并行扫描多个文件 | | 🛡️ PE 头验证 | 规则在应用 Windows 特定逻辑前验证 MZ 魔数 | | ⚠️ 文件大小限制 | 跳过大于 50MB 的文件以防止资源耗尽 | | 📋 日志系统 | 结构化日志模块 —— 没有原始 print() 调用 | | 🧪 单元测试 | 20 多个测试用例覆盖哈希、检测、Schema 和边缘情况 | | 🔌 退出代码 | 0 = 正常, 1 = 检测到威胁, 2 = 错误 —— 兼容 CI/CD 管道 | ## 架构 ``` Input: File or Directory Path │ ▼ ┌─────────────────────┐ │ CLI (cli/main.py) │ ← argparse, logging setup, exit codes └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Rule Loader │ ← Loads and compiles .yar files, validates metadata └──────────┬──────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Scanner Engine (core/scanner.py) │ │ ┌──────────────────────────────────┐ │ │ │ ThreadPoolExecutor (4 workers) │ │ ← Concurrent file scanning │ │ scan_file() compute_hashes() │ │ ← Chunked hashing (8KB blocks) │ └──────────────────────────────────┘ │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ Report Builder (core/report.py) │ │ ├── JSON report saved per file │ │ └── Human-readable terminal output │ └──────────────────────────────────────┘ ``` **数据流:** `输入 → 规则编译 → 并发扫描 → 哈希 + YARA 匹配 → 结构化报告 → JSON + 终端输出` ## 安装说明 ### 前置条件 - Python 3.10 或更高版本 - pip ### 步骤 ``` # 1. Clone repository git clone https://github.com/jannath0223/yara-malware-scanner.git cd yara-malware-scanner # 2. Create virtual environment (推荐) python -m venv venv source venv/bin/activate # Linux / macOS venv\Scripts\activate # Windows # 3. Install dependencies pip install -r requirements.txt ``` ## 使用方法 ### 扫描单个文件 ``` python cli/main.py -f samples/suspicious.exe ``` ### 扫描目录 ``` python cli/main.py -d samples/ ``` ### 使用自定义规则 ``` python cli/main.py -f samples/file.bin -r path/to/custom_rules/ ``` ### 扫描但不保存报告 ``` python cli/main.py -d samples/ --no-save ``` ### 增加并发工作线程 ``` python cli/main.py -d samples/ --workers 8 ``` ### 启用详细输出 ``` python cli/main.py -f sample.exe -v ``` ### 查看完整帮助 ``` python cli/main.py --help ``` ## 输出解释 ### 终端输出 ``` ======================================================= 🔴 THREAT DETECTED ======================================================= File : suspicious.exe Size : 24576 bytes MD5 : d41d8cd98f00b204e9800998ecf8427e SHA256 : e3b0c44298fc1c149afbf4c8996fb924... Matches : 1 ▶ Rule : Ransomware_Indicators Desc : Detects behavioral indicators associated with ransomware Sev : CRITICAL Tags : ransomware, encryption, extortion ======================================================= ``` ### JSON 报告(保存到 `reports/`) ``` { "timestamp": "2025-03-19T10:30:00+00:00", "file": "/home/user/samples/suspicious.exe", "filename": "suspicious.exe", "size_bytes": 24576, "hashes": { "md5": "d41d8cd98f00b204e9800998ecf8427e", "sha1": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4..." }, "status": "THREAT_DETECTED", "match_count": 1, "matches": [ { "rule": "Ransomware_Indicators", "namespace": "malware_detection", "tags": ["ransomware", "encryption", "extortion"], "meta": { "description": "Detects behavioral indicators associated with ransomware", "severity": "CRITICAL", "confidence": "HIGH", "reference": "https://attack.mitre.org/techniques/T1486/" }, "strings": [ { "identifier": "$ransom1", "offset": 0, "matched_data": "YOUR FILES HAVE BEEN ENCRYPTED" } ] } ] } ``` **字段参考:** | 字段 | 描述 | |---|---| | `timestamp` | 扫描的 UTC 时间 | | `file` | 被扫描文件的绝对路径 | | `status` | `CLEAN` 或 `THREAT_DETECTED` | | `match_count` | 触发的规则数量 | | `matches[].rule` | 触发的 YARA 规则名称 | | `matches[].meta.severity` | `LOW` / `MEDIUM` / `HIGH` / `CRITICAL` | | `matches[].meta.reference` | MITRE ATT&CK 技术链接 | | `matches[].strings` | 带有字节偏移量的匹配字符串 | | `hashes` | 用于威胁情报查询的 MD5, SHA1, SHA256 | ## 规则工程 为了最大限度地减少误报,规则设计遵循以下原则: ### 本项目所做的 **1. 每个规则包含多个指标 —— 绝不进行单字符串匹配** ``` condition: (any of ($ransom*)) and (any of ($shadow*, $crypt*)) ``` **2. 行为配对 —— 需要能力 AND 动作同时存在** 一个下载器规则需要下载 API AND 执行 API AND 临时路径 —— 这三者缺一不可。任何单一匹配都不会触发规则。 **3. 针对 Windows 特定规则的 PE 头验证** ``` uint16(0) == 0x5A4D // MZ magic bytes — confirms valid Windows PE binary ``` **4. 用于抵抗规避的十六进制模式** ``` $hex1 = { 2F 62 69 6E 2F 73 68 } // /bin/sh in hex — bypasses ASCII-only evasion ``` **5. MITRE ATT&CK 对齐** 每个规则都包含一个链接到相应 ATT&CK 技术的 `reference` 字段。 ### 本项目所避免的 - 单字符串规则(仅 `$s1 = "cmd.exe"` 会导致大量误报) - 没有上下文的短字符串或过于常见的字符串 - 没有元数据的规则(使 SOC 分类变得不可能) - 像 `any of them` 这样没有限定条件的过于宽泛的条件 ## 示例规则解析 ``` rule Ransomware_Indicators { meta: description = "Detects behavioral indicators associated with ransomware" author = "Jannath R" severity = "CRITICAL" confidence = "HIGH" reference = "https://attack.mitre.org/techniques/T1486/" strings: $ransom1 = "YOUR FILES HAVE BEEN ENCRYPTED" ascii wide nocase $ransom2 = "To decrypt your files" ascii wide nocase $shadow1 = "vssadmin delete shadows" ascii wide nocase $shadow2 = "wmic shadowcopy delete" ascii wide nocase $crypt1 = "CryptEncrypt" ascii $crypt2 = "CryptGenKey" ascii condition: (any of ($ransom*)) and (any of ($shadow*, $crypt*)) } ``` | 元素 | 原因 | |---|---| | `$ransom1`, `$ransom2` | 勒索信是最清晰的行为信号 | | `$shadow1`, `$shadow2` | 勒索软件删除卷影副本以阻止文件恢复 | | `$crypt1`, `$crypt2` | 确认二进制文件中存在实际的加密能力 | | `nocase` 修饰符 | 捕获同一字符串的所有大小写变体 | | `wide` 修饰符 | 捕获 ASCII 和 UTF-16 字符串(常见于 Windows 二进制文件) | | 条件逻辑 | 需要勒索信 AND 卷影删除或加密 API —— 防止来自合法加密工具的误报 | ## 项目结构 ``` yara-malware-scanner/ │ ├── core/ # Core scanning engine │ ├── __init__.py │ ├── scanner.py # File and directory scanning with concurrency │ ├── rules_loader.py # YARA rule loading and validation │ ├── hashing.py # Chunked MD5 / SHA1 / SHA256 computation │ └── report.py # JSON report building and terminal output │ ├── cli/ │ └── main.py # CLI entry point — argparse, logging, exit codes │ ├── rules/ │ └── malware_detection.yar # Custom YARA rules (6 detection categories) │ ├── tests/ │ └── test_scanner.py # 20+ unit tests │ ├── reports/ # Generated JSON reports (git ignored) ├── screenshots/ # README screenshots │ ├── requirements.txt ├── .gitignore ├── LICENSE └── README.md ``` ## 截图 ### 1. 检测到威胁 + 正常文件(单文件扫描) ![Threat Detected and Clean](https://raw.githubusercontent.com/jannath0223/yara-malware-scanner/main/screenshots/02_threat_detected_and_clean.png) ### 2. 目录扫描 — 并发扫描多个文件 ![Directory Scan](https://raw.githubusercontent.com/jannath0223/yara-malware-scanner/main/screenshots/01_directory_scan.png) ### 3. 下载器检测 ![Dropper Detected](https://raw.githubusercontent.com/jannath0223/yara-malware-scanner/main/screenshots/03_dropper_detected.png) ### 4. JSON 报告输出 ![JSON Report](https://raw.githubusercontent.com/jannath0223/yara-malware-scanner/main/screenshots/04_json_report.png) ### 5. 全部 20 个测试通过 ![Tests Passing](https://raw.githubusercontent.com/jannath0223/yara-malware-scanner/main/screenshots/05_tests_passing.png) ### 6. 帮助菜单 ![Help Menu](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/9369af9f71105515.png) ## 运行测试 ``` # Run all tests with verbose output python -m unittest discover tests -v # Run specific test class python -m unittest tests.test_scanner.TestDetection -v ``` | 测试类 | 覆盖范围 | |---|---| | `TestHashing` | 哈希正确性、分块读取、错误处理 | | `TestRulesLoader` | 有效加载、错误路径、空目录、语法错误 | | `TestDetection` | 正常文件、勒索软件、键盘记录器、RAT、下载器、编码 Payload | | `TestReportSchema` | 必填字段、哈希 Schema、磁盘持久化 | | `TestEdgeCases` | 文件丢失、空文件、正确的文件大小报告 | ## 局限性 | 局限性 | 解释 | |---|---| | 仅静态分析 | 不执行文件 —— 行为分析需要像 Cuckoo 这样的沙箱 | | 无加壳恶意软件检测 | UPX 和自定义加壳器会隐藏字符串,使静态扫描器无法检测 | | 依赖规则质量 | 检测效果取决于规则的好坏 —— 弱规则会产生误 | | 无混淆处理 | 高度 XOR 编码的 Payload 可能无法触发基于字符串的规则 | | 无实时监控 | 仅按需扫描 —— 没有文件系统监控功能 | | 专注于 Windows PE | 特定于 PE 的规则仅适用于 Windows 二进制文件 | ## 未来改进 | 改进 | 优先级 | |---|---| | SIEM 集成 —— Wazuh / Splunk | 高 | | 使用 watchdog 进行实时目录监控 | 高 | | 使用 YarGen 自动生成规则 | 中 | | 通过 VirusTotal API 进行威胁情报富化 | 中 | | 熵分析以检测加壳或加密部分 | 中 | | 检测仪表板 —— 用于查看扫描历史的 Web UI | 低 | | ELF / Linux 恶意软件规则覆盖 | 中 | ## 使用场景 | 场景 | 本工具如何提供帮助 | |---|---| | SOC 警报分类 | 快速扫描可疑文件并获得带有严重程度的基于规则的判定 | | 恶意软件实验室分析 | 根据自定义规则对收集的样本进行分类,以识别恶意软件家族 | | 威胁狩猎 | 扫描整个文件系统目录以查找特定的失陷指标 | | 蓝队训练 | 在一个可运行的、可测试的环境中学习 YARA 规则逻辑 | | CI/CD 安全门禁 | 使用退出代码(0 / 1)在检测到恶意文件时阻止部署 | ## 参考链接 - [YARA 官方文档](https://virustotal.github.io/yara/) - [MITRE ATT&CK 框架](https://attack.mitre.org/) - [YarGen — 自动 YARA 规则生成器](https://github.com/Neo23x0/yarGen) - [Awesome YARA — 社区规则集合](https://github.com/InQuest/awesome-yara) - [YARA 性能指南](https://yara.readthedocs.io/en/stable/writingrules.html) ## 作者 **Jannath R** 网络安全爱好者 | 有志成为 SOC 分析师 [![GitHub](https://img.shields.io/badge/GitHub-jannath0223-181717?logo=github)](https://github.com/jannath0223)
标签:DAST, DNS 反向解析, IP 地址批量处理, JSON报告, Python, SHA256, YARA, 云安全监控, 云计算, 云资产可视化, 云资产清单, 哈希计算, 域名收集, 并发扫描, 库, 应急响应, 恶意软件分析, 无后门, 模式匹配, 网络信息收集, 网络安全, 自动化资产收集, 规则引擎, 逆向工具, 逆向工程, 隐私保护, 静态分析