dataSIMS Avionics ARINC 4.5.3(Data Device Corporation)中的本地基于栈的缓冲区溢出
你好,我是 Kağan Çapar。2020 年 2 月,我在 DDC 的 dataSIMS 航空电子数据总线软件中发现了一个本地基于栈的缓冲区溢出,并于 2021 年 2 月在 Exploit-DB 上发布了一个概念验证。近五年后的 2026 年 1 月,VulnCheck 将其分配为 CVE-2021-47881,成为一个追溯性 CVE —— 我是事后才得知这一分配的,而不是从它那里得知的。
本仓库是该发现的存档记录:按发布时原样保存的原始 PoC、与字节完全一致的 Python 3 移植版本、对载荷的注释性分解,以及对已发布 CVE 记录中两个问题的更正。
先说明范围。 这是一份记录,不是根本原因分析。dataSIMS 是闭源商业软件,没有供应商补丁,我也未针对当前版本重新测试。此处可验证的内容均已验证并展示;其余内容在局限性中说明。如果你期望的是 CVE-2026-5201 那种深度,请先阅读该说明。
| CVE | CVE-2021-47881 |
| CWE | CWE-121 — 基于栈的缓冲区溢出 |
| CVSS v4.0 | 6.7 中 — AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N (VulnCheck) |
| CVSS v3.1 | 8.4 高 — AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (VulnCheck) |
| 受影响 | dataSIMS Avionics ARINC 664-1,版本 4.5.3 |
| 供应商 | Data Device Corporation |
| CNA | VulnCheck |
| 发现日期 | 2020-02-17 |
| PoC 发布日期 | 2021-02-19 — EDB-49577 |
| CVE 发布日期 | 2026-01-23 (NVD) |
| 供应商补丁 | 未发布 |
| 测试环境 | Windows 10 Enterprise x64 |
受影响的组件是 dataSIMS 4.5.3 的 ARINC 664-1 模块。它会读回一个结果文件 —— 尽管它属于该模块 —— 文件名却是 milstd1553result.txt;该名称是从套件的 MIL-STD-1553 血统中遗留下来的供应商产物,并不表示受影响的是哪个模块。提供超长且由攻击者构造的该文件版本,会在回读路径上溢出固定大小的栈缓冲区,并覆盖保存的返回地址。崩溃时完全控制 EIP:
EIP 42424242 <- 'BBBB' from the payload
ECX 42424242
C0000005 <- STATUS_ACCESS_VIOLATION
已发布的 PoC 为 1040 字节,并在 EIP 覆盖处停止。它并未实现代码执行,也从未打算实现 —— 参见可利用性(诚实评估)。
PoC 的字段布局,已通过运行移植版本(py poc/poc_py3.py --layout)验证:
EIP 的偏移量为 1007。 这个数字不是通过 !mona findmsp 或 pattern_offset.rb 得到的 —— 它是五个手工调优字段的总和。原始 PoC 是通过不断加宽崩溃载荷直到返回地址移动来构建的,而不是通过分析定位偏移量。我在此说明这一点,而不是加以粉饰:一次干净的改写会找到到保存的返回地址的真实距离,并完全去掉 align、imp 和 imp2,因为它们都没有承载任何含义。imp/imp2 是填充字符串,不是导入。
buf 是一个 29 字节的 msfvenom shikata_ga_nai 存根。使用 ndisasm -b32 反汇编:
00000000 DAC1 fcmovb st1 ; junk FPU op (sgn signature)
00000002 D97424F4 fnstenv [esp-0xc] ; GetPC
00000006 58 pop eax ; eax = &stub
00000007 BB0B7E9762 mov ebx,0x62977e0b ; XOR key
0000000C 33C9 xor ecx,ecx
0000000E B101 mov cl,0x1 ; <-- ONE 4-byte block
00000010 315819 xor [eax+0x19],ebx ; decode block at +0x19
00000013 83E8FC sub eax,-4 ; eax += 4
00000016 035815 add ebx,[eax+0x15] ; key schedule
00000019 E9 db 0xe9 ; <-- encoded block, not code
0000001A 8B db 0x8b
0000001B 7C9C jl 0xffffffb9
由此可以得出两点,而这两点都意味着该载荷永远无法运行:
mov cl,0x1 —— 解码循环被配置为仅处理一个 4 字节块。其背后没有真正的载荷,只有那 4 个字节。\xe2\xf4(loop)终止符。 一个完整的 sgn 存根会在编码主体之前以 loop 结束解码循环。而这里执行流会直接从 add ebx,[eax+0x15] 落入 E9 8B 7C 9C —— 此时该序列仍处于编码状态,而且无论如何都不是一条有效的指令序列。因此,这个存根只是占用载荷尾部的一个占位符。这与 PoC 在 Exploit-DB 上的描述一致,也是最诚实的解读:这是一个 EIP 控制演示,而不是一个可用的漏洞利用。
以漏洞经纪商或供应商会采用的方式,而不是 CVSS v3.1 向量的方式来权衡这一点:
milstd1553result.txt 是应用程序自身生成的文件,位于同一用户本来就已控制的位置。能够改写该文件的攻击者通常已经可以以该用户身份运行代码。这使得它与其说是安全缺陷,不如说是一个健壮性缺陷。EIP 本身说明不了太多。要将其转化为代码执行,需要满足 DEP/ASLR 的条件 —— 一个未启用 /DYNAMICBASE 的模块、一条 ROP 链,或一次部分覆盖。这些都没有做,而且我也没有检查当前构建自带了哪些缓解措施。UI:A 反映了现实;v3.1 的 UI:N 则没有。如果有人想让这个问题真正变得有意思,那么有价值的攻击面根本不是这个文件:DDC 为其 1553/664 PCIe 卡附带的内核驱动程序(IOCTL 处理 → LPE)、任何面向网络的 ARINC 664/AFDX 帧解析,以及该套件从不可信来源消费的输入文件格式。那些跨越了真正的边界。而这个并没有。
CVE 记录存在两个值得明确指出的缺陷,因为它是用我的名字发布的。
记录中的产品名称 —— "dataSIMS Avionics ARINC 664-1 version 4.5.3" —— 是正确的。受影响的组件是 ARINC 664 模块,正如我最初的 Exploit-DB 标题所述。
缺陷在于 CNA 所附加的供应商引用。NVD 引用了 BU-69414,这是 DDC 的 MIL-STD-1553 软件产品页面 —— 与本发现所影响的数据总线栈不同。ARINC 664 是 AFDX(规范化的交换式以太网,ARINC 664 第 7 部分);MIL-STD-1553 是 1 Mbps 双余度命令/响应总线。它们是不相关的标准。
引用错误可能的原因在于结果文件名。dataSIMS 将 ARINC 664 模块的结果文件命名为 milstd1553result.txt —— 这是套件 MIL-STD-1553 血统的遗留物。任何阅读 CVE 描述并寻找对应供应商产品页面的人,都会顺着这个字符串直接找到 1553 产品线,而实际情况似乎正是如此。文件名并不是受影响模块的证据,而指向 1553 产品页面的记录会让防御者审计错误的组件。
两个向量都来自 VulnCheck,而在两个重要方面它们相互矛盾:
| v3.1(8.4 高) | v4.0(6.7 中) | |
|---|---|---|
| 用户交互 | UI:N — 无 | UI:A — 必需 |
| 影响 | C:H/I:H/A:H — 完整的 CIA | VC:N/VI:N/VA:H — 仅可用性 |
它们不可能同时正确。v4.0 向量是站得住脚的:PoC 展示的是崩溃,而不是信息泄露或完整性损失。v3.1 的 8.4 分夸大了这一发现,我宁愿在此明说,也不愿从中获益。
这里的一切都不需要目标软件 —— PoC 仅写入畸形文件。触发溢出需要 dataSIMS 4.5.3,这是本仓库未分发的授权商业软件。
# print the field map, write nothing
py poc/poc_py3.py --layout
# write the 1040-byte payload
py poc/poc_py3.py -o milstd1553result.txt
然后在调试器中用受影响的构建加载该文件,并观察 EIP 覆盖。poc/49577.py 是最初的 Python 2 源码,已逐字存档;它无法在 Python 3 上运行。
移植版本会生成字节完全相同的 1040 字节文件(sha256 530efb5e…)。有三处必须修改,还有一件看似是 bug 的事情其实并不是 bug:
print len(win32) 在 Python 2 中是语句,在 Python 3 中会引发 SyntaxError。str 字段与 bytes shellcode 拼接。Python 2 允许这样做,因为 str 就是字节;Python 3 会抛出 TypeError。open(..., "w") 必须改为 "wb"。在文本模式下,Python 3 会对存根中每个 ≥ 0x80 的字节进行 UTF-8 编码 —— 0xda → 0xc3 0x9a —— 从而悄悄破坏载荷并改变其长度。imp2 = "\x61\x72\x61\x63\x61\x67\x131\x7a" 不是 与版本相关的怪癖。在 Python 2 和 3 中,\x 都恰好占用两位十六进制数字,因此 \x131 是 后跟字符 。该字段在两种版本中都是 9 字节。它只是读起来很难看。明确列出如下,以免有人需要猜测完成了什么、没完成什么:
EIP 覆盖就是全部结果。Kağan Çapar — GitHub · Exploit-DB · LinkedIn · X
| 字段 | 偏移量 | 长度 | 内容 |
|---|
junk | 0 / 0x000 | 600 | 0x41 填充 |
align | 600 / 0x258 | 8 | "22221111" |
prop | 608 / 0x260 | 380 | 0x43 填充 |
imp | 988 / 0x3dc | 10 | "bzhrturlu2" |
imp2 | 998 / 0x3e6 | 9 | "aracag" 0x13 "1z" |
overwrite | 1007 / 0x3ef | 4 | 0x42 × 4 → 保存的返回地址 |
buf | 1011 / 0x3f3 | 29 | shikata_ga_nai 解码存根 |
| 总计 | 1040 | sha256 530efb5efef917082e40dcf379f5e0a526375724af18aba6f0270f794f96d066 |
0x131| 日期 | 事件 |
|---|
| 2020-02-17 | 发现漏洞 |
| 2021-02-19 | PoC 发布 —— EDB-49577 |
| 2026-01-22 | VulnCheck 公告发布 |
| 2026-01-23 | CVE-2021-47881 发布至 NVD |
| 2026-06-17 | NVD 记录最后修改 |