# MeshSafe 文件安全检测服务 · 总体方案 | 项目 | 内容 | | ---- | ------------------- | | 系统名称 | MeshSafe 文件安全检测服务 | | 版本 | v1.0(方案稿) | | 文档状态 | 待评审 | | 适用场景 | 光闸内外网文件摆渡场景下的文件安全检测 | | 合规要求 | 满足网络安全等级保护三级相关控制项 | *** ## 目录 1. [背景与目标](#1-背景与目标) 2. [范围界定](#2-范围界定) 3. [总体架构](#3-总体架构) 4. [检测能力设计](#4-检测能力设计) 5. [安全设计](#5-安全设计) 6. [接口设计概要](#6-接口设计概要) 7. [策略与裁决模型](#7-策略与裁决模型) 8. [部署架构](#8-部署架构) 9. [在线调试台与文档体系](#9-在线调试台与文档体系) 10. [实施路线](#10-实施路线) 11. [风险与应对](#11-风险与应对) 12. [长期演进预研(非本期实施内容)](#12-长期演进预研非本期实施内容) 13. [待确认事项](#13-待确认事项) *** ## 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 | | PDF | pdf | | 归档 | 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、文档变量 | | pdf | `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 规则覆盖机制 关键规则在策略文件中配置**强制处置**,不依赖评分累加: ```yaml 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 一期不实现的理由 1. **环境不匹配**:CAPE / DRAKVUF 依赖 Windows 客体与裸金属虚拟化(Intel VT-x + EPT),与内网国产化终端环境不匹配 2. **资源开销**:典型配置 4C8G 起,单样本运行 3\~5 分钟,全量沙箱在吞吐上不可行 3. **场景收益有限**:本场景以文档为主,静态分析对文档类样本覆盖度已较高;沙箱真正适用面窄(仅加壳二进制、镜像类) 4. **投入产出失衡**:一套沙箱环境的投入 ≈ 整个检测服务的开发投入 #### 4.6.2 保留的接口语义 异步模式与 `sandbox_required_extensions` 配置项在策略中保留,未来接入沙箱时无需改动接口与策略结构。 | 项目 | 设计 | | ---- | --------------------------------------------- | | 触发条件 | 策略命中 `sandbox_required_extensions`(一期不生效,仅占位) | | 替代措施 | 对高危解析路径(字体、图像、压缩流、复合文档)增加结构完整性校验与畸形构造检测 | | 接口影响 | 无。异步模式已预留 `task_id` 语义 | ### 4.7 引擎降级与失败处理 任一引擎不可用(进程崩溃、连接超时、库加载失败)时: 1. 记录为"引擎不可用"信号,**不中断整个扫描** 2. 由策略的 `engine_failure_mode` 决定整体处置 3. 生产环境配置为 `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 专属) 上述规则中的多数归入**零容忍规则集**,命中即拒绝,**不走评分累加**: ```yaml 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 打开风险等级(结论的独立维度) 在「人打开」场景下,检测服务应把「已确认有害」与「需用户注意」区分开。前者必须拦,后者应告知。 ```json { "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 响应结构概要 ```json { "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 字段结构 ```json { "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,不动代码。 ```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 容器拓扑 ```yaml 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 ──▶ 业务逻辑 ``` 理由: 1. 测试出的是**真实对接体验**,包含签名正确性、响应验签头等 2. 避免"控制台能跑通但对接方跑不通"的旁路假象 3. 控制台自身即为一个调用方,形成 dogfooding 验证 **实现要点**:控制台持有独立的内部凭证 `client_id = console-internal`,其调用在审计日志中与外部调用方一致,可区分"人工上传测试"与"系统自动扫描"。 ### 9.5 门控与部署模式 配置项(`config/console.yaml`): ```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` | 限指定网段 | 限指定网段 | 生产但内部团队需查阅文档 | **关闭的实现方式**:在**路由注册期**决定,而非运行期判断。 ```python 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 ``` *** **文档结束** · 下一步:《接口文档》(对外交付物)