Files
MeshSate/rules/ransom.yar
zhaolei b6a004bdb7 fix: 六引擎误报根因修复 — 解包递归、YARA 恒真规则、签名分级、real_type 溢出
检测范围与证据链修复,不改裁决口径(口径改动在下一条提交)。

- extractor:zip/tar 成员在超限分支外漏加回扫描队列,解包后内容永远不参与检测;
  zip 目录条目被当成内嵌对象;tar 超限成员先落盘不删。递归真正生效后深扫耗时可测。
- clamav:_HIGH/_MEDIUM/_UNWANTED 关键词是小写,而签名名是 "Win.Trojan..." 大小写混排,
  分级判定恒不命中全走默认档;改统一大写匹配。超过 clamd MaxFileSize 的裸奔区间
  (1G~1.5G) 新增 ClamAVSkippedSizeLimit(30) — 按"不可扫描不放行"进复核。
- yara:pe.yar C1 系列改用导入表判定,不再靠裸子串命中字符串表;
  linux.yar C7 多条规则条件恒真(裸 nc/fetch 之类)已收紧;C8/C3 相应收窄。
- structure:DangerousExecutableExtension 是载体信号而非恶意行为,critical 权重 45→35,
  不再作为把中低置信度信号一起顶过 block_score 的底座。
- scanner/documents:real_type 拼进 libmagic 对 MSI/OLE 的元数据串实测 334+ 字符,
  超列宽导致整条 scan_tasks INSERT 连 findings 一起丢(被拒文件不留痕)→
  列宽 256→512,migrate.sql 补 ALTER。
2026-11-02 20:26:56 +08:00

228 lines
9.7 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// =============================================================================
// MeshSafe L2B YARA 规则集 —— 勒索 / 挖矿专项(C8,剩余家族)
// =============================================================================
//
// 设计原则:
// - C8_Ransomware_Encryption 在 pe.yar 里已经覆盖了"加密 API + 卷影删除 + 勒索信"通用链
// - 本文件补充:具体家族特征(LockBit/BlackCat/Conti/Ryuk/Pseudo)+
// 文件扩展名黑名单变体 + 勒索信文件名模式
// - 必须满足"加密 API 组合 + 家族特征"才触发,单靠扩展名不触发
//
// 元数据规范:同 webshell.yar / pe.yar(risk_level, category, false_positive_rate)
// =============================================================================
// =============================================================================
// C8-1 LockBit 家族
// =============================================================================
rule C8_Ransomware_LockBit {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "LockBit / BitLocker 勒索家族"
description = "LockBit 家族特征:Mutex 名 + .lockbit3/.lockbit 扩展名 + CryptEncrypt"
strings:
$mutex1 = /Global\\[Ll]ock[Bb]it/ ascii
$mutex2 = /Local\\[Ll]ock[Bb]it/ ascii
$mutex3 = /LockBit[\d_]/ ascii nocase
$ext1 = /\.lockbit3?\b/ ascii nocase
$ext2 = /\.lckbt\b/ ascii nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptGenKey/ ascii
$ransomnote = /README[\d_-]*\.(html|txt|bmp|png|jpg|url)/ nocase
condition:
// Mutex + 加密 API(家族识别核心)
any of ($mutex*) and any of ($enc*)
or
// Mutex + 勒索扩展名
any of ($mutex*) and any of ($ext*)
or
// 加密 API + 家族扩展名 + 勒索信
any of ($enc*) and any of ($ext*) and $ransomnote
}
// =============================================================================
// C8-2 BlackCat / ALPHV 家族
// =============================================================================
rule C8_Ransomware_BlackCat {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "BlackCat (ALPHV) 勒索家族"
description = "BlackCat/ALPHV:Mutex + .blackcat/.bc1 扩展名 + Rust 字符串特征"
strings:
$mutex1 = /Global\\[Bb]lack[Cc]at/ ascii
$mutex2 = /[Aa][Ll][Pp][Hh][Vv]/ ascii
$ext1 = /\.blackcat\b/ ascii nocase
$ext2 = /\.bc1?\b/ ascii nocase
$rust1 = "rustc" ascii
$rust2 = "/rustc/" ascii
$enc = /CryptEncrypt|BCryptEncrypt/ ascii
$note = /BlackCat.*README|how_to_decrypt|restore_files/ ascii nocase
condition:
any of ($mutex1, $mutex2) and any of ($enc*, $ext*)
or
any of ($ext*) and any of ($rust*) and $note
}
// =============================================================================
// C8-3 Conti 家族
// =============================================================================
rule C8_Ransomware_Conti {
meta:
risk_level = "critical"
category = "C8"
false_positive_rate = "low"
reference = "Conti 勒索家族"
description = "Conti:Mutex + .conti 扩展名 + 加密 API"
strings:
$mutex1 = /Global\\[Cc]onti/ ascii
$mutex2 = /Local\\[Cc]onti/ ascii
$ext1 = /\.conti\b/ ascii nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
any of ($mutex*) and any of ($enc*, $ext*)
or
any of ($ext*) and any of ($enc*)
}
// =============================================================================
// C8-4 Ryuk / Pseudo / Dharma 家族
// =============================================================================
rule C8_Ransomware_Ryuk_Pseudo {
meta:
risk_level = "high"
category = "C8"
false_positive_rate = "medium"
reference = "Ryuk / Pseudo / Dharma 勒索家族"
description = "Ryuk/Pseudo: RyukTask Mutex + 加密 API + .ryk/.pseudo 扩展名"
strings:
$mutex_ryuk = /RyukTask[\d]/ ascii
$mutex_pseudo = /Global\\[Pp]seudo/ ascii
$mutex_dharma = /Global\\[Dd]harma/ ascii
$ext_ryk = /\.ryk\b/ ascii nocase
$ext_pseudo = /\.pseudo\b/ ascii nocase
$ext_dharma = /\.dharma\b/ ascii nocase
$enc = /CryptEncrypt|CryptDeriveKey/ ascii
condition:
(any of ($mutex_ryuk, $mutex_pseudo, $mutex_dharma))
and (any of ($enc*, $ext_ryk, $ext_pseudo, $ext_dharma))
}
// =============================================================================
// C8-5 勒索信文件名模式(独立规则,辅助 family 识别)
// =============================================================================
rule C8_Ransomware_Note_Filename {
meta:
risk_level = "medium"
category = "C8"
false_positive_rate = "low"
reference = "勒索信文件名通用模式"
description = "勒索信文件名 + (加密 API + 赎金语言)或(赎金语言 + 钱包地址)"
strings:
// 只保留"文件名形态"的勒索信特征:家族专有名 + 扩展名。
// 不再用裸 README.txt / _readme.txt:任何安装包都带这两个字面量,
// 在二进制内容上做全文匹配时必然命中(Go 官方 MSI 即被这样判成恶意)。
$n1 = /HOW_TO_RECOVER[\w.-]*\.(txt|html|png|bmp|jpg|url|vbs|js)/ nocase
$n2 = /RESTORE_FILES[\w.-]*\.(txt|html|png|bmp|jpg|url|vbs|js)/ nocase
$n3 = /DECRYPT_INSTRUCTIONS[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n4 = /README[._-]*(FOR[._-]*DECRYPT|TO[._-]*RESTORE)[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n5 = /HELP_DECRYPT[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n6 = /\b_(readme|restore)[\w.-]*\.(txt|html|png|bmp|jpg|url)/ nocase
$n7 = /(how_to_decrypt|restore_my_files|decrypt_your_files)[\w.-]*\.(txt|html)/ nocase
// 赎金语言:必须是完整词组。裸 "BTC"/"XMR"/"payment"/"ransom" 在压缩流里
// 会以随机字节出现,"ransom" 还会被 "Ransomware" 子串命中。
$payment = /(bitcoin|monero|xmr|btc)\s+(address|wallet)|send\s+(the\s+)?money|pay\s+(the\s+)?(ransom|fee)|\bransom\b\s+(note|payment|demand)|your\s+files\s+(are\s+)?encrypted|decrypt\s+your\s+files/ nocase
// 钱包地址:锚定到整个 token,并用真实地址字符集/长度。
// 原写法 1[A-Za-z0-9]{25,34} 无边界,单个 56MB 安装包命中 7.6 万次。
$btc_addr = /\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b/
$bech32 = /\bbc1q[a-z0-9]{38}\b|\bbc1q[a-z0-9]{58}\b/
$xmr_addr = /\b[48][0-9A-Za-z]{94}\b/
$encapi = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
any of ($n*)
and (
// 投递器:真加密 API + 赎金语言
($encapi and $payment)
or
// 纯文本勒索信:赎金语言 + 具体钱包地址
($payment and any of ($btc_addr, $bech32, $xmr_addr))
)
}
// =============================================================================
// C8-6 加密文件扩展名黑名单(不单独触发,配合加密 API)
// =============================================================================
rule C8_Ransomware_Extension_Blacklist {
meta:
risk_level = "low"
category = "C8"
false_positive_rate = "medium"
reference = "勒索加密文件扩展名模式"
description = "常见勒索加密扩展名(.locky/.zepto/.cryptolocker/.encrypted/.virus/.tor/.crpt 等)+ 加密 API"
strings:
$ext1 = /\.locky\b/ nocase
$ext2 = /\.zepto\b/ nocase
$ext3 = /\.cryptolocker\b/ nocase
$ext4 = /\.cryptor\b/ nocase
$ext5 = /\.crypt\b/ nocase
$ext6 = /\.encrypted\b/ nocase
$ext7 = /\.virus\b/ nocase
$ext8 = /\.tor\b/ nocase
$ext9 = /\.crpt\b/ nocase
$ext10 = /\.wallet\b/ nocase
$ext11 = /\.pay2[\w.-]*\.?\w*\b/ nocase
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
$note = /HOW_TO_RECOVER|RESTORE_FILES|DECRYPT_INSTRUCTIONS|README/ nocase
condition:
// 扩展名 + 加密 API + 勒索信 = 完整勒索链
any of ($ext*) and $enc and $note
or
// 扩展名 + 加密 API(至少 2 种扩展名变体)
(2 of ($ext*)) and $enc
}
// =============================================================================
// C8-7 卷影删除专项(辅助勒索前置)
// =============================================================================
rule C8_Ransomware_VolumeShadow {
meta:
risk_level = "high"
category = "C8"
false_positive_rate = "medium"
reference = "MITRE ATT&CK T1490 Inhibit System Recovery"
description = "删除卷影副本:vssadmin / wmic shadowcopy + 加密 API"
strings:
$vss1 = "vssadmin delete shadows" ascii
$vss2 = /vssadmin\s+delete\s+shadows\s+\/all\b/ ascii
$wmic1 = /wmic\s+shadowcopy\s+delete/ ascii
$wmic2 = /wmic\s+shadowcopy\s+where\s+\d+/ ascii
$vss4 = /vssadmin[^\n]{0,48}delete[^\n]{0,48}(shadows|shadow\s+copies)/ ascii
$enc = /CryptEncrypt|BCryptEncrypt|CryptDeriveKey/ ascii
condition:
// 卷影删除 + 加密 API = 完整勒索前置
// 不用裸 "vss"/"ShadowCopy" 子串:任何备份/卷影库的符号表都有它们,
// 和 CryptEncrypt 同框就报勒索,是典型误报来源。
(any of ($vss1, $vss2, $wmic*, $vss4)) and any of ($enc*)
or
// 连续多次 vssadmin delete = 正在清卷影
any of ($vss1, $vss2) and any of ($wmic*)
}