fix: 裁决口径重构 — rule_overrides 改处置地板,YARA 权重分档与阈值解耦

三件事,都围绕"分数只反映证据,不放行由地板保证":

- rule_overrides 的 manual_review 旧实现是 score=max(score,65) 并跳过该规则自身权重:
  注进去的 65 不是证据,再叠任意 ≥5 分噪声就越过 block_score=70 变拒绝,同时显示分数
  与真实证据脱钩。改为步骤 9「复核地板」:权重照常累加,裁决后处置低于复核才抬到
  manual_review,已判 reject 不降回。3661 条历史扫描重放 0 收紧 0 放行;把 review_score
  下界抬到 36/40/50 或把 DEE 权重降到 10,无地板时干净 exe 静默放行,有地板恒为人工复核。
- DangerousExecutableExtension 进 rule_overrides(manual_review),落实光闸口径「EXE/DLL/
  脚本不自动放行」,不再依赖 weight=30 恰好等于 review_score 下界这种数值巧合。
- YARA 权重分档 85/65/45/25 → 85/60/30/10,只有 critical 一档能独立越过 70;
  档位与 rules/*.yar 的 meta.risk_level 一一对应,控制台注释与 policy.html 同步。
- 词表:RemoteDownloadUnix/PowerShell 移出零容忍、改判"工具与 URL/IP 同框",
  新增 RemoteDownloadExec(40)/PayloadDropToDisk(45) 带内网源站白名单。裸 cmdlet 名会把
  nvidiaInspector.exe 的 add_DownloadFileCompleted 白送 30 分,把 45 分复核顶成 75 分拒绝。
- 风险等级文案:裁决已是 malicious/error 时仍输出"打开风险低"是自相矛盾的对外文案,
  强制收敛到 critical。
- 靶场 L5-005 expected_verdict reject→review:旧 85 分靠载体45+时间戳20+未签名10+架构10
  堆叠,属权重堆叠误报;真实注入器由 C1_PE_ProcessInjection(85) 拦截。
This commit is contained in:
2026-11-02 20:27:30 +08:00
parent b6a004bdb7
commit f1a176aae0
6 changed files with 154 additions and 73 deletions

View File

@@ -67,8 +67,6 @@ zero_tolerance_rules:
- ReverseShellPowershell # PowerShell 反弹 Shell (-enc)
- CredentialStealer # 凭据窃取工具 (mimikatz/sekurlsa/wce/...)
- CredentialExport # 凭据导出命令 (reg save/reg export/...)
- RemoteDownloadUnix # Unix 远程下载执行 (curl|wget|certutil)
- RemoteDownloadPowerShell # PowerShell 远程下载执行 (IWR/DownloadString)
# ---------- 文件类型白名单 ----------
# 只允许这些类型通过。空列表表示不限制(不推荐生产使用)。
@@ -217,6 +215,12 @@ sandbox_required_extensions:
# rule_name: [action, reason_override]
# action 取值:pass / pass_with_flag / manual_review / reject / reject_and_notify
rule_overrides:
# 光闸口径:EXE/DLL/脚本一律不自动放行,最低人工复核。
# 用 override 而不是靠 weight=30 恰好等于 review_score 下界来维持——
# 数值巧合意味着把下界调到 >35 或把权重降一点,干净可执行文件就会静默放行。
DangerousExecutableExtension:
action: manual_review
reason: "可执行/脚本类型文件,按光闸口径最低转人工复核"
VBAShellInvocation:
action: manual_review
reason: "宏调用 Shell 但无自动执行入口,需人工复核"
@@ -255,58 +259,60 @@ notification:
max_reason_length: 500
# ---------- YARA 规则权重映射 ----------
# 按规则名精细设定权重(0-100),覆盖 binary.py 里的默认 weight=50
# 命中但不在下列名单中的规则 weight 保持默认值 50
# 严重度分档由规则内 meta.risk_level 决定(critical/high/medium/low)
# 档位权重与 rules/*.yar 的 meta.risk_level 一一对应(由 binary.py 读取 meta 得到
# 默认严重度,再用本表覆盖为固定权重,保证规则文件与策略只有一处真相)。
# critical=85(单独命中即 reject)/ high=60 / medium=30 / low=10
# 只有 critical 一档可以独立越过 block_score=70;其余档位需与其他信号叠加。
# 不在本表的规则:沿用 meta.risk_level 推导出的默认权重。
yara_rule_weights:
critical: # weight=85
- C3_PHP_Webshell_Oneliner
- C3_JSP_Webshell_RuntimeExec
- C3_Webshell_Behinder
- C1_PE_ProcessInjection
- C8_Ransomware_Encryption
- C8_Ransomware_LockBit
- C8_Ransomware_BlackCat
- C8_Ransomware_Conti
- C1_PE_RAT_CommandControl
- C3_JSP_Webshell_Deserialization
- C3_JSP_Webshell_RuntimeExec
- C3_PHP_Webshell_Oneliner
- C3_Webshell_Behinder
- C3_Webshell_CommandExecutionEcho
- C3_Webshell_Godzilla
- C7_Linux_ReverseShell_Bash
- C7_Linux_ReverseShell_NC
- C7_Linux_Rootkit_KernelModule
high: # weight=65
- C8_Ransomware_BlackCat
- C8_Ransomware_Conti
- C8_Ransomware_Encryption
- C8_Ransomware_LockBit
high: # weight=60
- C1_PE_DLLHijacking
- C1_PE_Downloader_Loader
- C1_PE_LOLBin_Usage
- C3_JSP_Webshell_MemoryShell
- C3_PHP_Webshell_Obfuscated
- C3_PHP_Webshell_VariableDeformation
- C3_Webshell_CommandExecutionEcho
- C3_Webshell_Godzilla
- C1_PE_Downloader_Loader
- C1_PE_RAT_CommandControl
- C1_PE_LOLBin_Usage
- C1_PE_Mutex_Persistence
- C7_Linux_ReverseShell_Python
- C7_Linux_ReverseShell_Perl
- C7_Linux_ReverseShell_Socat
- C7_Linux_Persistence_Crontab
- C7_Linux_Persistence_SystemD
- C3_Webshell_ASP_Classic
- C3_Webshell_ASPNET
- C3_Webshell_AntSword
- C7_Linux_Persistence_AuthorizedKeys
- C7_Linux_Persistence_Crontab
- C7_Linux_Persistence_LD_PRELOAD
- C8_Ransomware_VolumeShadow
- C8_Ransomware_Note_Filename
- C7_Linux_Persistence_SystemD
- C7_Linux_ReverseShell_Perl
- C7_Linux_ReverseShell_Python
- C7_Linux_ReverseShell_Socat
- C8_Mining_Monero
- C8_Ransomware_Ryuk_Pseudo
medium: # weight=45
- C9_Packer_UPX
- C9_Packer_Themida_VMP
- C1_PE_DLLHijacking
- C8_Ransomware_VolumeShadow
medium: # weight=30
- C1_PE_EntropyHighNetwork
- C1_PE_Mutex_Persistence
- C7_Linux_Miner_Generic
- C7_Linux_ReverseShell_Misc
- C7_Misc_Ruby_Lua_ReverseShell
- C7_Network_Tools_Malicious
- C3_Webshell_AntSword
- C3_Webshell_ASPNET
- C3_Webshell_ASP_Classic
- C3_JSP_Webshell_Deserialization
- C3_JSP_Webshell_MemoryShell
- C3_Webshell_CommandExecutionEcho
- C8_Ransomware_Note_Filename
- C9_Packer_Themida_VMP
low: # weight=10
- C8_Ransomware_Extension_Blacklist
low: # weight=25
- C7_Linux_ReverseShell_Misc
- C9_Packer_UPX
# ---------- 内网特征词表引擎(P1)----------
@@ -339,26 +345,55 @@ keyword_rules:
# 恶意行为特征词表(覆盖 CSV L3 全部 25 条用例)
# ================================================================
# ---- 远程下载执行 ----
# ---- 远程下载即执行(要有完整动作链,裸词不算;README 里的安装命令进复核而非直接拒)----
# cross_line:命令换行/续行是本类特征最常见的绕过(curl \ + 下一行 | sh),
# 拼接后仍要求"下载工具 + 执行动作"同框,散文里的多行文本不会凑出这条链。
- name: RemoteDownloadExec
match: regex
pattern: "(?:\\b(?:curl|wget)\\b[^\\n]{0,120}\\|\\s*(?:ba|z|k|da)?sh\\b|\\b(?:curl|wget)\\b[^\\n]{0,120}(?:&&|;)\\s*(?:chmod\\s+\\+x|\\./)|(?:^|[^\\w$-])(?:iex|invoke-expression)\\b[^\\n]{0,60}(?:\\biwr\\b|invoke\\s*[-_]?\\s*web\\s*[-_]?\\s*request|invoke\\s*[-_]?\\s*rest\\s*[-_]?\\s*method|downloadstring)|\\b(?:iwr|invoke\\s*[-_]?\\s*web\\s*[-_]?\\s*request|invoke\\s*[-_]?\\s*rest\\s*[-_]?\\s*method)\\b[^\\n]{0,120}\\|\\s*(?:iex|invoke-expression)\\b|certutil\\s+[-/]urlcache[^\\n]{0,60}\\.exe\\b|mkfifo[^\\n]{0,60}(?:\\bnc\\s|\\bnetcat\\b))"
ignore_case: true
cross_line: true
weight: 40
severity: critical
# ---- 下载并落地成可执行文件(dropper 行为,比"下载即执行"弱一档但仍高危)----
- name: PayloadDropToDisk
match: regex
pattern: "(?:\\b(?:curl|wget)\\b[^\\n]{0,120}(?:-o|-O|--output)\\s+\\S*\\.(?:exe|dll|ps1|bat|cmd|vbs|jar|msi|so|bin)\\b|\\b(?:i\\s*[-_]?\\s*wr|invoke\\s*[-_]?\\s*web\\s*[-_]?\\s*request|invoke\\s*[-_]?\\s*rest\\s*[-_]?\\s*method)\\b[^\\n]{0,120}-o(?:utfile)?\\s+\\S*\\.(?:exe|dll|ps1|bat|cmd|vbs)\\b|\\b(?:new-object|activexobject)\\s+system\\.net\\.webclient[^\\n]{0,80}downloadfile)"
ignore_case: true
cross_line: true
weight: 45
severity: critical
# ---- 外部下载动作(cmdlet/API + 无执行链):计分进复核,不再零容忍 ----
# cmdlet 名(Invoke-WebRequest/Invoke-RestMethod/BitsAdmin)是 PowerShell 专有写法,
# 单独出现即进复核。.NET/Win32 的方法名(DownloadString/DownloadFile)不一样——
# 它们存在于所有托管程序的标识符表里,裸匹配实测把 nvidiaInspector.exe 的
# `add_DownloadFileCompleted`、`DownloadFileAsync` 各算一次命中,白送 30 分,
# 把 45 分的人工复核顶成 75 分拒绝。所以方法名必须与 URL/IP 同框才算下载。
- name: RemoteDownloadPowerShell
match: regex
pattern: "(Invoke-WebRequest|Invoke-RestMethod|DownloadString|DownloadFile|Start-BitsTransfer|BitsAdmin)"
ignore_case: true
weight: 35
severity: high
- name: RemoteDownloadUnix
match: regex
pattern: "(\\bwget\\b|\\bcurl\\b|\\bcertutil\\s+-urlcache\\s+-split|\\bfetch\\b)"
pattern: "(?:\\b(?:Invoke-WebRequest|Invoke-RestMethod|Start-BitsTransfer|BitsAdmin)\\b|\\bDownload(?:String|File)\\b[^\\n]{0,40}(?:https?://|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|(?:https?://|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})[^\\n]{0,40}\\bDownload(?:String|File)\\b)"
ignore_case: true
weight: 30
severity: high
severity: medium
# ---- 下载工具 + 明确地址:只认"工具与 URL/IP 同框",裸 -o 参数不算 ----
# 旧写法里的 `curl|wget -O/-o 任意值` 会命中任何写成两段的安装文档,去掉。
- name: RemoteDownloadUnix
match: regex
pattern: "(?:\\b(?:curl|wget|certutil)\\b[^\\n]{0,80}(?:https?://|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))"
ignore_case: true
weight: 30
severity: medium
# ---- 反弹 Shell ----
- name: ReverseShellNetcat
match: regex
# nc/ncat 后必须跟参数 (如 -e/-l/-p/-v/-s),单独 nc 在二进制里必然误报
pattern: "(\\bnc\\s+-[elpvs]\\w*|\\bncat\\s+-\\w+|\\bnetcat\\b|/dev/tcp/|bash\\s+-i\\s+>&|sh\\s+-i\\s+>&)"
# 只认「执行原语」形态:nc/ncat/netcat 带 -e/-c(把 shell 交给连接),
# 或 /dev/tcp、bash -i >& 这类内核级反连。裸 nc / nc -l / nc -z 是运维常用,
# 出现在速查文档和二进制字符串表里必然误报,不计分。
pattern: "(\\b(?:nc|ncat|netcat)\\s+(?:[^\\n]{0,60}\\s)?-[ec]\\w*\\s*(?:/bin/|/usr/|cmd\\.exe\\b|\\S*sh\\b)|/dev/tcp/|bash\\s+-i\\s+>&|sh\\s+-i\\s+>&)"
ignore_case: true
weight: 40
severity: critical
@@ -430,6 +465,32 @@ keyword_whitelist:
- ".senmesh.com"
- "repo.internal"
- "mirror.internal"
- rule: RemoteDownloadExec # 下载即执行:内网源站安装脚本按白名单放行
allowed_keywords:
- "192.168."
- "10."
- "172.16."
- "172.17."
- "172.18."
- "172.19."
- "172.2"
- "172.3"
- ".senmesh.com"
- "repo.internal"
- "mirror.internal"
- rule: PayloadDropToDisk # 下载落地可执行文件:内网源站安装包放行
allowed_keywords:
- "192.168."
- "10."
- "172.16."
- "172.17."
- "172.18."
- "172.19."
- "172.2"
- "172.3"
- ".senmesh.com"
- "repo.internal"
- "mirror.internal"
- rule: RemoteDownloadPowerShell # Invoke-WebRequest/BitsAdmin
allowed_keywords:
- "192.168."