核心功能: - 6 层检测管线: L0 结构分析 → L1 ClamAV → L2 文档深度检测 → L3 关键词匹配 → L4 YARA → L5 PE/二进制 - FastAPI + PostgreSQL + Redis + Docker Compose 架构 - 客户端 HMAC-SHA256 签名鉴权 + 限流 + 幂等性 - 控制台 UI (登录/Dashboard/诊断中心/策略管理/任务列表/测试中心/产品介绍页) - 三层诊断定时器 (error_scan 30s / db_aggregate 30s / container_check 5min) 并发与稳定性修复: - 诊断定时器 Redis 时间槽位锁 (多 worker 同一槽位只有一个执行) - JSONL 存储 fcntl 跨进程排他锁 + 容错解码 + 原子重写 - 移除 SQLite fallback, 统一 PostgreSQL - API_CLIENTS 脱敏为环境变量, .env 已 .gitignore
404 lines
16 KiB
Plaintext
404 lines
16 KiB
Plaintext
// =============================================================================
|
||
// MeshSafe L2B YARA 规则集 —— Windows PE 恶意程序专项(C1 + C8)
|
||
// =============================================================================
|
||
//
|
||
// 设计原则:
|
||
// - 所有规则使用 2-3 特征组合命中(API 组合 + C2 URL + Mutex 持久化等)
|
||
// - binary.py 的 PE 结构分析负责:节熵 + 签名 + 可疑导入(单 API)
|
||
// - YARA 负责:多 API 组合 + 字符串组合 + 壳 + 勒索专项
|
||
// - 命中后作为 finding 交给 PolicyEngine 权重累加,不直接零容忍
|
||
//
|
||
// 范围:
|
||
// - C1: Windows PE 恶意程序(注入器 / 下载器 / RAT / Loader)
|
||
// - C8: 勒索 / 挖矿专项
|
||
// - C9: 壳 / 签名 / 结构异常(binary.py 已覆盖大部分,YARA 补充壳特征)
|
||
//
|
||
// 维护:
|
||
// - 新恶意家族出现时,优先补充"API 组合 + Mutex 名 + C2 URL"三件套
|
||
// - 壳特征(UPX/Themida/VMP)可识别后自动送沙箱深检
|
||
// =============================================================================
|
||
|
||
|
||
// =============================================================================
|
||
// C1-1 进程注入三件套(VirtualAllocEx + WriteProcessMemory + CreateRemoteThread)
|
||
// binary.py 扫了 SuspiciousImports(单个 API),但 3 个同时出现 = 必然是注入器
|
||
// =============================================================================
|
||
|
||
rule C1_PE_ProcessInjection {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C1"
|
||
false_positive_rate = "low"
|
||
reference = "MITRE ATT&CK T1055 Process Injection"
|
||
description = "PE 文件同时导入 进程注入三件套 API = 远控/注入器特征"
|
||
strings:
|
||
$s1 = "VirtualAllocEx" ascii
|
||
$s2 = "WriteProcessMemory" ascii
|
||
$s3 = "CreateRemoteThread" ascii
|
||
// 备选:Nt 系列(NtUnmapViewOfSection + VirtualAllocEx + CreateRemoteThread)
|
||
$n1 = "NtUnmapViewOfSection" ascii
|
||
$n2 = "NtMapViewOfSection" ascii
|
||
$n3 = "ZwUnmapViewOfSection" ascii
|
||
// 也可能是 QueueUserAPC 注 APC 注入
|
||
$apc = "QueueUserAPC" ascii
|
||
// 或 SetWindowsHookEx DLL 注入
|
||
$hook = "SetWindowsHookEx" ascii
|
||
condition:
|
||
// 经典三件套(必须同时命中)
|
||
$s1 and $s2 and $s3
|
||
or
|
||
// Nt 系列内存注入(至少 2 个 Nt + 1 个注入)
|
||
(any of ($n1, $n2, $n3) and any of ($s1, $s3, $apc))
|
||
or
|
||
// APC 注入 + VirtualAllocEx
|
||
$apc and $s1
|
||
or
|
||
// Hook DLL 注入
|
||
$hook and $s1
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-2 下载器组合(网络 API + 本地持久化 / 执行)
|
||
// 单一 URLDownloadToFile 不致命,但 "下载 + 执行 + 持久化" 三件套 = Loader
|
||
// =============================================================================
|
||
|
||
rule C1_PE_Downloader_Loader {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C1"
|
||
false_positive_rate = "low"
|
||
reference = "MITRE ATT&CK T1105 Ingress Tool Transfer"
|
||
description = "下载器组合:HTTP/FTP 下载 + 写入到可疑路径 + 执行"
|
||
strings:
|
||
// 网络下载 API(任选其一)
|
||
$net1 = "URLDownloadToFile" ascii
|
||
$net2 = "InternetOpenUrl" ascii
|
||
$net3 = "WinHttpOpen" ascii
|
||
$net4 = "WinHttpOpenRequest" ascii
|
||
$net5 = "FtpOpenFile" ascii
|
||
$net6 = "DownloadFile" ascii
|
||
$net7 = "WinHttpSendRequest" ascii
|
||
|
||
// 写入/保存到本地
|
||
$save1 = "WriteFile" ascii
|
||
$save2 = "SaveToFile" ascii
|
||
$save3 = "URLDownloadToCacheFile" ascii
|
||
|
||
// 执行下载的载荷
|
||
$exec1 = "WinExec" ascii
|
||
$exec2 = "CreateProcess" ascii
|
||
$exec3 = "ShellExecute" ascii
|
||
$exec4 = "CreateRemoteThread" ascii
|
||
|
||
// 持久化(注册表/启动项)
|
||
$persist1 = "RegSetValueEx" ascii
|
||
$persist2 = "SetServiceObjectSecurity" ascii
|
||
$persist3 = "CreateService" ascii
|
||
$persist4 = "schtasks.exe" ascii
|
||
$persist5 = "RUN" ascii // HKCU\Software\Microsoft\Windows\CurrentVersion\Run
|
||
condition:
|
||
// 下载 + 保存 + 执行(三件套)
|
||
any of ($net*) and any of ($save*) and any of ($exec*)
|
||
or
|
||
// 下载 + 持久化(即使没执行也是准备投毒)
|
||
any of ($net*) and any of ($persist*)
|
||
or
|
||
// 执行 + 持久化(下载可能在运行时动态完成)
|
||
any of ($exec1, $exec2, $exec3) and any of ($persist*)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-3 RAT / 远控特征(C2 通信 + 命令执行 + 持久化)
|
||
// =============================================================================
|
||
|
||
rule C1_PE_RAT_CommandControl {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C1"
|
||
false_positive_rate = "medium"
|
||
reference = "MITRE ATT&CK T1071 Application Layer Protocol"
|
||
description = "RAT C2 通信特征:WinHTTP/WSASend + 命令执行 API + 可疑 URL/域名"
|
||
strings:
|
||
// C2 网络通道
|
||
$c2_send = /WSASend|send\s*\(|sendto|WinHttpSendRequest|InternetWriteFile/ ascii
|
||
$c2_recv = /WSARecv|recv\s*\(|recvfrom|WinHttpReadData|InternetReadFile/ ascii
|
||
$c2_connect = /WSAConnect|connect\s*\(|WinHttpConnect|InternetConnect/ ascii
|
||
|
||
// 命令执行
|
||
$cmd = /CreateProcess|ShellExecute|WinExec|system\s*\(|popen/ ascii
|
||
|
||
// 可疑 C2 URL(可执行文件里出现 http://...exe 或常见 C2 域名)
|
||
$c2url1 = /http:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,5}/ ascii
|
||
$c2url2 = /https?:\/\/[^\"\s'\)]+\.(ru|top|xyz|tk|ml|ga|gq|cf|pw|click|stream|xyz|buzz|loan)\/[^\"\s'\)]*\.exe/ ascii
|
||
$c2url3 = /(c2|panel|gate|bot|ops|serv|beacon|stage|stager)\.(ru|top|xyz|cc|io|com|net)/ ascii
|
||
condition:
|
||
// C2 通信 + 命令执行(至少两个网络 + 一个命令)
|
||
any of ($c2_send, $c2_recv, $c2_connect) and any of ($cmd*) and any of ($c2url*)
|
||
or
|
||
// C2 URL 模式 + 网络 API
|
||
any of ($c2url*) and any of ($c2_connect, $c2_send)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-4 Mutex 互斥体名(勒索 / RAT / Loader 的持久化标记)
|
||
// 单一 Mutex 名有一定价值,但必须配合其他特征才触发
|
||
// =============================================================================
|
||
|
||
rule C1_PE_Mutex_Persistence {
|
||
meta:
|
||
risk_level = "medium"
|
||
category = "C1"
|
||
false_positive_rate = "medium"
|
||
reference = "MITRE ATT&CK T1057 Process Discovery (mutex as persistence marker)"
|
||
description = "可疑 Mutex 名称 + CreateMutex API = 持久化标记"
|
||
strings:
|
||
$createmutex = "CreateMutexA" ascii
|
||
$createmutexw = "CreateMutexW" ascii
|
||
// 常见勒索/RAT Mutex 名(大小写不敏感,含 Unicode 变体用 wide)
|
||
// LockBit
|
||
$lockbit1 = /Global\\[Ll]ock[Bb]it/ ascii
|
||
$lockbit2 = /Local\\[Ll]ock[Bb]it/ ascii
|
||
// BlackCat / ALPHV
|
||
$blackcat = /Global\\[Bb]lack[Cc]at|[Aa][Ll][Pp][Hh][Vv]/ ascii
|
||
// Ryuk
|
||
$ryuk = /RyukTask[\d]|Global\\Ryuk/ ascii
|
||
// Conti
|
||
$conti = /Global\\[Cc]onti|Local\\[Cc]onti/ ascii
|
||
// Pseudo/Dharma
|
||
$dharma = /Global\\[Dd]harma|Local\\[Dd]harma/ ascii
|
||
// 通用可疑模式:Mutex 名包含 "Mutex" + UUID 变体
|
||
$generic1 = /Global\\Mutex[0-9a-f]{8}/ ascii
|
||
// Kryptik/Qakbot
|
||
$qakbot = /[Qq]akbot|[Kk]ryptik/ ascii
|
||
// Cobalt Strike named pipe
|
||
$cs1 = /\\\\\.\\pipe\\msagent_[0-9a-f]+/ ascii
|
||
$cs2 = /\\\\\.\\pipe\\[Bb]eacon_[0-9a-f]+/ ascii
|
||
condition:
|
||
// CreateMutex + 已知家族 Mutex 名
|
||
(any of ($createmutex*)) and any of ($lockbit1, $lockbit2, $blackcat, $ryuk, $conti, $dharma, $qakbot)
|
||
or
|
||
// Cobalt Strike 命名管道特征(不需要 CreateMutex)
|
||
any of ($cs*)
|
||
or
|
||
// CreateMutex + 通用可疑 UUID Mutex
|
||
(any of ($createmutex*)) and $generic1
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-5 DLL 劫持 / LoadLibrary 动态加载
|
||
// =============================================================================
|
||
|
||
rule C1_PE_DLLHijacking {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C1"
|
||
false_positive_rate = "medium"
|
||
reference = "MITRE ATT&CK T1574 Hijack Execution Flow"
|
||
description = "PE 动态加载多个系统 DLL + 非系统路径 = DLL 劫持迹象"
|
||
strings:
|
||
$loadlib = "LoadLibraryA" ascii
|
||
$loadlibw = "LoadLibraryW" ascii
|
||
$getproc = "GetProcAddress" ascii
|
||
// 可疑加载路径(非 System32)
|
||
$path1 = /\\Users\\[^\\]+\\AppData\\Local\\Temp/ ascii
|
||
$path2 = /\\AppData\\Local\\Temp/ ascii
|
||
$path3 = /\\ProgramData\\/ ascii
|
||
$path4 = /\\Public\\Documents\\/ ascii
|
||
condition:
|
||
// LoadLibrary + 可疑路径 + GetProcAddress = 完整劫持链
|
||
(any of ($loadlib*)) and any of ($path*) and $getproc
|
||
or
|
||
// LoadLibrary + 多个可疑路径
|
||
(any of ($loadlib*)) and 2 of ($path*)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-6 LOLBin(Living Off The Land Binary)调用特征
|
||
// 已知合法 Windows 二进制被恶意利用来执行命令
|
||
// =============================================================================
|
||
|
||
rule C1_PE_LOLBin_Usage {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C1"
|
||
false_positive_rate = "low"
|
||
reference = "https://lolbas-project.github.io/"
|
||
description = "PE 文件中出现 LOLBin 调用:certutil / mshta / rundll32 / regsvr32 / bitsadmin / wmic / msiexec"
|
||
strings:
|
||
$certutil = /certutil(\.exe)?\s+(-urlcache|-decode|-encode|-hashfile)/ ascii
|
||
$mshta = /mshta(\.exe)?\s+(https?:|javascript:|vbscript:)/ ascii
|
||
$rundll32 = /rundll32(\.exe)?\s+[A-Za-z0-9_.]+,/ ascii
|
||
$regsvr32 = /regsvr32(\.exe)?\s+\/s\s+\/u/ ascii
|
||
$bitsadmin = /bitsadmin(\.exe)?\s+(\/transfer|\/create)/ ascii
|
||
$wmic = /wmic(\.exe)?\s+(process\s+call\s+create|product\s+call)/ ascii
|
||
$msiexec = /msiexec(\.exe)?\s+\/[ia]\s+https?:/ ascii
|
||
$installutil = /installutil(\.exe)?\s+\/u\s+\/logfile=/ ascii
|
||
$syncapp = /syncapp(\.exe)?\s+\/compattrack/ ascii
|
||
$psexec = /psexec(\.exe)?\s+(-accepteula|-i\s+\d+|-w\s+https?:)/ ascii
|
||
// 命令执行 API(用于组合条件)
|
||
$exec1 = "CreateProcess" ascii
|
||
$exec2 = "ShellExecute" ascii
|
||
$exec3 = "WinExec" ascii
|
||
condition:
|
||
// 至少 1 个 LOLBin 调用 + 命令执行 API
|
||
any of ($certutil*, $mshta*, $rundll32*, $regsvr32*, $bitsadmin*, $wmic*, $msiexec*, $installutil*, $syncapp*, $psexec*)
|
||
and any of ($exec*)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C8-1 勒索加密 API 组合(CryptEncrypt + BCrypt* + 文件遍历 + 删除卷影)
|
||
// =============================================================================
|
||
|
||
rule C8_Ransomware_Encryption {
|
||
meta:
|
||
risk_level = "critical"
|
||
category = "C8"
|
||
false_positive_rate = "low"
|
||
reference = "MITRE ATT&CK T1486 Data Encrypted for Impact"
|
||
description = "勒索加密链:CryptEncrypt/BCryptEncrypt + 大量文件遍历 + 卷影删除 = 勒索"
|
||
strings:
|
||
// 加密 API(至少出现两个)
|
||
$enc1 = "CryptEncrypt" ascii
|
||
$enc2 = "CryptDeriveKey" ascii
|
||
$enc3 = "BCryptEncrypt" ascii
|
||
$enc4 = "BCryptDeriveKeyPair" ascii
|
||
$enc5 = "CryptGenKey" ascii
|
||
|
||
// 文件遍历(全盘加密需要)
|
||
$enum1 = "FindFirstFileA" ascii
|
||
$enum2 = "FindFirstFileW" ascii
|
||
$enum3 = "FindNextFileA" ascii
|
||
$enum4 = "FindNextFileW" ascii
|
||
|
||
// 卷影删除(勒索前置)
|
||
$vss1 = "vssadmin" ascii
|
||
$vss2 = "delete shadows" ascii
|
||
$vss3 = "DeleteShadowCopies" ascii
|
||
$vss4 = "wmic" ascii
|
||
|
||
// 勒索信文件名变体(出现在二进制里)
|
||
$ransomnote1 = /(HOW_TO_RECOVER|RESTORE_FILES|DECRYPT_INSTRUCTIONS|README|HELP_DECRYPT|_readme|_restore)[\w.-]*\.(txt|html|png|jpg|bmp|url)/ nocase
|
||
$ransomnote2 = /\.(locky|zepto|cryptolocker|tor|crpt|encrypted|virus|wallet|pay2)/ nocase
|
||
$ransomnote3 = /bitcoin|bitcash|monero|ltc|BTC\b/ ascii
|
||
condition:
|
||
// 加密 API + 文件遍历 = 加密工具(必须至少 2 个加密 API)
|
||
(2 of ($enc*)) and any of ($enum*)
|
||
or
|
||
// 加密 API + 卷影删除 = 完整勒索
|
||
(any of ($enc*)) and any of ($vss*)
|
||
or
|
||
// 加密 API + 勒索信 + 加密文件扩展名 = 明确勒索
|
||
(any of ($enc*)) and (any of ($ransomnote1, $ransomnote2)) and $ransomnote3
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C8-2 挖矿(xmrig / stratum+tcp / 矿池域名)
|
||
// =============================================================================
|
||
|
||
rule C8_Mining_Monero {
|
||
meta:
|
||
risk_level = "high"
|
||
category = "C8"
|
||
false_positive_rate = "low"
|
||
reference = "MITRE ATT&CK T1496 Resource Hijacking"
|
||
description = "挖矿程序特征:xmrig 命令行参数 / stratum+tcp / 矿池域名"
|
||
strings:
|
||
// xmrig 命令行特征
|
||
$xmrig1 = "xmrig" ascii nocase
|
||
$xmrig2 = /--donate-level\s+\d+/ ascii
|
||
$xmrig3 = /-o\s+stratum\+tcp/ ascii
|
||
$xmrig4 = /--cpu-priority\s+\d/ ascii
|
||
$xmrig5 = /--max-threads-hint/ ascii
|
||
|
||
// 矿池域名(Monero)
|
||
$pool1 = "pool.xmrig.com" ascii nocase
|
||
$pool2 = "pool.minexmr.com" ascii nocase
|
||
$pool3 = "pool.supportxmr.com" ascii nocase
|
||
$pool4 = "mine.moneropool.com" ascii nocase
|
||
$pool5 = "stratum+tcp://" ascii
|
||
|
||
// CPU 高占用循环特征
|
||
$loop = /(while|for)\s*\(\s*\d+\s*[<>=]/ ascii
|
||
$thread = "CreateThread" ascii
|
||
condition:
|
||
// 至少 2 个 xmrig 特征
|
||
(any of ($xmrig1, $xmrig2, $xmrig3, $xmrig4, $xmrig5)) and 2 of ($*)
|
||
or
|
||
// stratum+tcp 矿池协议 + 多个线程创建
|
||
$pool5 and ($thread or 2 of ($xmrig*))
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C9 壳特征(UPX / Themida / VMProtect / Enigma)
|
||
// 壳识别后建议升级到 L3 沙箱深检,不单独阻断
|
||
// =============================================================================
|
||
|
||
rule C9_Packer_UPX {
|
||
meta:
|
||
risk_level = "medium"
|
||
category = "C9"
|
||
false_positive_rate = "low"
|
||
reference = "UPX Packer"
|
||
description = "UPX 加壳 PE:节名 UPX0 / UPX1 + UPX 签名"
|
||
strings:
|
||
$upx0 = "UPX0" ascii
|
||
$upx1 = "UPX1" ascii
|
||
$upx2 = "UPX!" ascii
|
||
$upx3 = /UPX\s+\d+\.\d+/ ascii // "UPX 3.96" 这类版本字符串
|
||
$upx4 = /UPX\b/ ascii
|
||
condition:
|
||
// 节名(两个)+ 签名
|
||
($upx0 and $upx1) or ($upx2 and any of ($upx3, $upx4))
|
||
}
|
||
|
||
rule C9_Packer_Themida_VMP {
|
||
meta:
|
||
risk_level = "medium"
|
||
category = "C9"
|
||
false_positive_rate = "low"
|
||
reference = "Themida / VMProtect"
|
||
description = "商业壳特征:Themida / VMProtect 产品标识字符串"
|
||
strings:
|
||
$themida1 = "Themida" ascii wide
|
||
$themida2 = "WinLicense" ascii wide
|
||
$themida3 = "Oreans" ascii wide
|
||
$vmp1 = "VMProtect" ascii wide
|
||
$vmp3 = "VMProtect SDK" ascii wide
|
||
condition:
|
||
any of ($themida*) or any of ($vmp*)
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// C1-7 PE 高熵 + 大量网络 API(疑似加壳下载器)
|
||
// binary.py 的 HighEntropySection 已单独扫描,但 YARA 看"熵 + 网络"组合
|
||
// =============================================================================
|
||
|
||
rule C1_PE_EntropyHighNetwork {
|
||
meta:
|
||
risk_level = "medium"
|
||
category = "C1"
|
||
false_positive_rate = "medium"
|
||
reference = "binary.py HighEntropySection 联动"
|
||
description = "PE 同时出现:多个网络 API + 加壳特征(熵高) + 无签名"
|
||
strings:
|
||
$net1 = "InternetOpenUrl" ascii
|
||
$net2 = "WinHttpOpen" ascii
|
||
$net3 = "URLDownloadToFile" ascii
|
||
$net4 = "WSAConnect" ascii
|
||
// 壳特征
|
||
$upx = "UPX0" ascii
|
||
$themida = "Themida" ascii
|
||
condition:
|
||
// 网络 API + 壳特征 = 加壳下载器
|
||
any of ($net*) and ($upx or $themida)
|
||
}
|