abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · opnsense-tunables-loader
类别: 配置行注入 可达性: 远程
OPNsense 核心 26.7.6 (a842fe48) - opnsense.org
System: Advanced: Tunables 仍会将名称/值插值到 /boot/loader.conf。这是 GHSA-fq94 的遗留同类问题。Tunables.xml 中的 tunable / value 是裸 TextField(允许换行)。system_login_configure() 写入 {$param}="{$value}"。Tunables 重新配置还会重启 login。实时 sysctl(8) 会经过 shell_safe 以及 OID 过滤,因此该环节不是 shell 注入。遗留问题是在下次启动时多出的 loader 指令。权限是 page-system-advanced-sysctl,而非 page-all。
此 GitHub 包在协调披露之前保持私有。
| ID | 暂无 CVE |
| 类别 | 配置行注入 |
| 可达性 | 远程(已认证 WebGUI / API) |
| CWE | CWE-93 |
| CVSS | 高危:8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 产品 | OPNsense core |
| 受影响 | 26.7.6 (a842fe48c21288d11a422cb944678e8eb308becf) System: Advanced: Tunables |
| 认证 | 具有 page-system-advanced-sysctl 的 WebGUI 会话或 API 密钥 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | compose exec gadget(hunt slot 18850) |
我固定了标签 26.7.6 的提交 a842fe48。实验环境是一个 PHP gadget,用于复现固定版本 system_login_configure() 的插值。Compose 项目为 opnsense-tunables-loader。Hunt slot 18850 属于 18800-18860 gadget 系列;此 compose 文件使用 docker compose exec php,而非发布的 HTTP 绑定。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
Tunables 值包含 CR/LF(hw.usb.no_boot_wait 加上 "\n# witness) | 在 /boot/loader.conf 中固定 system_login_configure() 额外行 | 完整性(实验证明): 在已闭合的赋值之后,单独一行出现额外的 # OPNSENSE-TUNABLES-LOADER-WITNESS。实验:newline-extra-line=yes。 |
干净值 1 | 同一写入器 | 否定(实验证明): 单条赋值行,无 witness。实验:clean-value-single-line=yes。 |
| 下次启动时相同的额外 loader 行 | loader init_path / module_path / *_load / vfs.root.mountfrom / console | 完整性(推断): 下次启动的 loader 会采用攻击者的键。此 gadget 中未重启。 |
垃圾 loader 行 / 错误的 vfs.root.mountfrom | /boot/loader.conf | 可用性(推断): 启动失败或根错误。 |
POST /api/core/tunables/searchItem | tunables API | 侦察(推断): 列出 tunables,包括 current/default/type。此 ACL 的预期用途。 |
对有效 OID 执行实时 sysctl -w | set_sysctl + OID 过滤 | 预期页面功能。额外 loader 行是遗留问题。 |
实验证明 vs 推断: 换行额外 loader 行和干净值单行是实验 SUCCESS。下次启动 loader 应用为推断。是 gadget,而非完整的 OPNsense FreeBSD VM。
要求: 已登录用户或该用户的 Local API 密钥,具有 page-system-advanced-sysctl 且没有 page-all。POST /api/core/tunables/*。会话 POST 需要 CSRF。重新配置会重启 login;rc.reload_all 和启动也会调用 system_login_configure。
| 攻击面 | 实验 |
|---|---|
| 实时 sysctl shell 注入 | shell_safe 加 OID 过滤 |
| 干净值 | 单条赋值行 |
| 未认证 | 401 |
没有 page-system-advanced-sysctl 的用户 | 403 |
user-config-readonly | save() 抛出异常 |
page-all tunables 管理员设置真实 OID | 预期行为 |
| GHSA-fq94 已修补的 GUI 文本字段 | 不同的汇聚点;此字段未被点名 |
无未认证。无实时 sysctl shell。无 Diagnostics: Command。
cd lab
./run.sh
Compose 项目 opnsense-tunables-loader。Witness OPNSENSE-TUNABLES-LOADER-WITNESS。最后一行:
SUCCESS opnsense-tunables-loader newline-extra-line=yes clean-value-single-line=yes OPNSENSE-TUNABLES-LOADER-WITNESS
根启动器:python3 opnsense-tunables-loader-Abraxas-Labs.py。
从 tunables 名称和值中剥离 CR/LF 和 ",与 GHSA-fq94 同类。将名称类型设为 OID 掩码,而非裸 TextField。使用无法闭合赋值的辅助函数进行引用。除非是已知 loader 键,否则不要将 tunable 写入 /boot/loader.conf。
a842fe48c21288d11a422cb944678e8eb308becfsystem.inc system_login_configure loader.conf 插值Tunables.xml 裸 TextField 名称/值