面向 COBOL 遗留系统的安全审计工具包
VTR 研究方法论的一部分 | DOI: 10.5281/zenodo.22063208 状态:可复现 | 许可证:MIT | 领域:关键基础设施
检测 GnuCOBOL 源代码中的编译上下文差异、不可见 Unicode 攻击以及不安全的 COBOL 模式。同一个源文件使用 -fixed 与 -free 编译会产生不同的程序——本工具使这种差异可观察、可复现。
git clone https://github.com/LuisCastellanos-dev/cobol-shield
cd cobol-shield
bash tools/poc_compiler_flag.sh
本工具不声称也不演示远程代码执行、权限提升或网络利用。根据 VTR 方法论,发现结果被分类为 CONFIRMADO、PROBABLE 或 OBSERVADO——分类反映的是证据强度,而非影响严重程度。
面向 COBOL 遗留系统的安全审计工具包
检测 GnuCOBOL 源代码中的不可见 Unicode 攻击、不安全的 COBOL 模式以及格式转换完整性问题。 已使用 GnuCOBOL 3.1.2 验证。在 IBM Enterprise COBOL 或 Micro Focus 上的行为未经验证——编译器特定的标志语义可能不同。
PIC X 接受一切。你的批处理不应该如此。
cobol-shield 覆盖两个不同的威胁面:
1. Unicode 不可见字符 —— CVE-2021-42574 及 Glassworm 类向量,可绕过人工代码审查并静默破坏 PIC X 字段。
2. COBOL 静态分析 —— 遗留源代码中的不安全模式:未初始化的工作存储、未检查的 STRING/UNSTRING 溢出、REDEFINES 大小不匹配,以及转换后含义发生变化的固定格式位置条件。
| 文件 | 用途 |
|---|---|
tools/check-invisibles.py | CI 检查器——检测到不可见 Unicode 时以退出码 1 退出 |
tools/clean-invisibles.py | 带取证审计日志的清理器 |
src/AUDITOR-INVISIBLE.cob | 使用 HEX-OF 的 COBOL 内字节验证器 |
tools/cobol_rules.py | 静态分析规则 R-01 至 R-04 |
tools/transform_renumber.py | 固定格式重编号偏移模拟器(阶段 2) |
tools/poc_compiler_flag.sh | 决定性 PoC——同一文件,-fixed 与 -free,编译器标志差异 |
tools/poc_differential.sh | 阶段 2 差分 PoC——SOURCE A 与 SOURCE B(手动迁移) |
每条规则产生 VTR Finding Schema v1 输出,可通过 context_loader 与 cryptofault 和 vtr-forensic-img 兼容。
| 规则 | 名称 | 严重性 | 分类 |
|---|---|---|---|
| R-01 | UNINITIALIZED_WS | 高 | HECHO |
| R-02 | UNSTRING_NO_OVERFLOW | 高 | HECHO |
| R-03 | REDEFINES_SIZE_MISMATCH | 高 | HECHO |
| R-04 | FORMAT_BOUNDARY_ANALYSIS | 信息 | PROYECCION |
R-01 — UNINITIALIZED_WS 检测在 Working-Storage 中声明但未使用 VALUE 子句,且在 PROCEDURE DIVISION 中未使用 INITIALIZE 或 MOVE 的变量。在批处理和 CICS 环境中存在静默未定义行为风险。
R-02 — UNSTRING_NO_OVERFLOW 检测未处理 ON OVERFLOW 的 STRING/UNSTRING 语句。当输入超过目标字段长度时发生静默截断。
R-03 — REDEFINES_SIZE_MISMATCH 检测被重定义字段声明的字节数超过其基础字段的 REDEFINES。存在内存边界违规风险——行为取决于编译器。
R-04 — FORMAT_BOUNDARY_ANALYSIS (阶段 1——仅观察) 检测固定格式 COBOL 源代码中的位置条件:
COL73_NONEMPTY —— 标识区(第 73–80 列)中存在非空格内容COL7_VERB —— 注释行(第 7 列 = * / / / D)中存在 COBOL 可执行动词SOURCE_BOUNDARY —— 第 80 列之后存在内容R-04 产生 severity=info、classification=PROYECCION。它记录的是格式条件——而非漏洞。影响需要转换差分分析(阶段 2)。
核心论点:COBOL 固定格式文件根据构建时使用的编译器标志具有不同的语义——而该标志位于源文件之外。
使用 GnuCOBOL 3.1.2 演示,单一产物,无修改:
bash tools/poc_compiler_flag.sh
cobc -x -fixed poc-same-file.cbl → compiles → output: 0000001000
cobc -x -free poc-same-file.cbl → 10 compilation errors
在 -fixed 下:第 6 行第 7 列 = * 是注释指示符——MOVE 999999 处于休眠状态,程序执行并显示 1000。
在 -free 下:序列号 000100...001000 被解析为数字字面量——报告缺少 PROGRAM-ID 头,每一行都产生错误。同一文件在语法上无效。
编译器标志不在源文件内。它存在于 Makefile、CI 配置或操作员调用中。更改它——无论有意还是无意——都会改变程序是否有效以及它的行为。
证据: corpus/fixed-format/poc-evidence.md
SHA-256 和完整错误日志已记录。
一个更早的 PoC 通过手动迁移演示了相同的论点:
SOURCE A (fixed-format, col7='*' dormant): output → 0000001000
SOURCE B (free-format, code active): output → 0000999999
SHA-256 A: b70a948a0df5e8f685e82f5bffc9c4710f2c0a7a23b6294e7ca20092c2d25d37
SHA-256 B: f5fd80f79ed3e5be97628f89790256d6fba80605dce2b7985b729b5fef6f26d5
局限性: SOURCE B 是不正确迁移的手动表示,而非 IBM Z Open Editor 或 IBM SCU 在真实重编号下的输出。上述编译器标志 PoC 没有此局限性。
检测范围:
| 码点 | 名称 | 风险 |
|---|---|---|
| U+0001–U+001F | C0 控制字符 | 批处理异常终止 |
| U+200B–U+200F | 零宽字符 | 数据损坏、VSAM 截断 |
| U+202A–U+202E | 双向覆盖 | Trojan Source——CVE-2021-42574 |
| U+2066–U+2069 | 双向隔离 | 方向欺骗 |
| U+FE00–U+FE0F | 变体选择符 | Glassworm 类隐写术 |
| U+E000–U+F8FF | 私用区 | 载荷隐藏 |
| U+FEFF | BOM | 静默前置字节 |
# Byte-level inspection
hexdump -C source.cob | grep -E "e2 80 (8b|ae)"
# Unicode CI check — exits 1 on detection
python3 tools/check-invisibles.py .
# Sanitize with forensic audit log
python3 tools/clean-invisibles.py . --report audit-$(date +%Y%m%d).log
# Run static analysis rules
python3 -c "
from tools.cobol_rules import scan_path_r01, scan_path_r02, scan_path_r03, scan_path_r04
import json
for f in scan_path_r02('your-source.cbl'):
print(f.to_json())
"
# Transformation differential PoC
bash tools/poc_differential.sh
- name: Check for invisible Unicode
run: python3 tools/check-invisibles.py .
PIC X(n) 是一个原始字节缓冲区。它接受任何字节序列而不进行验证。当 Zowe API 层通过 MOVE 将 JSON 传递给 COBOL copybook 时,不可见 Unicode 会静默进入记录。
固定格式 COBOL 增加了第二个攻击面:位置列语义(第 7 列作为指示符区,第 73–80 列作为标识区)依赖于格式。不保留这些语义的迁移工具可能激活休眠代码或静默破坏程序结构。
与 CVE-2021-42574 共享的机制是检测缺口——绕过视觉检查的内容。数据字段截断向量和格式转换向量与 CVE-2021-42574 中描述的源代码语义翻转不同。
pip install pytest
python -m pytest tests/ -q
# 159 tests, 0 failures
编译器范围: 所有规则仅针对 GnuCOBOL 3.1.2 验证。IBM Enterprise COBOL 和 Micro Focus COBOL 具有不同的标志语义、列边界行为和扩展支持。在这些编译器上的结果未经验证——在测试之前应归类为 INFERENCIA。
R-04 关键字匹配(COL7_VERB): 注释行中 COBOL 动词的检测使用固定关键字列表。包含列表中不存在的安全相关动词的注释行会产生假阴性。R-04 因此被归类为 PROYECCION——它记录的是条件,而非已确认的漏洞。
cfg-shield 类比——功能名称依赖: METHODOLOGY.md 中记录的跨语言方法论假设功能/标志名称遵循可识别的约定。具有非描述性名称的安全相关标志(例如 legacy、compat)在没有人工审查的情况下可能无法正确分类。
单编译器 PoC: 决定性 PoC(poc-same-file.cbl)演示了 GnuCOBOL 下的差异。预期在其他 COBOL 编译器下存在相同的差异类别,但尚未验证。
MIT