核心功能: - 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
103 KiB
MeshSafe 文件安全检测服务 · 总体方案
| 项目 | 内容 |
|---|---|
| 系统名称 | MeshSafe 文件安全检测服务 |
| 版本 | v1.0(方案稿) |
| 文档状态 | 待评审 |
| 适用场景 | 光闸内外网文件摆渡场景下的文件安全检测 |
| 合规要求 | 满足网络安全等级保护三级相关控制项 |
目录
1. 背景与目标
1.1 现状
现有系统为一套基于光闸的内外网数据交换系统,核心能力是文件摆渡、解包与展示,并支持按预设文件格式限制上传。当前缺少针对被摆渡文件的独立安全检查能力,文件"能不能传"仅由格式白名单决定,无法回答"这个文件本身是否安全"。
1.2 目标
建设一个独立部署、可被外部应用调用的专用检测服务,对摆渡文件执行多层次安全检查,向调用方返回结构化的检测结论与处置建议。
核心目标:
| 编号 | 目标 |
|---|---|
| G1 | 提供 RESTful 检测接口,外部应用(光闸摆渡系统)可调用并获得结构化结论 |
| G2 | 覆盖恶意性、可执行性、合规性三类风险判据 |
| G3 | 全组件私有化部署,运行期不依赖公网 |
| G4 | 满足等保三级相关控制项(身份鉴别、访问控制、安全审计、数据完整性与保密性等) |
| G5 | 检测引擎、签名规则、裁决策略均可独立升级,不与摆渡软件耦合 |
| G6 | 提供在线自测控制台,降低对接方联调成本 |
1.3 方向定位:一期只做「外网 → 内网」
本服务一期聚焦外网向内网传入方向的检测,内网向外网传出方向的内容审计暂不纳入,列为待定项。
| 方向 | 一期范围 | 说明 |
|---|---|---|
| 外网 → 内网 | ✅ 完整覆盖 | 核心风险是"外部文件伤到内网",即恶意代码与可执行性风险 |
| 内网 → 外网 | ⏸ 待定 | 核心风险是"内部内容违规外泄",属内容审计范畴,依赖业务场景建模 |
为什么一期不内做内容审计
外发方向的内容审计需要回答"这段内容是否允许离开内网",其判定依据是业务规则——哪些案件材料涉密、哪些个人信息不得外传、哪些类型需审批。这些规则高度依赖具体业务场景与密级标准,在场景未明确前设计检测逻辑,产出大概率不可用。
相比之下,内入方向的判定依据是技术事实(这个文件是否有害),与业务规则耦合度低,可以立即工程化。
架构上为后续预留:内容审计所需的"文本抽取 → 分类 → 规则裁决"链路,与本方案 L0 文本准备层、策略引擎的形态完全一致。届时只需新增 L-S 语义层与内容规则集,不需重构架构。
1.4 非目标(明确不做)
| 不做项 | 原因 |
|---|---|
| 内容清洗 / 文件改写 | 本服务只做"判定",不做"加工"。原文件仍由摆渡系统处置 |
| 解包后内容对外输出 | 用户已明确不返回解包内容,仅返回检测结论 |
| 用户 / 权限 / 文档管理系统 | 独立成品的检测服务,不做 OA 能力 |
| 动态沙箱(P4 一期不实现) | 资源开销大、对光闸场景收益有限,架构预留 |
| 内网外发内容审计 | 一期聚焦外网→内网方向;外发方向依赖业务密级规则,场景待定(见 §1.3) |
| 内容敏感信息识别 | 与恶意代码检测属不同问题域,一期不做 |
2. 范围界定
2.1 风险判据分类
光闸场景下,"外网传入的文件是否安全"实际包含三类相互独立的判据。原方案仅覆盖第一类,这是需要补齐的核心缺口。
| 判据 | 关注点 | 典型风险 | 主要覆盖层 |
|---|---|---|---|
| 恶意性 | 会不会伤到内网 | 病毒、木马、勒索、挖矿 | L1 ClamAV、L2B YARA |
| 可执行性 | 传进去会不会自动运行 | VBA 宏、DDE、双扩展名、内嵌可执行对象 | L0 结构层、L2 文档深度 |
| 合规性 | 是不是不允许传的东西 | 类型不符、超大文件、加密压缩包、路径穿越 | L0 结构层、全局策略 |
关键结论:可执行性判据在光闸场景中发生频率最高。一个带宏的
.docx在 ClamAV 判定为"干净",但在内网被双击打开时宏即刻执行。因此本方案将 L2 文档深度检测与全局格式策略作为重点,而非动态沙箱。
2.1.1 方向差异带来的重点偏移
一期只做外网→内网,因此三类判据的权重与内网外发方向不同:
| 判据 | 外网→内网(一期) | 内网→外网(待定) |
|---|---|---|
| 恶意性 | 核心,权重最高 | 次要 |
| 可执行性 | 核心,权重最高 | 次要 |
| 合规性 | 次要(类型/大小/密级约束较弱) | 核心(涉及密级与外传审批) |
| 内容语义 | 辅助(识别伪装与诱导) | 核心(识别涉密与违规内容) |
这解释了为什么一期的能力重心放在恶意性 + 可执行性上,以及为什么大模型在内入方向的定位是"识别伪装与诱导"而非"判定涉密"。
2.2 支持的输入格式
| 类别 | 格式 |
|---|---|
| Office 文档 | doc / docx / docm / xls / xlsx / xlsm / ppt / pptx / pptm / rtf / odt / ods / odp |
| 归档 | zip / rar / 7z / tar / gz / bz2 / xz / cab / iso / jar / apk |
| 图像 | jpg / jpeg / png / gif / bmp |
| Windows 可执行 | exe / dll / msi / scr / com / cpl / jar / apk |
| Linux 可执行 | .elf / .so / .desktop / .appimage / .deb / .rpm / .run / .bin / .snap / .flatpak |
| 脚本 | bat / cmd / ps1 / vbs / vbe / js / jse / hta / wsf / sh / bash / zsh / py / pl / rb |
| 文本 | txt / csv / json / xml / html / log |
2.3 单文件与批量限制
| 约束 | 默认值 | 配置项 |
|---|---|---|
| 单文件大小上限 | 50 MB | policy.global.max_file_size |
| 同步模式处理上限 | 50 MB | policy.global.sync_max_size |
| 上传硬上限 | 2048 MB | MESHSAFE_MAX_UPLOAD_MB |
| 解包深度上限 | 5 层 | MESHSAFE_MAX_EXTRACT_DEPTH |
| 解包总量上限 | 4096 MB | MESHSAFE_MAX_EXTRACT_TOTAL_MB |
| 压缩比上限 | 100:1 | MESHSAFE_MAX_EXTRACT_RATIO |
3. 总体架构
3.1 分层视图
┌──────────────────────────────────────────────────────────────┐
│ 接入层 API 网关 · mTLS/Token 认证 · 限流 · 请求/响应签名 │
├──────────────────────────────────────────────────────────────┤
│ 接收层 文件接收 · 类型识别 · 递归解包 · 哈希计算 │
├──────────────────────────────────────────────────────────────┤
│ 检测层 L0 结构 │ L1 ClamAV │ L2 文档 │ L2B YARA/二进制 │
├──────────────────────────────────────────────────────────────┤
│ 裁决层 策略引擎 · 风险评分 · 处置动作映射 │
├──────────────────────────────────────────────────────────────┤
│ 留存层 结论存储 · 审计日志(哈希链)· 报告生成 │
└──────────────────────────────────────────────────────────────┘
3.2 关键架构决策
决策 1:独立服务,不嵌入摆渡软件
理由:摆渡软件负责数据搬运(数据平面),检测服务负责安全判定(控制平面)。若耦合,升级检测引擎就必须重新发布摆渡软件——在政务/法院内网环境下,这是不可接受的发布风险。
后果:需要设计稳定的接口契约,接口版本必须严格管理(见 §6.6)。
决策 2:检测引擎作为独立进程组
ClamAV 守护进程、YARA 规则库、文档解析库在容器内独立运行或独立容器化。好处:
- 引擎崩溃不影响 API 服务的可用性(引擎异常被捕获并降级为"引擎不可用"信号)
- 引擎可独立升级(ClamAV 签名库每日更新不影响应用镜像)
- 资源可独立限制(clamd 内存占用大,需单独限制)
决策 3:同步与异步双模式
| 模式 | 触发条件 | 行为 |
|---|---|---|
| 同步 | 文件 ≤ sync_max_size 且不需沙箱 |
请求内完成检测并直接返回结论 |
| 异步 | 文件超限或命中强制沙箱规则 | 返回 task_id,调用方轮询或等待回调 |
理由:同步模式延迟低(摆渡业务最常用);异步模式避免 HTTP 长连接超时给网关造成压力,也让未来接入沙箱时无需改动接口。
决策 4:检测在隔离区完成,单向数据流
摆渡系统 ──── 文件内容 ────▶ 检测服务 ──── 检测结论 ────▶ 摆渡系统
│
└── 绝不主动连外网
检测服务不修改、不回写被检文件。病毒库与规则库通过单向导入方式更新(见 §8.3)。
决策 5:全局单策略
按用户确认,本期采用全局单策略,不按业务通道区分。策略引擎在实现上保留通道扩展位(channel 字段贯穿全链路),后续扩展无需重构。
4. 检测能力设计
4.1 五层流水线总览
| 层 | 引擎 | 检查对象 | 关键信号 | 典型时延 |
|---|---|---|---|---|
| L0 | structure / extractor | 全部文件 | 扩展名伪装、双扩展名、危险可执行类型、zip bomb、路径穿越、嵌套过深 | 毫秒 |
| L0 | link / shortcut | LNK 等 | 目标指向可执行体或远程路径 | 毫秒 |
| L1 | ClamAV | 全部文件 | 已知木马 / 勒索 / 挖矿签名命中、启发式检测 | 秒 |
| L2 | oletools / PDF 解析 | Office、PDF、RTF、脚本 | VBA 宏、DDE/DDEAUTO、嵌入对象、PDF JavaScript、外部链接、脚本混淆 | 秒 |
| L2C | links / qrcode | 文档与图片 | 外部 URL、二维码内容、可疑域名 | 秒 |
| L2B | YARA / pefile | PE、脚本、内存马 | 家族规则命中、危险能力组合、壳与免杀、签名异常 | 秒 |
| L3 | 沙箱(长期可选项) | 可执行文件 | 释放文件、持久化、外联 C2 | 分钟 |
场景定位:本服务的文件最终由人工在内网终端打开,自动化处理极少。这一前提决定了能力重心——所有「打开即执行」的载体必须零容忍拦截(见 §4.8)。
4.2 L0 结构与完整性层
这一层最快、最廉价,却能挡掉大量"人工伪装"类攻击,是性价比最高的一层。
4.2.1 真实类型识别
- 双引擎识别:
libmagic(python-magic)+ 内置魔数表作为兜底 - 不信任扩展名,一律以内容判定真实类型
- OOXML 容器(docx/xlsx/pptx)通过检查内部部件名区分,避免被误判为普通 zip
4.2.2 伪装检测规则
| 规则名 | 触发条件 | 默认严重度 |
|---|---|---|
ExtensionMismatch |
声明扩展名与真实类型不相容 | HIGH |
DoubleExtension |
文件名含两个以上扩展名,且前缀为危险类型 | HIGH |
DangerousExecutableExtension |
顶层文件为 exe/scr/dll/com/pif 等 | CRITICAL / HIGH |
ArchiveContainsExecutable |
归档内含可执行成员 | HIGH |
ArchiveBombSuspect |
压缩比超过阈值 | HIGH |
ArchiveTooLarge |
解压总量超限 | HIGH |
PathTraversal |
归档内含路径穿越条目 | CRITICAL |
ArchiveTooManyMembers |
归档成员数异常(>10000) | MEDIUM |
4.2.3 递归安全解包
这是最容易被遗漏、也是最关键的一环。 只扫描外层压缩包是最常见的绕过手法。
安全约束(全部强制执行):
| 约束 | 行为 |
|---|---|
| 解包深度 | 超过 max_extract_depth 停止并记录信号 |
| 解压总量 | 累计超过 max_extract_total_mb 停止 |
| 单成员大小 | 超过单文件上限则跳过该成员 |
| 压缩比 | 单成员压缩比超阈值则跳过并记录 ArchiveBombBlocked |
| 路径穿越 | 拦截含 ..、绝对路径、盘符的条目 |
| 符号链接 | tar 中的 symlink/hardlink 一律拦截 |
| 文件名 | 解包后文件名重写为安全形式,原始名保留在逻辑路径中供追溯 |
解包出的文件自动进入待检测队列,形成递归检测。
4.2.4 加密文件识别
- Office 加密文档 →
PdfEncrypted/ 加密标记信号 - 加密压缩包 → 记录为不可静态分析
按策略,加密文件默认拒绝(无法确认安全),除非策略显式放开。
4.3 L1 ClamAV 层
4.3.1 部署方式
使用 clamd 常驻守护进程(TCP 或 Unix Socket),而非 clamdscan 一次性调用。理由:签名库加载到内存需数秒至数十秒,常驻模式可支撑并发扫描。
4.3.2 离线签名库更新机制
这是内网部署最容易失效的环节,必须做成自动化流程:
外网侧签名库同步机
│ 每日定时执行 freshclam,拉取官方 CVD
▼
本地私有镜像(cvdupdate 模式 / freshclam 私有镜像模式)
│ 通过单向导入介质(摆渡光闸 / 刻录介质)传入内网
▼
内网签名库分发节点
│ 内网节点增量同步
▼
clamd 容器(签名库版本记入扫描结果 meta)
要求:签名库版本号与更新时间必须包含在检测结果中,作为检测有效性的举证材料。
4.3.3 命中强度分级
ClamAV 2025 起区分三类命中强度,建议在策略中区分对待:
| 类型 | 含义 | 本方案处置 |
|---|---|---|
| Strong Indicator | 传统签名命中,扫描立即中止 | 视为确凿恶意 |
| Potentially Unwanted | 可疑软件,扫描结束时告警 | 视签名关键词判定为 MEDIUM |
| Weak Indicator | 低置信度命中 | 降权处理 |
4.4 L2 文档深度检测层
本方案的重点层,直接对应光闸场景最高频的实际风险。
| 格式 | 工具 | 检测内容 |
|---|---|---|
| doc / docm / xls / ppt | oletools.olevba |
VBA 宏提取与代码分析 |
| 同上 | oletools.mraptor |
宏的整体启发式判定(AutoExec + 可疑关键词 + 编码字符串) |
| 同上 | oletools.msodde |
DDE / DDEAUTO 自动执行字段 |
| 同上 | oletools.oleobj |
内嵌 OLE 对象,识别内嵌可执行体 |
| docx / xlsx / pptx | 自研 OOXML 解析 | 外部链接部件、嵌入对象、外部 URI、附加模板、DDEAUTO、文档变量 |
pypdf |
JavaScript 动作、LaunchAction、OpenAction、外部 URI、内嵌文件、加密状态 | |
| rtf | oletools.rtfobj |
OLE 嵌入对象 |
| ps1 / bat / vbs / js | 正则特征集 | 编码命令、Base64 解码执行、下载器、隐藏窗口、关闭防护、勒索前置行为 |
4.4.1 VBA 宏判定分级
| 条件 | 规则名 | 严重度 | 默认权重 |
|---|---|---|---|
| 自动执行入口 + 调用系统命令/外联 | VBAAutoExecShell |
CRITICAL | 80 |
| 调用 Shell / CreateObject | VBAShellInvocation |
HIGH | 55 |
| 含自动执行入口(AutoOpen / Workbook_Open) | VBAAutoExec |
HIGH | 45 |
| 含外部链接 | VBAExternalLink |
MEDIUM | 25 |
| 含疑似编码/混淆长串 | VBAEncodedString |
MEDIUM | 20 |
| 仅含宏,无明显恶意特征 | VBAMacroPresent |
LOW | 15 |
4.4.2 规则覆盖机制
关键规则在策略文件中配置强制处置,不依赖评分累加:
rule_overrides:
MRaptorAutoExecSuspicious:
action: reject
reason: "文档宏具备自动执行且包含可疑行为,按策略直接拒绝"
DDEAutoExecution:
action: reject
reason: "检测到 DDE/DDEAUTO 自动执行字段,按策略直接拒绝"
4.5 L2B YARA 与二进制分析层
| 组件 | 用途 |
|---|---|
| YARA | 通用规则库 + 环境专属规则(如针对内部文书模板名的钓鱼文件) |
| pefile | PE 节区熵值、导入表分析、签名目录检查、编译时间戳 |
| capa(可选) | 可执行文件能力识别(持久化、注入、加密、HTTP 通信) |
规则严重度依据规则名与标签自动判定:
| 标签 / 关键词 | 严重度 | 权重 |
|---|---|---|
| critical / malware / ransomware / backdoor / c2 / exploit | CRITICAL | 85 |
| high / trojan / dropper / obfusc / shellcode | HIGH | 60 |
| medium / suspicious / pua / packer | MEDIUM | 30 |
| 其他 | LOW | 10 |
规则库维护要求:规则库需版本管理与定期回归测试集,否则半年后必然出现大量误报或漏报。
4.6 L3 动态沙箱层(长期可选项,一期不实现)
4.6.1 一期不实现的理由
- 环境不匹配:CAPE / DRAKVUF 依赖 Windows 客体与裸金属虚拟化(Intel VT-x + EPT),与内网国产化终端环境不匹配
- 资源开销:典型配置 4C8G 起,单样本运行 3~5 分钟,全量沙箱在吞吐上不可行
- 场景收益有限:本场景以文档为主,静态分析对文档类样本覆盖度已较高;沙箱真正适用面窄(仅加壳二进制、镜像类)
- 投入产出失衡:一套沙箱环境的投入 ≈ 整个检测服务的开发投入
4.6.2 保留的接口语义
异步模式与 sandbox_required_extensions 配置项在策略中保留,未来接入沙箱时无需改动接口与策略结构。
| 项目 | 设计 |
|---|---|
| 触发条件 | 策略命中 sandbox_required_extensions(一期不生效,仅占位) |
| 替代措施 | 对高危解析路径(字体、图像、压缩流、复合文档)增加结构完整性校验与畸形构造检测 |
| 接口影响 | 无。异步模式已预留 task_id 语义 |
4.7 引擎降级与失败处理
任一引擎不可用(进程崩溃、连接超时、库加载失败)时:
- 记录为"引擎不可用"信号,不中断整个扫描
- 由策略的
engine_failure_mode决定整体处置 - 生产环境配置为
fail_closed(拒绝),符合等保"安全优先"原则
4.8 「打开即执行」载体零容忍(核心设计)
4.8.1 为什么这是核心
本场景的关键前提是:文件最终由人工在内网终端打开,自动化处理极少。因此"文件打开即执行"的所有载体构成最高风险敞口——这类攻击不需要用户任何操作,一次双击即完成入侵。
传统杀毒以"是否为已知恶意样本"为判据,但在本场景下判据应改为"是否存在打开即执行的载体"。
4.8.2 目标终端与威胁模型
本方案一期的目标终端是 麒麟桌面/UOS(x86_64)+ WPS Office。这是纯 Linux 桌面环境,与之前方案隐含的 Windows 兼容路线有本质差异——部分 Windows 专属载体在内网终端上不适用(如 LNK 快捷方式),同时存在 Linux 专属威胁载体(如 ELF、.desktop)。
纵深防御原则:即使内网是 Linux,Windows 威胁仍保持检测——因为文件可能通过其他路径最终到达 Windows 机器(运维人员的 Windows 工作站、外接 Windows 设备等)。但威胁等级按内网终端环境加权。
4.8.3 载体清单与判定方式(按 Linux 适用性分层)
A. 跨平台通用载体(Linux 上同样有效)
| 载体 | 触发条件 | Linux 上是否生效 | 判定方式 | 规则名 |
|---|---|---|---|---|
| PDF JavaScript | 打开即执行脚本 | ✅ 麒麟默认 PDF 阅读器和浏览器都支持 JS | pypdf | PdfJavaScript |
| PDF LaunchAction | 打开即启动程序 | ✅ Linux PDF 阅读器会触发 | pypdf | PdfLaunchAction |
| PDF OpenAction | 打开即执行动作 | ✅ | pypdf | PdfOpenAction |
| 宏代码混淆 / 加密 | 意图不可知 | ✅ 与平台无关 | 编码特征检测 | MacroObfuscated |
| 路径穿越条目 | 解包时逃逸 | ✅ | 结构校验 | PathTraversal |
| ISO / 镜像 | 双击即挂载 | ✅ UOS 可直接挂载 | 挂载后递归扫描 | IsoWithExecutable |
B. 宏相关(WPS on Linux 需实测验证)
VBA 宏检测的核心逻辑(行为分析、危险 API 识别、混淆检测)是跨平台的——不管宏最终在哪个 Office 实现中运行,代码本身的危险特征(调用 Shell、下载文件、混淆加密)都可以被静态识别。差异在于 AutoOpen 等自动执行入口在 WPS on Linux 上是否与 Office on Windows 行为一致。
待实测:AutoOpen / Workbook_Open 在 WPS on 麒麟/UOS 上是否在打开时自动触发;Shell / CreateObject 调用在 WPS on Linux 上是否有效。这项验证在 P0 开发前必须完成(见 §13 Q15 已确认,补充方案见 §4.8.4)。
| 载体 | 触发条件 | 判定方式 | 规则名 |
|---|---|---|---|
| VBA 宏 AutoOpen | 打开即触发(WPS on Linux 需实测) | oletools + 宏行为分析 | VBAAutoExec / VBAAutoExecShell |
| DDE / DDEAUTO | 打开即触发(WPS on Linux 需实测) | msodde | DDEAutoExecution |
| 外部模板注入 | 打开即触发 | OOXML 解析 | AttachedTemplate |
| 内嵌可执行对象 | 点击确认后执行 | oleobj | EmbeddedExecutable |
C. Windows 专属载体(Linux 上无直接威胁,降级为纵深防御)
以下载体在内网麒麟桌面/UOS 终端上不生效,但保持检测——文件可能流向 Windows 工作站:
| 载体 | 触发条件 | Linux 上生效? | 处置定位 | 规则名 |
|---|---|---|---|---|
| LNK 快捷方式 | 点击即执行 | ❌ Linux 不识别 .lnk 格式 | 纵深防御(文件可能流向 Windows) | LnkWithAutoExec |
| CHM 帮助文件 | 打开即执行脚本 | ❌ Linux 上需专门查看器,默认不自动执行 | 纵深防御 | ChmWithScript |
D. Linux 专属载体(之前方案遗漏,一期必须补充)
| 载体 | 触发条件 | 判定方式 | 规则名 |
|---|---|---|---|
| ELF 可执行文件 | Linux 原生二进制,直接运行 | 真实类型识别 + 签名/熵值分析 | LinuxExecutable |
| .desktop 快捷方式 | 包含 Exec= 字段指向程序或 shell |
.desktop 文件解析,检查 Exec 字段中是否包含 /bin/sh -c、wget/curl、隐藏命令等 |
DesktopFileAutoExec |
| Shell / Python / Perl / Ruby 等脚本 | 直接可执行,或被其他程序调用 | 脚本特征提取 + 危险函数识别(system/eval/exec/shell=True 等) | ShellScriptDangerous |
| AppImage / Flatpak / Snap 包 | 跨发行版便携可执行格式,双击即运行 | 真实类型识别,内部可执行递归扫描 | LinuxPortableExecutable |
| 压缩包内的 .sh / .deb / .run / .bin | Linux 下解压即可执行 | 递归解包 + 真实类型识别 | ArchiveContainsLinuxExec |
4.8.4 零容忍规则集(更新版,含 Linux 专属)
上述规则中的多数归入零容忍规则集,命中即拒绝,不走评分累加:
zero_tolerance_rules:
# === 跨平台通用 ===
- PdfJavaScript
- PdfLaunchAction
- PdfOpenAction
- PathTraversal
- IsoWithExecutable
- MacroObfuscated
- AttachedTemplate
# === 宏相关(WPS on Linux 生效)===
- VBAAutoExec
- VBAAutoExecShell
- MRaptorAutoExec
- MRaptorAutoExecSuspicious
- DDEAutoExecution
- EmbeddedExecutable
# === Linux 专属(新增)===
- LinuxExecutable
- DesktopFileAutoExec
- ShellScriptDangerous
- LinuxPortableExecutable
- ArchiveContainsLinuxExec
# === Windows 专属(纵深防御)===
- LnkWithAutoExec
- ChmWithScript
Linux 专属载体一期优先级:ELF 和 shell 脚本识别已包含在 L0 结构层的真实类型识别和 L2 文档检测中(脚本特征提取 + 正则),一期直接生效;.desktop 文件、AppImage/Flatpak 的专用解析器在 P0 中一并实现。
为什么零容忍要独立于评分模型:评分是相对度量(权重累加过阈值才拒绝),而"打开即执行"是绝对问题——一个宏文档哪怕只命中一条,也应直接拒。零容忍用独立机制表达,避免依赖权重调参。
4.8.5 宏行为分级(从「类型黑名单」到「行为白名单」)
内网人员需要打开带宏的公文模板(自动编号、签章定位等),因此不能简单地把"含宏"等同于"拒绝"。判定依据必须是宏做了什么,而非有没有宏:
| 宏的实际行为 | 风险 | 判定 | 处置 |
|---|---|---|---|
| 自动执行 + 调用系统命令 / 外联 | 极高 | 特征组合 + 编码特征 | 零容忍,拒绝 |
| 宏代码被混淆 / 加密 | 极高(意图不可知) | 编码特征检测 | 零容忍,拒绝 |
| 自动执行 + 仅本地无害操作 | 低 | 无危险 API、无网络、无文件写入 | 放行(可登记例外) |
| 无自动执行,仅手动触发 | 中 | 特征分析 | 标记放行 / 转复核 |
实现方式:判定"宏做了什么"靠的是危险 API 调用清单 + 自动执行入口存在性 + 混淆特征三项的组合,而非单纯的宏存在性。
4.8.5a 危险 API 清单(跨平台 + Linux 等价物)
原来的危险 API 清单是 Windows 专属的。以下补充 Linux 桌面环境下的等价威胁调用:
Windows 专属(宏中识别,文件可能流向 Windows 工作站)
| API | 含义 | 威胁等级 |
|---|---|---|
Shell() |
执行外部程序 | HIGH |
CreateObject("wscript.shell") |
脚本宿主对象,可执行任意命令 | HIGH |
URLDownloadToFile() / MonikerDownload() |
下载文件到本地 | HIGH |
CreateObject("MSXML2.XMLHTTP") |
HTTP 请求(常配合下载) | HIGH |
PowerShell / cmd.exe / net.exe 调用 |
Windows 系统命令 | HIGH |
注册表写入(HKEY_LOCAL_MACHINE 等) |
持久化 | MEDIUM |
Linux 等价物(宏在 WPS on Linux 中调用的系统接口)
| 调用特征 | 含义 | 威胁等级 |
|---|---|---|
Shell() → 执行 /bin/sh -c "..." |
Linux 下 Shell 函数通过 /bin/sh 执行命令 |
HIGH |
CreateObject("com.sun.star.system.SystemShellExecute") |
WPS/Office on Linux 执行外部程序的标准接口 | HIGH |
ShellExecute → curl / wget 下载 |
Linux 下常见下载器 | HIGH |
Shell 命令中含 cron 写入 / systemctl enable |
持久化 | HIGH |
Shell 命令中含 /tmp / /var/tmp 写入 |
落地可执行文件 | MEDIUM |
Shell 命令中含 /dev/tcp/ / bash -i |
反弹 Shell / 反向连接 | CRITICAL |
注意:以上 Linux 等价物是基于 WPS on Linux 的技术特性推断。§4.8.5b 的实测验证将确认这些调用在 WPS on 麒麟/UOS 上是否真的有效。
4.8.5b WPS on Linux 需实测的验证点
宏行为分级逻辑核心是跨平台的——基于宏代码的危险特征组合判定。差异在于这些特征在目标终端上是否可利用。以下验证项需在 P0 开发前完成:
| 验证项 | 说明 | 验证方式 |
|---|---|---|
| AutoOpen / Workbook_Open 在 WPS on 麒麟/UOS 是否自动触发 | 决定 VBAAutoExec 在 Linux 上的威胁等级 |
制作含 AutoOpen 的 docm 文件,在 WPS on 麒麟桌面打开观察 |
| Shell / CreateObject 在 WPS on Linux 是否有效 | 决定"自动执行 + 调用系统命令"场景在 Linux 上是否可利用 | 宏内写 Shell "ls" 或 Shell "/bin/sh -c 'echo test > /tmp/pwned'",在 WPS on Linux 上测试 |
/dev/tcp/ / bash -i 在宏内能否实现反向连接 |
决定 Linux 下反弹 Shell 的实际威胁 | 宏内写反弹 Shell 命令,测试是否成功 |
| DDE / DDEAUTO 在 WPS on Linux 是否生效 | 决定 DDEAutoExecution 在 Linux 上的实际威胁 |
构造含 DDEAUTO 的文档,在 WPS on Linux 上打开 |
安全优先:在验证完成前,宏相关零容忍规则保持默认生效。即使 AutoOpen 在 Linux 上不自动触发,宏代码本身的危险特征(混淆、Shell 调用、反弹 Shell 尝试)仍足以触发零容忍。
4.8.6 解析器漏洞的处理边界
MalformedStructure(畸形结构)不进入零容忍集,仅降权处理。理由:
| 考量 | 说明 |
|---|---|
| 无法判定 | 畸形结构既可能是攻击构造,也可能是正常的软件兼容产物 |
| 误报代价高 | 大量正常文档存在非标准结构,零容忍会阻塞业务 |
| 检出能力有限 | 结构校验只能发现部分畸形,无法覆盖全部解析器漏洞 |
| 责任边界 | 根治该类风险属终端侧加固范畴(打补丁、限制字体自动加载、禁用宏) |
检测服务的责任边界:识别出「该格式存在解析器攻击面」并在结论中提示,不给出「检测通过即绝对安全」的暗示。
4.8.7 链接与二维码:分级而非一刀切
外部链接在正常公文中极常见(法院官网、办事指南),一刀切会造成严重误报。因此采用分级:
| 情形 | 判定 | 处置 |
|---|---|---|
| 命中恶意 URL 库 | 确定性命中 | 零容忍,拒绝 |
| 指向非常规端口 / IP 直连 / 短链服务 | 特征命中 | 转复核 |
| 域名与内网已知系统同名但解析异常 | 特征命中 | 转复核 |
| 普通 http/https 链接 | 无命中 | 放行,但在打开风险中提示 |
二维码同理:解码后按 URL 规则判定;同时识别"二维码内容与文档主题完全无关"这一可疑组合。
4.8.8 打开风险等级(结论的独立维度)
在「人打开」场景下,检测服务应把「已确认有害」与「需用户注意」区分开。前者必须拦,后者应告知。
{
"verdict": "suspicious",
"action": "pass_with_flag",
"score": 25.0,
"reason": "文档包含外部链接与二维码,未命中恶意特征",
"open_risk": {
"level": "medium",
"factors": ["external_url", "qrcode", "contains_macro"],
"advice": "此文件包含宏与外部链接,打开前请确认来源,宏请勿启用",
"requires_macro_enable": true
}
}
| 等级 | 判定条件 | 提示语义 |
|---|---|---|
low |
无宏、无外链、无嵌入对象 | 无需特别提示 |
medium |
含外部链接 / 二维码 / 隐藏内容 | 请确认来源后再访问链接 |
high |
含宏(行为无害)/ 含外部模板引用 | 打开时请勿启用宏 |
critical |
含可执行文件 / ISO / Linux ELF / .desktop / AppImage / 零容忍命中 | 请勿直接双击,使用虚拟机或联系管理员 |
设计要点:
| 要点 | 说明 |
|---|---|
| 独立字段 | action 供系统判断,open_risk 供人阅读,语义不同不可混用 |
| 消费方分离 | 摆渡系统读 action;内网用户看 open_risk.advice |
| 可忽略 | 对接方觉得多余可直接忽略该字段,不影响接口兼容 |
| 独立演进 | 提示文案调整不影响判定逻辑 |
5. 安全设计
5.1 威胁模型
| 威胁 | 场景 | 应对 |
|---|---|---|
| 越权调用 | 未授权方直接调用检测接口 | mTLS + HMAC 签名 + 时间戳 + nonce |
| 重放攻击 | 截获合法请求后重复发送 | timestamp 窗口 ±300s + nonce 一次性 |
| 篡改响应 | 中间人将"恶意"结论改为"干净" | 响应体独立签名,调用方验签 |
| 参数试探 | 拿到密钥后反复调接口摸清检测逻辑 | 限流 + 按角色裁剪响应 + 错误信息不区分原因 |
| 恶意文件打服务端 | 上传构造的压缩炸弹 / 路径穿越文件 | 解包配额 + 路径清洗 + 进程隔离 + 超时限制 |
| 提权 | 通过文件内容影响服务进程 | 非 root 运行、只读文件系统、无出网权限 |
| 凭据泄露 | 配置文件中的密钥泄露 | 环境变量注入 + 文件权限 600 + 密钥派生隔离 |
| 日志篡改 | 事后删除不利审计记录 | 审计日志哈希链,篡改可被检测 |
| 未授权访问控制台 | 攻击者利用调试台探测系统 | 登录认证 + 失败锁定 + 生产默认关闭 |
5.2 认证与签名体系
5.2.1 凭证模型
每个调用方分配独立的 client_id / secret:
- 密钥不直接使用,通过 HKDF-SHA256 按用途派生出相互隔离的子密钥:
- 请求签名密钥:
info = "meshsafe/api/v1/request-signing" - 响应签名密钥:
info = "meshsafe/api/v1/response-signing"
- 请求签名密钥:
- 用途隔离的意义:即使请求签名密钥泄露,攻击者也无法伪造响应签名
5.2.2 请求签名
待签名串按固定顺序拼接,分隔符为 \n:
METHOD \n PATH \n CANONICAL_QUERY \n BODY_SHA256 \n TIMESTAMP \n NONCE \n CLIENT_ID
签名为 HMAC-SHA256(请求签名密钥, 待签名串) 的小写十六进制。
完整规范、校验向量、多语言示例见《接口文档》。
5.2.3 响应签名
服务端对响应体计算签名并通过响应头返回:
X-MS-Response-Signature = HMAC-SHA256(响应签名密钥, SHA256(响应体) || TIMESTAMP)
调用方必须验签。未验签的调用方无法获得防篡改保障——这在文档中会明确标注为对接方的强制要求。
5.2.4 防重放
| 机制 | 参数 | 说明 |
|---|---|---|
| 时间戳窗口 | ±300 秒(MESHSAFE_SIGNATURE_WINDOW) |
超窗直接拒绝 |
| nonce 一次性 | Redis SET NX + TTL |
重复 nonce 直接拒绝 |
nonce 校验通过 Redis 保证分布式一致性;Redis 不可用时降级为仅时间戳校验(记录告警)。
5.2.5 分权响应
| 角色 | 返回内容 |
|---|---|
operator |
完整结论 + 全部 findings + 提取文件路径 |
basic |
仅 verdict / score / action / reason 摘要 + 精简 file 信息 |
目的是缩小信息泄露面,避免攻击者通过对比不同密钥的响应差异反推检测规则细节。
5.2.6 错误信息不泄露原因
认证失败统一返回"认证失败",不区分"client_id 不存在"与"签名错误",避免 client_id 枚举。
5.3 控制台安全
| 控制项 | 实现 |
|---|---|
| 口令存储 | PBKDF2-HMAC-SHA256,60 万次迭代,16 字节随机盐 |
| 口令复杂度 | ≥12 位,含大小写字母、数字、特殊字符 |
| 失败锁定 | 5 次失败锁定 15 分钟 |
| 会话管理 | 服务端会话存储,30 分钟超时,滑动续期 |
| CSRF | 状态变更请求校验 CSRF Token + SameSite Cookie |
| 首次登录 | 强制修改初始密码(must_change_password) |
| 操作审计 | 登录、登出、上传扫描、查看明细、策略重载全部留痕 |
| 生产关闭 | 默认 always_on 模式,路由不注册,访问返回 404 |
5.4 审计与合规
| 控制项 | 实现 |
|---|---|
| 审计范围 | 所有 API 调用、认证事件、策略变更、人工复核、控制台操作 |
| 防篡改 | 哈希链:row_hash = SHA256(记录字段 ‖ prev_hash),任一条被改则后续链断裂可检出 |
| 留存期 | ≥ 180 天(MESHSAFE_AUDIT_RETENTION_DAYS) |
| 完整性校验 | GET /api/v1/audit/verify 提供链完整性自检 |
| 日志外发 | 审计日志支持导出,便于对接集中审计平台 |
5.5 运行环境安全
| 项 | 配置 |
|---|---|
| 容器用户 | 非 root 运行 |
| 文件系统 | 应用目录只读,仅临时目录可写 |
| 网络 | 检测容器无出网权限;仅 Nginx 暴露 443 |
| 密钥管理 | 环境变量注入,不写入镜像层 |
| 依赖 | 版本锁定(requirements.txt 精确版本号) |
| 镜像 | 固定基础镜像 tag,定期重建 |
5.6 等保三级要求的融入点
本节不展开逐条对照(测评时另行整理),而是说明等保三级对本系统的设计产生了哪些实际约束——这些约束已经体现在前面的架构决策中。
5.6.1 约束如何影响设计
| 等保要求方向 | 对本系统的实际影响 | 体现在哪 |
|---|---|---|
| 身份鉴别 | 接口必须有强鉴别,不能只靠 IP 白名单 | §5.2 请求签名全量校验 |
| 访问控制 | 需按角色分配权限,防止越权获取信息 | §5.2.5 分权响应 |
| 安全审计 | 审计记录需完整、留存 ≥6 个月、防篡改 | §5.4 哈希链 + 180 天 |
| 数据完整性 | 传输与存储过程需有完整性保护手段 | 请求体哈希 + 响应签名 + 哈希链 |
| 数据保密性 | 口令不可逆存储,密钥不落盘 | §5.3 PBKDF2 + §5.5 环境变量注入 |
| 剩余信息保护 | 检测后不留存敏感文件 | 临时文件任务结束即清理 |
| 安全计算环境 | 恶意代码防范软件能力 | 本系统自身即为恶意代码防范组件 |
| 集中管控 | 策略需集中配置与审计 | 策略引擎 + 策略版本快照 |
5.6.2 本系统需要特别注意的两点
① "安全优先"的故障处理
等保要求"安全优先",因此策略的 engine_failure_mode 默认必须是 fail_closed(引擎不可用时拒绝文件)。这与一般业务系统的"可用性优先"相反,是刻意的设计取舍——检测服务在引擎故障时若继续放行,等同于没有检测。
② 双因素鉴别的依赖
等保三级对重要系统要求两种或以上鉴别方式组合。本服务的接口层已具备"证书 + 请求签名"的双要素,但对控制台的人工操作而言,目前只有单一口令。
建议方案:控制台接入承载方的统一身份认证体系(UAC / CA 证书 / 短信令牌),由该体系提供第二因素。若测评要求服务自身实现,则需增加 TOTP 模块——这会成为一个待补项。
5.6.3 依赖部署侧落实的事项
以下事项不在应用代码内,但测评时会被检查,需在部署方案中明确:
| 事项 | 要求 |
|---|---|
| 时钟同步 | NTP 同步,偏差 < 1 秒(签名窗口 ±300 秒,同步可避免误拒) |
| TLS 证书 | 内部 CA 签发,TLS 1.2+,禁用弱套件 |
| 磁盘加密 | 存储数据库与策略文件的卷启用加密 |
| 容器加固 | 非 root、只读根文件系统、cap_drop: ALL、no-new-privileges |
| 网络隔离 | 检测网段与业务内网隔离,无出网路由 |
| 主机加固 | 麒麟 / Ubuntu 安全基线(SSH、口令策略、审计服务) |
| 备份策略 | 数据库与配置备份计划 + 演练记录 |
6. 接口设计概要
完整契约见《接口文档》。此处仅列概要。
6.1 接口清单
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| POST | /api/v1/scans |
提交文件扫描 | 调用方 |
| GET | /api/v1/scans/{task_id} |
查询扫描结果 | 调用方 |
| POST | /api/v1/scans/{task_id}/rescan |
按当前策略重扫 | 调用方 |
| POST | /api/v1/scans/{task_id}/review |
人工复核结论回写 | operator |
| GET | /api/v1/health |
引擎状态与签名库版本 | 调用方 |
| GET | /api/v1/policies |
查询生效策略 | operator |
| POST | /api/v1/policies/reload |
重载策略文件 | operator |
| GET | /api/v1/audit/verify |
审计链完整性自检 | operator |
6.2 结论字段语义
| 字段 | 取值 | 含义 |
|---|---|---|
verdict |
clean / suspicious / malicious / error |
总体判定 |
action |
pass / pass_with_flag / manual_review / reject |
处置建议 |
score |
0~100 | 风险评分 |
action 与 verdict 解耦:调用方应依据 action 执行业务逻辑,verdict 供人判断。
6.3 处置动作语义
| action | 调用方应采取的行动 |
|---|---|
pass |
正常放行 |
pass_with_flag |
放行但记录标记(低风险信号) |
manual_review |
转入人工复核流程,暂不放行 |
reject |
拒绝本次传输,并向用户说明 reason |
6.4 响应结构概要
{
"task_id": "…",
"verdict": "malicious",
"score": 85.0,
"action": "reject",
"reason": "检测到 VBA 宏 + DDEAUTO 自动执行",
"status": "completed",
"file": {
"sha256": "…", "md5": "…", "size": 284915,
"real_type": "Microsoft Word 2007+",
"declared_ext": ".docx", "filename": "起诉状.docx"
},
"findings": [
{
"engine": "document", "layer": "L2", "severity": "critical",
"rule": "DDEAutoExecution", "detail": "…", "weight": 65.0
}
],
"extracted": [ { "path": "word/vbaProject.bin", "size": 10240 } ],
"meta": {
"scan_duration_ms": 1840,
"policy_version": "2026.10.1",
"clamav": { "version": "…", "signature": "…" }
}
}
6.5 同步 / 异步
| 模式 | 请求 | 响应 |
|---|---|---|
| 同步 | POST /api/v1/scans |
直接返回完整结论 |
| 异步 | POST /api/v1/scans(文件超限或需沙箱) |
返回 { "task_id": "…", "status": "pending" },轮询 GET /api/v1/scans/{task_id} |
6.6 版本与兼容策略
- 采用路径版本:
/api/v1/,便于网关路由配置 - v1 契约内的新增字段不视为破坏性变更,调用方应忽略未知字段
- 字段删除或语义变更必须升 v2,v1 与 v2 路径并存
- 响应中始终携带
meta.policy_version,便于问题定位
6.7 打开风险等级(open_risk)
本服务的结论有两个面向:系统判定 与 人工提示。前者供摆渡系统执行业务逻辑,后者供最终在内网打开文件的用户判断风险。open_risk 即为后者的独立字段。
6.7.1 与 action 的语义分离
| 字段 | 消费者 | 含义 |
|---|---|---|
action |
摆渡系统 | 机器执行——放行 / 拒绝 / 转复核 |
open_risk |
内网用户 / 安全管理员 | 人阅读——打开时需要注意什么 |
两者独立演进:提示文案调整不影响判定逻辑;判定规则变更也不强制修改提示模板。
6.7.2 字段结构
{
"open_risk": {
"level": "high",
"factors": ["contains_macro", "attached_template", "external_url"],
"advice": "此文件包含宏与外部模板引用,打开时请勿启用宏,并确认来源可信",
"requires_macro_enable": true
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
level |
枚举 | low / medium / high / critical |
factors |
字符串数组 | 触发该等级的具体因素标识,供前端选择性提示 |
advice |
字符串 | 面向最终用户的中文提示语,可直接展示 |
requires_macro_enable |
布尔 | 该文件是否需要用户手动启用宏才能正常使用(仅提示,不代表检测建议) |
6.7.3 等级定义
| 等级 | 触发条件 | 典型提示 |
|---|---|---|
low |
无宏、无外链、无嵌入对象、无非常规容器 | 无提示 |
medium |
含普通外部链接 / 二维码 / 隐藏内容 | "请确认链接来源" |
high |
含宏(行为无害)/ 含外部模板引用 / 含嵌入对象(非可执行) | "打开时请勿启用宏" |
critical |
含可执行文件 / ISO / Linux ELF / .desktop / AppImage / 零容忍命中 | "请勿直接双击,联系管理员" |
6.7.4 消费方忽略权
对接方若不需要该字段可直接忽略,不影响接口兼容。本服务保证 open_risk 始终存在于响应中,即使 verdict = clean 也会返回 level = low 的结构。
6.7.5 与零容忍的关系
零容忍命中时:action = reject 且 open_risk.level = critical。两者同时出现,摆渡系统看 action 自动拒绝,内网用户若绕过摆渡(通过其他途径拿到文件)也能在安全审计面板看到 open_risk 的警告。
7. 策略与裁决模型
7.1 裁决流程
检测信号
│
▼
┌─────────────────────────────────┐
│ 0. 零容忍检查(独立机制) │ ── 命中 → 直接 reject,不走评分
└─────────────────────────────────┘
│ 未命中
▼
┌─────────────────────────────────┐
│ 1. 硬性约束检查 │ ── 引擎可用性 / 大小 / 扩展名 / 加密
└─────────────────────────────────┘
│ 通过
▼
┌─────────────────────────────────┐
│ 2. rule_overrides 检查 │ ── 命中 → 按覆盖动作执行
└─────────────────────────────────┘
│ 未命中
▼
┌─────────────────────────────────┐
│ 3. 权重累加评分 + 阈值映射 │ ── 得到 verdict / action / open_risk
└─────────────────────────────────┘
顺序是强制的:零容忍独立于评分模型,优先级最高。这样"路径穿越 / VBA 自动执行"这类绝对问题不会因为文件其他方面"干净"而被放过。
7.2 裁决步骤
| 步骤 | 检查 | 触发后果 |
|---|---|---|
| 0 | 命中 zero_tolerance_rules |
直接 reject,记录原因,跳过后续所有步骤 |
| 1 | 引擎可用性 | fail_closed 下直接拒绝 |
| 2 | 文件大小超限 | 直接拒绝 |
| 3 | 扩展名不在白名单 | 直接拒绝 |
| 4 | 文件加密且策略不允许 | 直接拒绝 |
| 5 | 命中 rule_overrides |
按覆盖动作执行 |
| 6 | 其余信号权重累加 | 得到评分 |
| 7 | 评分阈值映射 | 得到最终 verdict / action / open_risk |
例外机制的切入点:若文件同时命中零容忍规则和例外条件(见 §7.7),则零容忍检查会额外查询例外表——存在有效例外时跳过该条零容忍,继续进入步骤 1。这是整个裁决流程中唯一的"零容忍放宽"入口。
7.3 评分与阈值
| 评分区间 | verdict | action |
|---|---|---|
| 0 | clean |
pass |
| 0 < score < review_low | suspicious |
pass_with_flag |
| review_low ≤ score < block_score | suspicious |
manual_review |
| score ≥ block_score | malicious |
reject |
默认阈值:review_score = [30, 70],block_score = 70。
7.4 策略文件
策略以 YAML 管理,与代码分离。调整裁决规则只改 YAML,不动代码。
version: "2026.10.1"
global:
block_score: 70
review_score: [30, 70]
engine_failure_mode: fail_closed
max_file_size: 52428800
sync_max_size: 52428800
allow_encrypted_archive: false
allow_encrypted_document: false
# ===== 零容忍规则集(步骤 0,优先级最高)=====
# 命中即 reject,不走评分。与评分模型完全独立的机制。
zero_tolerance_rules:
- VBAAutoExec
- VBAAutoExecShell
- MRaptorAutoExec
- MRaptorAutoExecSuspicious
- DDEAutoExecution
- PdfJavaScript
- PdfLaunchAction
- PdfOpenAction
- AttachedTemplate
- EmbeddedExecutable
- LnkWithAutoExec
- ChmWithScript
- IsoWithExecutable
- PathTraversal
- MacroObfuscated
allowed_extensions: [ .docx, .pdf, .xlsx, .jpg, .png, .zip ]
sandbox_required_extensions: [ .exe, .msi, .js, .vbs, .iso ]
# ===== 规则覆盖(步骤 5)=====
# 对特定规则强制指定处置动作,独立于权重累加
rule_overrides:
VBAShellInvocation: { action: manual_review, reason: "…" }
ArchiveContainsExecutable: { action: manual_review, reason: "…" }
# ===== 宏行为例外(步骤 0 的唯一放宽入口)=====
# 内网人员需要打开带宏的公文模板,按文件指纹放行
# 详见 §7.7 例外机制
macro_exceptions:
- fingerprint_sha256: "a1b2c3d4..."
filename_pattern: "公文模板*.docm"
reason: "内部公文模板,宏仅执行本地编号与签章定位"
approved_by: "admin"
approved_at: "2026-10-15T10:30:00Z"
expires_at: "2027-10-15T10:30:00Z"
策略加载时执行严格校验(阈值区间合法性、动作枚举合法性、扩展名格式、例外的 SHA256 格式、到期时间不早于当前),校验不通过则拒绝加载并保留旧策略,防止错误的策略文件导致误放行。
7.5 策略版本追溯
每次扫描结果记录 policy_version 与 policy_sha256。策略重载时在数据库中留存版本快照,支持"按历史策略复现"能力。
7.6 零容忍机制详解
7.6.1 为什么独立于评分
评分是相对度量——权重累加过阈值才拒绝,天然存在"权重调参"问题。而"打开即执行"载体是绝对问题:一个宏文档哪怕只命中一条零容忍规则,也应直接拒。
如果把零容忍规则塞进评分体系(比如给 PathTraversal 一个 100 分权重),那么:
- 策略维护者需要记住"这条规则权重必须 ≥ block_score 才会生效"
- 未来有人调低
block_score可能无意间让零容忍规则失效 - 逻辑上"零容忍"就变成了"高权重",语义弱化
独立机制的好处:零容忍是一份不与评分耦合的清单,增删条目无需考虑权重平衡。
7.6.2 清单来源
当前零容忍规则集中的所有条目来源于 §4.8.3 的分层载体判定表。未来新增零容忍规则的准入条件:
| 条件 | 说明 |
|---|---|
| 命中即有害 | 不存在"合法使用"的场景(如路径穿越) |
| 无法通过权重平衡 | 即使其他信号都是干净的,命中本身即应拒 |
| 可稳定判定 | 不依赖大模型或主观判断 |
宏的处理是唯一例外——存在"合法宏模板"场景,因此引入例外机制(§7.7)而非直接把所有宏相关规则放进零容忍集。
7.6.3 与 rule_overrides 的交互
zero_tolerance_rules → 步骤 0 最先检查,命中直接 reject
rule_overrides → 步骤 5 在零容忍未命中后检查
两者不重叠。如果某规则在零容忍清单中,它不会再出现在 rule_overrides 的覆盖对象里——因为零容忍已经处理了它。rule_overrides 仅针对"未进零容忍集但需要强制处置"的规则(如 VBAShellInvocation)。
7.7 宏行为例外机制
内网业务场景下,需要打开带宏的公文模板(自动编号、签章定位等),这类宏不做网络访问、不调用系统命令、仅在本地操作文档。零容忍机制必须为此预留受控的放宽入口。
7.7.1 五道保险
| 保险 | 机制 | 效果 |
|---|---|---|
| 指纹绑定 | 例外按 sha256 精确匹配 |
换一个字节的模板文件就不匹配,攻击者无法批量绕过 |
| 双因素匹配 | 同时校验指纹 + 文件名模式(glob) | 防止同哈希文件被不同文件名复用 |
| 必须到期 | 例外必须有 expires_at,最长不超过 1 年 |
防止过期例外长期有效;到期自动失效 |
| 审批留痕 | 创建例外需 approved_by + 审计日志 |
谁批的、为什么批、批了什么全部可追溯 |
| 行为前提 | 例外仅对"无危险 API"的宏生效(§4.8.4 判定) | 宏虽在例外中,但若检测到 Shell 调用 / URLDownloadToFile / 混淆等,仍触发零容忍 |
7.7.2 例外如何生效
文件进入零容忍检查 ──► 命中 VBAAutoExec ──► 查询例外表
│
┌───────────┴───────────┐
▼ ▼
存在有效例外 无有效例外
(指纹 + 文件名 + 或 已过期
宏行为无害)
│ │
▼ ▼
跳过此条零容忍 零容忍 reject
继续步骤 1
关键约束:例外是逐规则、逐文件的,不是"对某类文件全部例外"。一个例外只对清单中明确列出的那一条零容忍规则生效(如仅放宽 VBAAutoExec,但 DDEAutoExecution 仍会触发零容忍)。
7.7.3 例外的审批流程
| 方式 | 描述 | 适用 |
|---|---|---|
| 线下审批 + 写进策略文件 | 业务侧提交书面申请 → 安全管理员审核 → 写入 policy.yaml 的 macro_exceptions 段 → 控制台触发热重载 |
一期默认方式,流程清晰、审计留痕自然 |
| 系统内审批流 | 控制台内发起申请 → 另一名管理员审批 → 自动入库并热重载 | 待后续评估,一期不做(与线下方式等价,但开发量显著增加) |
一期采用线下审批。理由:例外数量预计很少(可能 <10 条),不值得为其开发审批工作流。控制台的配置编辑页面(§9.7)提供例外表的可视化增删改查。
8. 部署架构
8.1 容器拓扑
services:
api: # FastAPI 应用(API + 控制台)
clamav: # clamd 守护进程
db: # PostgreSQL
redis: # 任务队列 / 幂等缓存 / 限流 / nonce
nginx: # TLS 终止 + 静态资源 + 反向代理
单机 Docker Compose 编排,无需 Kubernetes。
8.2 目标环境
| 环境 | 说明 |
|---|---|
| 检测服务部署(服务器端) | Ubuntu 20.04+ / 麒麟 V10(服务器版),x86_64 架构 |
| 容器运行时 | Docker 20.10+ / Docker Compose v2 |
| 资源要求 | ≥ 4 核 8 GB(ClamAV 签名库加载需约 2 GB 内存),磁盘 ≥ 50 GB |
| 网络 | 检测服务部署在隔离区,仅对摆渡系统开放 443 |
| 目标终端环境 | 麒麟桌面/UOS(x86_64)+ WPS Office,纯 Linux 桌面环境(见 §4.8.2 威胁模型) |
8.3 签名库离线更新流程
① 外网同步机:freshclam 每日拉取官方 CVD
② 外网镜像:cvdupdate 模式提供私有镜像
③ 单向导入:通过光闸/介质将签名库传入内网
④ 内网分发:内网节点从内网镜像增量同步
⑤ clamd 加载:更新签名库并重载
⑥ 验证:GET /api/v1/health 确认版本与更新时间
要求:更新流程需文档化并纳入运维手册;签名库超过 7 天未更新应在健康检查中告警。
8.4 网络访问控制
| 源 | 目标 | 端口 | 说明 |
|---|---|---|---|
| 摆渡系统 | Nginx | 443 | 检测接口 |
| 运维终端 | Nginx | 443 | 控制台(按需) |
| Nginx | api | 8000 | 内部 |
| api | clamav | 3310 | 内部 |
| api | db / redis | 5432 / 6379 | 内部 |
| api | 外部 | — | 禁止 |
9. 在线调试台与文档体系
9.1 文档体系
保持精简,只保留两份:
| 文档 | 读者 | 内容 | 载体 |
|---|---|---|---|
| 本文档 | 全体 | 总体方案(架构、检测能力、安全设计、演进路线) | Markdown |
| 《接口文档》 | 对接方开发人员 | API 契约 + 签名规范 + 多语言示例 | Markdown(对外交付物) |
其他内容按需在本文档内补充章节,不单独成文。运维手册、README 等在方案定稿后再补。
9.2 为何不能只提供 Swagger
| 问题 | 说明 |
|---|---|
| 不体现签名机制 | Swagger 的 "Try it out" 必然失败(缺签名头),对接方会误判接口故障 |
| 不体现 multipart 签名特殊性 | 文件上传时 body 哈希如何计算、Content-Type 含随机 boundary 的处理方式必须文字说明 |
| 不体现响应验签 | 对接方若不做验签则失去防篡改保障,而这不会在 Swagger 中体现 |
因此文档必须是**"人读 Markdown + 机读 OpenAPI + 可运行示例代码"** 三件套。
9.3 在线调试台组成
| 页面 | 路径 | 说明 |
|---|---|---|
| Swagger UI | /docs |
FastAPI 生成,含中文描述、示例值、枚举说明 |
| 签名调试台 | /console/signing |
表单输入 → 实时生成签名头 → 一键复制 |
| 请求模拟器 | /console/try |
构造带签名请求并实际发送,展示完整 HTTP 报文与验签结果 |
| 历史任务 | /console/tasks |
按时间/结论筛选,查看详情与 findings |
| 审计查询 | /console/audit |
查询审计日志,触发链完整性自检 |
| 引擎看板 | /console/health |
各引擎状态、签名库版本、队列深度 |
关键设计:调试台自行实现一遍签名并展示验签计算过程,让对接方直观理解"签名怎么来、怎么验",比读十页文字更快。
9.4 控制台必须走正式接口
控制台不得直接调用内部扫描函数,必须经由完整 HTTP 链路:
浏览器 ──▶ /console/api/* ──▶ httpx(带签名) ──▶ /api/v1/scans ──▶ 业务逻辑
理由:
- 测试出的是真实对接体验,包含签名正确性、响应验签头等
- 避免"控制台能跑通但对接方跑不通"的旁路假象
- 控制台自身即为一个调用方,形成 dogfooding 验证
实现要点:控制台持有独立的内部凭证 client_id = console-internal,其调用在审计日志中与外部调用方一致,可区分"人工上传测试"与"系统自动扫描"。
9.5 门控与部署模式
配置项(config/console.yaml):
console:
mode: always_on # always_on / enabled / internal_only
show_api_docs: false
show_signing_tool: false
allow_live_scan: false
show_full_findings: false
allowed_cidrs: [] # internal_only 模式下的允许网段
| 模式 | 控制台 | /docs | 适用 |
|---|---|---|---|
always_on |
关闭 | 关闭 | 生产默认 |
enabled |
开放 | 开放 | 开发测试 |
internal_only |
限指定网段 | 限指定网段 | 生产但内部团队需查阅文档 |
关闭的实现方式:在路由注册期决定,而非运行期判断。
if console_cfg.mode != "always_on":
app.include_router(console_router, prefix="/console")
这样生产环境中 /console 与 /docs 在路由表中根本不存在,外部扫描得到 404 —— 比返回 403 更好,因为 403 会暴露"这里有东西"。
注意:openapi_url 需同步控制,否则关闭 UI 但保留 /openapi.json 等于文档仍在被爬取。
9.6 对外文档的信息边界
对外文档需控制信息暴露程度:
| 应当提供 | 不应提供 |
|---|---|
| API 契约与字段枚举 | YARA 规则正文 |
| 签名规范与校验向量 | 内部代码结构与目录 |
| 规则名 + 含义 + 严重度 | 引擎版本号与依赖细节 |
| 多语言完整示例代码 | 绕过检测的手法说明 |
9.7 策略配置页面
9.7.1 核心原则:数据库为准
配置同时以 YAML 文件和数据库两种形式存在,但数据库是权威数据源:
| 项 | 说明 |
|---|---|
| 权威源 | policy_versions 表 + macro_exceptions 表,控制台编辑直接写库 |
| YAML 文件 | 每次发布版本时从数据库导出,供文件备份与容器镜像打包使用 |
| 加载方式 | API 服务启动时从数据库加载当前生效版本,而非读 YAML 文件 |
| 一致性 | 数据库与 YAML 的 SHA256 定期校验,不一致则告警 |
为什么数据库为准:实施人员通过网页改配置时,不可能手动同步修改文件和重新部署容器。数据库方案让"编辑 → 热重载"变为一次操作。
9.7.2 双模式编辑
┌──────────────────────────────────────────────────┐
│ 策略编辑页 /console/config │
├──────────────┬───────────────────────────────────┤
│ 📋 表单模式 │ 📝 YAML 模式 │
│ │ │
│ · 分组卡片 │ 完整 YAML 编辑器(只读高亮) │
│ · 下拉框/开关 │ 直接编辑原始结构 │
│ · 带校验提示 │ 高级用户可精确控制字段 │
│ · 初学者友好 │ 实施人员可直接粘贴整段配置 │
└──────────────┴───────────────────────────────────┘
│ │
└────────┬───────────┘
▼
统一后端校验 → 保存到数据库 → 触发热重载
| 模式 | 适合场景 | 特点 |
|---|---|---|
| 表单模式 | 运维人员日常调参 | 分组卡片、枚举下拉、阈值滑块、SHA256 格式校验、到期时间日历选择 |
| YAML 模式 | 高级实施人员批量配置 | 与 policy.yaml 完全同结构、语法高亮、粘贴即校验、实时预览影响 |
两种模式共享同一份后端校验逻辑,保存时执行相同的完整校验(§7.4 策略文件校验规则)。
9.7.3 策略页面分区
策略配置页
├── ① 基本裁决参数(global)
│ ├── block_score / review_score 阈值滑块
│ ├── engine_failure_mode 开关
│ └── 各文件大小上限
│
├── ② 零容忍规则集(zero_tolerance_rules)
│ ├── 全部规则,每条独立开关
│ ├── 新增 / 删除条目(需填规则名)
│ └── 每条附规则含义说明与来源
│
├── ③ 规则覆盖(rule_overrides)
│ ├── key = 规则名,value = {action, reason}
│ ├── 下拉框列出已注册的全部规则供选择
│ └── action 枚举限制为 reject / manual_review
│
├── ④ 宏行为例外(macro_exceptions)
│ ├── 表格:指纹 / 文件名模式 / 原因 / 审批人 / 到期时间
│ ├── 新增时校验 SHA256 格式、到期时间
│ ├── 到期自动标记失效,保留历史记录
│ └── 支持"扫描中发现需例外的文件 → 一键添加"快捷入口
│
├── ⑤ 允许的扩展名(allowed_extensions)
│ └── 勾选式多选项,附格式说明
│
└── ⑥ 版本管理面板
├── 当前版本号 / SHA256 / 创建时间 / 创建人
├── 历史版本列表(可按版本号 / 时间筛选)
├── 点击历史版本 → 只读预览
└── 一键回滚到任意历史版本
9.7.4 保存校验流程
用户点击"保存"
│
▼
前端基本校验(必填 / 格式 / 枚举范围)
│ 通过
▼
后端完整校验(与 §7.4 策略文件校验规则相同)
│ 通过
▼
写入 policy_versions 表(新行,状态 = pending)
│
▼
触发热重载 /api/v1/policies/reload
│ 成功
▼
更新 policy_versions 状态 → active(旧版本自动标记 archived)
│
▼
导出 YAML 到 `config/policy.yaml`(供备份)
│
▼
审计日志记录完整 diff
│
┌───────── 失败分支 ─────────┐
▼ ▼
热重载失败 校验失败(极罕见)
│ │
▼ ▼
新策略自动标记 archived 返回具体字段错误
继续使用旧策略 不写入数据库
关键设计:任何环节失败都不会让系统进入"无有效策略"状态。
9.7.5 权限分级
| 角色 | 权限 |
|---|---|
admin |
完整读写:编辑策略各段、增删零容忍规则、增删例外、回滚版本 |
operator |
只读 + 例外增删:可查看全部配置,可新增/删除宏行为例外(需审批留痕),不可修改裁决阈值或零容忍规则 |
viewer |
只读:仅查看当前生效策略与历史版本,不可编辑 |
等保三级对应:权限分级即"访问控制"要求的落地。
operator角色可管例外(因为是日常运维高频操作)但不能改裁决逻辑,降低误操作风险。
10. 实施路线
原则:一期聚焦核心风险敞口——"打开即执行"载体的零容忍拦截 + 恶意文件识别。其余能力按风险收益排序。沙箱(原 P4)与大模型(原 P5)已从实施计划中移除,前者见 §12.4,后者见 §12.1。
10.1 阶段总览
| 阶段 | 定位 | 核心内容 | 交付物 |
|---|---|---|---|
| P0 核心引擎 | 能跑通、能拦核心风险 | 项目骨架 + 安全层 + L0/L1/L2 检测流水线 + 零容忍机制 + 宏行为分级 + LNK 深度解析 + URL/二维码提取 + open_risk 等级 + 例外机制 | 完整检测引擎,覆盖场景中最高频的恶意载体 |
| P1 扩展检测 | 覆盖剩余格式与启发式 | ISO 挂载内递归 + CHM 复合文档校验 + 内网特征词表引擎 + 畸形文件启发式检测 + 同步/异步任务编排 | 覆盖全部目标格式,降低误报率 |
| P2 控制台与部署 | 可配置、可运维、可交付 | 控制台(登录/锁定/CSRF)+ 策略配置页面(§9.7 双模式/版本管理/回滚)+ Docker Compose 编排 + Nginx TLS + 签名调试台 + 审计链自检 | 单机可部署、实施人员可操作的完整系统 |
| P3 接口与测试 | 正式交付 | 对外接口文档(含签名规范、校验向量、四语言示例)+ 单元/集成测试 + 恶意样本回归测试集 | 可交付、可联调、可验收 |
10.2 各阶段详细内容
P0 核心引擎
目标:覆盖场景中最高频、最危险的恶意载体。能跑通一条完整的"上传 → 检测 → 裁决 → 返回结论"链路。
| 模块 | 具体工作 | 优先级理由 |
|---|---|---|
| 项目骨架 | FastAPI + PostgreSQL + Redis + 配置体系 + ORM + 安全层(HKDF / 签名 / PBKDF2 / 审计哈希链) | 全部上层的基础 |
| L0 结构层 | 真实类型识别 / 伪装检测 / 递归安全解包 / 路径穿越 / zip bomb | 拦截 60% 以上的人工伪装攻击 |
| L1 ClamAV | clamd 接入 + INSTREAM 协议 + 签名库版本记录 | 已知恶意样本的基本拦截 |
| L2 文档深度 | oletools(olevba + mraptor + msodde + oleobj)+ pypdf + OOXML 解析 | 宏 / DDE / PDF JS 是场景核心风险 |
| 零容忍机制 | 当前零容忍规则集(§4.8.4,含跨平台 / Linux 专属 / 纵深防御三层)+ 独立裁决步骤(§7.2 步骤 0) | 打开即执行载体必须零容忍 |
| 宏行为分级 | 危险 API 清单 + 自动执行入口检测 + 混淆特征识别(§4.8.4) | 区分"有害宏"与"公文模板宏" |
| LNK 深度解析 | LnkParse3 库 + 目标路径/参数解析 + 远程链接检测 | LNK 是高频钓鱼载体 |
| URL/二维码提取 | 文档外部链接部件解析 + zxing/opencv 二维码解码 + 恶意 URL 库查询(§4.8.6) | 链接与二维码是常见诱导入口 |
| open_risk 等级 | 四个等级 + factors + advice 模板(§6.7) | 系统判定与人工提示分离 |
| 例外机制 | 宏行为例外的五道保险 + 审批留痕 + 到期自动失效(§7.7) | 必须支持合法公文模板的受控放行 |
| 策略引擎 | PolicyStore 加载校验 + PolicyEngine 裁决(含零容忍 + 评分 + rule_overrides) | 全部检测信号的裁决中枢 |
| 扫描编排 | 流水线编排 + 递归队列 + 引擎降级处理 | 让各引擎协同工作 |
| API 路由 | 扫描提交 / 结果查询 / health / policies/reload | 对外接口的最小集合 |
P1 扩展检测
目标:覆盖 P0 未涉及的格式和启发式检测,降低误报率。
| 模块 | 具体工作 | 优先级理由 |
|---|---|---|
| ISO 挂载内递归 | 挂载后自动扫描可执行文件(§4.8.2 IsoWithExecutable) | ISO 是"打开即挂载"载体 |
| CHM 复合文档校验 | 类型识别 + 结构完整性校验(§4.8.2 ChmWithScript) | CHM 帮助文件可执行脚本 |
| 内网特征词表引擎 | 词表匹配 + 正则 + 组合规则 | 识别内网特有模板与特征,辅助例外判断 |
| 畸形文件启发式 | 结构完整性校验 + 非标准字段检测 | 降低解析器漏洞可利用性 |
| YARA + pefile | YARA 规则库集成 + PE 节区熵值 / 导入表 / 签名目录分析 | 二进制文件的恶意检测 |
| 同步/异步任务 | 大文件异步处理 + task_id 轮询 + 队列管理 | 避免 HTTP 长连接超时 |
P2 控制台与部署
目标:让实施人员能操作(配置、查看、调试)、能部署(一键启动)、能通过安全测评。
| 模块 | 具体工作 | 对应章节 |
|---|---|---|
| 控制台认证 | 登录 / 失败锁定 / CSRF / 30 分钟会话 | §5.3 |
| 策略配置页面 | 表单+YAML 双模式 / 数据库为准 / 版本历史 / 一键回滚 / 权限分级 | §9.7 |
| 签名调试台 | 实时生成签名头 / 展示验签过程 | §9.3 |
| 历史任务 / 审计查询 | 任务列表筛选 + 审计链自检 | §9.3 / §5.4 |
| 引擎看板 | 各引擎状态 + 签名库版本 + 队列深度 | §9.3 |
| Docker Compose | api + clamav + db + redis + nginx 编排 | §8.1 |
| Nginx TLS | TLS 1.2+ 终止 + 反向代理 + 静态资源 | §8.2 / §5.6.3 |
| 离线签名库同步 | 外网镜像 + 单向导入 + 内网分发 + 超期告警 | §4.3.2 / §8.3 |
P3 接口与测试
目标:正式交付物完备,对接方可联调,验收可复现。
| 模块 | 具体工作 | 交付形式 |
|---|---|---|
| 对外接口文档 | 签名规范 + 校验向量 + 四语言示例(Python / Java / C# / Go) | Markdown(已完成初稿) |
| 单元测试 | 各引擎独立测试 + 策略裁决测试 + 签名/验签测试 | tests/ 目录 |
| 集成测试 | 端到端扫描链路 + 异常引擎降级 + 热重载 | 测试脚本 |
| 恶意样本回归测试集 | 覆盖零容忍全部规则 + 宏分级 + Linux 专属载体 + 纵深防御 Windows 载体 | 样本库 + 期望结果表 |
10.3 阶段出口标准
P0 出口(核心引擎可用)
| 检查项 | 通过标准 |
|---|---|
| 零容忍规则集 | 全部正确触发 reject,不走评分 |
| 宏行为分级 | 有害宏(Shell/URLDownloadToFile)触发零容忍,无害宏(仅本地文档操作)放行或标记 |
| LNK 深度解析 | 指向 exe / 远程路径 / 脚本的 LNK 零容忍拦截 |
| URL / 二维码 | 恶意库命中→零容忍;非常规端口→转复核;普通链接→放行但提示 |
| open_risk 等级 | 各等级正确映射,与 action 同时返回 |
| 例外机制 | 指纹匹配 + 文件名匹配 + 到期过期自动失效 |
| 引擎不可用 | fail_closed 下拒绝文件 |
| 审计哈希链 | 扫描结果 + 策略变更 + 例外增删全部留痕且链可校验 |
P1 出口(覆盖全部格式)
| 检查项 | 通过标准 |
|---|---|
| ISO 递归扫描 | 挂载后内部 exe/msi 被拦截 |
| CHM 识别 | 类型识别正确,恶意 CHM 零容忍 |
| 畸形文件检测 | 结构异常的文档触发 warning,不崩 |
| 误报回归 | 引入 P1 能力后正常业务文件误报率不高于 P0 |
P2 出口(可交付)
| 检查项 | 通过标准 |
|---|---|
控制台 always_on 模式 |
路由表中无 /console 和 /docs,外部扫描返回 404 |
| 策略配置页面 | 表单模式与 YAML 模式都能正确编辑、保存、热重载;失败时回滚 |
| 版本管理 | 可查历史版本、可一键回滚、回滚后立即生效 |
| 控制台签名链路 | 控制台上传的测试走完整签名链路,审计日志标记 source=console |
| Docker Compose | docker compose up -d 一键启动,全部容器健康 |
| TLS | 仅 443 暴露,无明文端口 |
P3 出口(可联调可验收)
| 检查项 | 通过标准 |
|---|---|
| 接口文档校验向量 | 对接方可直接用于单元测试(已预跑通过) |
| 四语言示例 | Python / Java / C# / Go 四套 SDK 骨架 + 可运行的签名/验签示例 |
| 回归测试集 | 全部零容忍规则 + 宏分级 + Linux 专属载体样本,预期结果与实际结果 100% 一致 |
11. 风险与应对
| 编号 | 风险 | 影响 | 应对 | 责任阶段 |
|---|---|---|---|---|
| R1 | 病毒库长期不更新 | 检测能力形同虚设 | 自动化离线同步流程 + 超期告警(§8.3) | P2 |
| R2 | YARA 规则失准 | 误报影响业务 / 漏报造成风险 | 规则版本管理 + 定期回归测试集 | P3 |
| R3 | 摆渡业务无法开展 | manual_review 通道 + 人工复核回写 |
P1 | |
| R4 | 引擎性能瓶颈 | 吞吐不足 | clamd 常驻 + 异步模式 + 水平扩展 worker | P1 |
| R5 | 大文件解包耗尽资源 | 服务不可用 | 解包配额 + 超时 + 容器资源限制 | P1 |
| R6 | 对接方签名实现错误 | 联调受阻 | 文档校验向量 + 调试台 + SDK | P3 |
| R7 | 审计日志被删 | 合规不达标 | 哈希链 + 链校验自检接口 | P1 |
| R8 | 密钥泄露 | 伪造检测结论 | 环境变量注入 + 用途隔离派生 + 定期轮换 | P2 |
| R9 | 控制台暴露攻击面 | 被探测 / 被利用 | 生产默认关闭 + 登录锁定 + 审计 | P2 |
| R10 | 接口契约变更 | 对接方返工 | 路径版本 + 兼容策略 + 变更记录 | P3 |
12. 长期演进预研(非本期实施内容)
12.1 本期定位:确定性能力优先
经需求澄清,本期(一期)不引入大模型 / AI 能力。所有检测结论均由确定性手段产出:
| 特性 | 确定性手段 | 大模型手段 |
|---|---|---|
| 可复现性 | ✅ 同输入必同输出 | ❌ 存在随机性 |
| 可举证性 | ✅ 命中哪条规则清晰可述 | ❌ 结论难以向当事人解释 |
| 资源依赖 | ✅ 无需推理算力 | ❌ 需 GPU / 推理服务 |
| 延迟 | ✅ 毫秒~秒级 | ❌ 秒级~十秒级 |
| 幻觉风险 | ✅ 无 | ❌ 存在 |
在法院 / 政务场景下,「可举证」与「可复现」是硬性要求——检测结论可能需要向当事人出示。因此本期以确定性规则为主是正确取舍。
代价与补偿:规则无法覆盖「未知形态」与「语义层面」,这是客观局限。本方案的补偿措施是:
| 局限 | 补偿措施 |
|---|---|
| 新型攻击形态滞后 | 规则库版本管理 + 定期回归测试 + 快速更新流程 |
| 无法理解语义 | 本期不做(见 §12.3),依靠用户侧风险提示(见 §6.7) |
| 误报难以根治 | 零容忍 + 分级 + 例外机制 + 人工复核通道(见 §7.5) |
12.2 三层能力模型(架构预留)
架构上仍保留三层结构,语义层作为可插拔扩展点预留,确保未来引入时无需重构:
┌─────────────────────────────────────────────────────┐
│ L-S 语义分析层(长期预研,一期不实现) │
│ 大模型 / 语义规则 / 上下文关联判断 │
│ 产出:语义风险信号 + 解释性结论 │
├─────────────────────────────────────────────────────┤
│ L-R 规则分析层(本期实现) │
│ ClamAV / YARA / oletools / pefile / LnkParse │
│ 产出:确定性的命中信号 │
├─────────────────────────────────────────────────────┤
│ L-D 数据层(本期实现) │
│ 结构识别 / 递归解包 / 哈希 / 类型判定 │
│ 产出:文件的基础属性与容器结构 │
└─────────────────────────────────────────────────────┘
预留的具体形式:
| 项 | 预留内容 |
|---|---|
| 引擎接口 | Engine 基类的 layer 字段已支持 LS;未来新增 SemanticEngine 即可注册 |
| 信号结构 | Finding.meta 中预留 deterministic 字段,用于标记信号来源的确定性 |
| 配置 | 策略中预留 semantic.enabled 开关(默认关闭) |
| 裁决 | 策略引擎支持按 deterministic 设置权重上限,无需改动裁决逻辑 |
12.3 长期预研方向(不列入实施计划)
以下方向经评估有价值,但因依赖算力、效果待验证、举证效力待确认,本期不实施:
| 方向 | 潜在价值 | 暂缓原因 |
|---|---|---|
| 诱导话术识别 | 识别"请登录此链接办理"类诱导表达 | 需求已明确本期不需要 |
| 仿冒公文模板识别 | 判断内容是否符合真实公文体例 | 需模板库 + 效果验证 |
| 上下文关联分析 | 识别批量钓鱼、机器化命名 | 纯统计方法即可实现,不需模型,可独立推进 |
| 规则辅助生成 | 缩短新威胁的规则覆盖周期 | 属研发辅助工具,不在运行时链路 |
| 辅助复核摘要 | 降低人工复核成本 | 可先用模板化摘要替代 |
若未来引入大模型,必须满足的约束(提前记录,避免后续返工):
| 约束 | 要求 |
|---|---|
| 完全离线、本地推理 | 模型权重部署在内网,不调用外部 API(数据外传违反隔离要求) |
| 模型选型 | 优先可商用授权的开源模型(Qwen 系列、GLM 系列等) |
| 只喂提取物 | 仅提供解包后的文本、宏源码、脚本内容,不提供原文件 |
| 不单独裁决 | 模型输出作为信号之一参与评分,权重受限,不可作为唯一拒绝依据 |
| 可一键关闭 | 模型不可用时降级为纯规则模式,主流程不受影响 |
| 决策留痕 | 模型版本、提示词版本、输入摘要哈希、原始输出全部记录 |
12.4 沙箱(L3)的定位调整
原方案将动态沙箱列为 P4 可选。结合需求澄清(内网为国产化终端、以文档为主),建议将沙箱从实施计划中移除,仅作为长期可选项保留。
| 考量 | 分析 |
|---|---|
| 环境适配 | CAPE / DRAKVUF 依赖 Windows 客体与裸金属虚拟化(VT-x/EPT),与国产化环境不匹配 |
| 场景适配 | 场景以文档为主,静态分析对文档类样本覆盖度已较高 |
| 投入产出 | 一套沙箱环境的投入 ≈ 整个检测服务的开发投入 |
| 替代方案 | 结构完整性校验 + 畸形文件检测,成本低一个数量级,覆盖部分解析器漏洞风险 |
替代措施:对高危解析路径(字体、图像、压缩流、复合文档)增加结构完整性校验,检测畸形构造。虽无法根治解析器漏洞,但可显著降低可利用性。
解析器漏洞风险的定位:该类风险无法由检测服务单方面消除,属于终端侧加固范畴(打补丁、限制字体自动加载、禁用宏)。检测服务的责任是识别出「该格式存在解析器攻击面」并在结论中提示,不给出「检测通过即绝对安全」的暗示。
13. 待确认事项
13.2 已确认(方案中已有明确结论)
| 编号 | 事项 | 决定 | 写入位置 |
|---|---|---|---|
| Q1 | 对外文档形式 | 双文档:总体方案(本文档 Markdown)+ 接口文档(对外交付 Markdown) | §9.1 |
| Q2 | 官方 SDK 优先级 | 一期提供 Python SDK;Java / C# / Go 给完整示例代码 | 接口文档 |
| Q3 | 接口版本策略 | 路径版本 /api/v1/,v2 路径并存 |
§6.6 |
| Q4 | 对外文档规则清单粒度 | 给到"规则名 + 含义 + 严重度"级别,不暴露规则正文 | §9.6 |
| Q5 | 控制台任务标记 | 共用数据库,打 source=console 标记 |
§9.4 |
| Q6 | 沙箱是否纳入一期 | 不纳入。架构预留,环境不匹配且投入产出失衡 | §10 总览 + §12.4 |
| Q7 | 审计日志对接集中审计平台 | 一期提供导出接口 | §5.4 |
| Q8 | 大模型接入的算力与选型 | 不纳入一期。长期预研,架构预留语义层扩展点 | §12.1 / §12.2 |
| Q9 | 语义层信号的证据效力定位 | 不纳入一期。长期预研时需确认合规意见 | §12.3 |
| Q10 | 内网外发方向的内容审计 | 一期不做。依赖业务密级规则,作为后续独立需求立项 | §1.3 |
| Q11 | 例外机制的审批方式 | 一期用线下审批 + 写进策略文件,系统内审批流后续评估 | §7.7.3 |
| Q12 | 配置编辑方式 | 数据库为准,表单+YAML 双模式,版本历史 + 一键回滚 | §9.7.1 / §9.7.2 |
| Q13 | 等保双因素认证 | 一期依赖部署侧统一身份认证,服务自身实现 TOTP 列为待补 | §5.6.2 |
| Q14 | 国产化终端 OS | 麒麟桌面/UOS(x86_64)+ WPS Office,纯 Linux 桌面环境 | §4.8.2 |
| Q15 | WPS 使用情况 | 内网基本用 WPS,也有用操作系统自带 Office 的;AutoOpen/Shell 调用在 WPS on Linux 上需实测验证 | §4.8.5 |
13.3 待确认(影响实现方向或验收标准)
以下事项需在对应阶段启动前确认,否则会影响实现方案:
| 编号 | 事项 | 为什么重要 | 建议方案 | 需在何阶段确认 |
|---|---|---|---|---|
| Q20 | WPS on 麒麟/UOS 宏行为实测结果 | AutoOpen/Workbook_Open 是否自动触发;Shell/CreateObject 是否有效——决定宏相关零容忍规则在 Linux 上的威胁等级 | 制作 3~5 个测试宏模板(AutoOpen + Shell、AutoOpen + Download、纯本地操作),在 WPS on 麒麟桌面打开验证 | P0 开发前(必须完成) |
| Q16 | 摆渡系统的调用技术栈 | 决定 SDK 实际优先级。若摆渡系统用 Java,则 Python SDK 可以延后 | 摆渡系统开发侧提供技术栈确认 | P3 启动前(影响交付形式) |
| Q17 | 配置变更是否需要草稿+发布模式 | 当前方案是"编辑 → 立即热重载",变更即时生效。多人协作时可能需要草稿区 + 审核发布两步走 | 单人实施可简化为立即生效;多人协作建议加草稿+发布 | P2 启动前(影响控制台开发量) |
| Q18 | ClamAV 签名库的离线同步由谁运维 | 签名库超过 7 天不更新会触发健康检查告警。需明确:外网同步机谁管、单向导入介质谁负责、内网分发谁维护 | 由实施侧运维团队负责,服务只提供版本检查与告警 | P2 部署前(影响运维方案) |
| Q19 | 是否需要对接内部统一身份认证 | §5.6.2 提到控制台双因素认证的依赖。若对接 UAC/CA,则控制台自身不需实现 TOTP;否则需要 | 优先对接既有统一认证;无则实现 TOTP | P2 开发前 |
附录 A:已确定的技术选型
| 项目 | 选型 | 说明 |
|---|---|---|
| 开发语言 | Python 3.11+ | 检测生态最完整 |
| Web 框架 | FastAPI + Uvicorn | 异步、原生 OpenAPI |
| 数据库 | PostgreSQL 15 | 任务、策略、审计 |
| 缓存/队列 | Redis 7 | nonce、限流、幂等、异步队列 |
| 容器编排 | Docker Compose | 单机足够,无需 K8s |
| 病毒引擎 | ClamAV(clamd) | 签名库离线镜像 |
| 文档检测 | oletools + pypdf + pefile | Python 原生生态 |
| 规则引擎 | YARA 4.5(yara-python) | 可嵌入进程,性能优于命令行 |
| 反向代理 | Nginx | TLS 终止 + 静态资源 |
| 目标系统 | Ubuntu / 麒麟 V10 | 国产化适配 |
附录 B:项目结构规划
MeshSafe/
├── app/
│ ├── main.py # 应用入口、路由注册、门控
│ ├── config.py # 配置加载
│ ├── db.py # 数据库会话
│ ├── models.py # ORM 模型
│ ├── api/ # /api/v1 路由
│ │ ├── scans.py
│ │ ├── policies.py
│ │ ├── health.py
│ │ └── audit.py
│ ├── console/ # 控制台(可关闭)
│ │ ├── router.py
│ │ ├── auth.py
│ │ ├── views.py
│ │ └── templates/
│ ├── engines/ # 检测引擎
│ │ ├── base.py
│ │ ├── structure.py # L0
│ │ ├── extractor.py # L0 安全解包
│ │ ├── clamav.py # L1
│ │ ├── documents.py # L2
│ │ └── binary.py # L2B
│ ├── security/ # 安全层
│ │ ├── crypto.py # 口令哈希、HKDF
│ │ ├── signing.py # 请求/响应签名
│ │ └── deps.py # 认证依赖、限流
│ ├── services/
│ │ ├── policy.py # 策略引擎
│ │ ├── scanner.py # 扫描编排
│ │ ├── audit.py # 审计哈希链
│ │ └── tasks.py # 异步任务
│ └── templates/ # 模板
├── config/
│ ├── policy.yaml # 全局检测策略
│ └── console.yaml # 控制台门控
├── rules/ # YARA 规则库
├── docs/ # 文档
├── scripts/ # 运维脚本(含签名示例)
├── tests/ # 测试
├── Dockerfile
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
├── requirements.txt
└── .env.example
文档结束 · 下一步:《接口文档》(对外交付物)