abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-limiter-number
技术分析文章:https://abraxaslabs.tech/research/pfsense-limiter-number
类别: RCE 可达性: 远程
pfSense CE 2.9.0-DEVELOPMENT(9363ac5)- pfsense.org
流量整形限流器(Traffic Shaper Limiters)在编辑时会输出一个隐藏的 number 字段。创建操作会用 dnpipe_find_nextnumber() 覆盖该编号。编辑操作则不会。validate_input 从不检查 number。GetNumber() 被不加引号地拼接进 dnctl pipe|sched|queue delete。PHP 的 mwexec 即 /bin/sh -c。所需权限为 page-firewall-trafficshaper-limiter,而非 Diagnostics: Command。
| ID | 暂无 CVE |
| 类别 | RCE |
| 可达性 | 远程(已认证 WebGUI) |
| CWE | CWE-78 |
| CVSS | 高危:8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 产品 | pfSense CE |
| 受影响版本 | 2.9.0-DEVELOPMENT(9363ac5b8651a1c7a333180425ce7719070f95f9)限流器 number |
| 认证 | 具备 page-firewall-trafficshaper-limiter 权限的 WebGUI 会话 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
我固定了公开 master 分支 9363ac5。实验环境是一个由固定版本的 ReadConfig / SetNumber / delete_queue 组成的 PHP gadget。回环地址 127.0.0.1:18840。
| 方法 | 汇聚点 | 权限 |
|---|---|---|
创建一个限流器,POST 保存时携带攻击者控制的 number,然后删除该限流器 | mwexec("/sbin/dnctl pipe delete " . $this->GetNumber())(shaper.inc:3820) | 完整性(实验已验证): root shell。实验:编辑-删除写入了见证文件(edit-delete-exec=yes)。创建覆盖与 apply-file 路径均未写入。 |
| 同上 root shell | 主机文件系统 | 侦察(推断): config.xml、密钥。 |
Root shell 或对攻击者编号执行 dnctl | dummynet | 可用性(推断): 限流器 / dummynet 中断。 |
实验已验证 vs 推断: 创建覆盖(无见证)、apply-file 路径(对文件执行 dnctl,无见证)以及编辑-删除执行(有见证)均为实验已验证。文件系统侦察由 root PHP-FPM 推断得出。
前提条件: 具备 page-firewall-trafficshaper-limiter 权限的 WebGUI 会话。POST 保存需 CSRF。删除为 GET action=delete。
| 攻击面 | 实验 |
|---|---|
| 创建路径 | dnpipe_find_nextnumber() 覆盖,create-overwrites=yes |
| 应用路径 | 对 /tmp/rules.limiter 执行 dnctl,文件名不受用户控制,apply-file=yes |
| 限流器名称字符集 | ^[a-zA-Z0-9_-]+$ |
| 未认证 | 关闭 |
| Diagnostics: Command | 除非同时授予,否则保持关闭 |
写入 /tmp/rules.limiter 的 AQM 参数属于额外的 dummynet 语言,并非此遗留问题。
cd lab
./run.sh
回环地址 127.0.0.1:18840。Compose 项目 pfsense-limiter-number。镜像标签 pfsense-limiter-number:2.9.0-dev。见证值 PFSENSE-LIMITER-NUMBER-WITNESS。最后一行:
SUCCESS PFSENSE-LIMITER-NUMBER create-overwrites=yes apply-file=yes edit-delete-exec=yes PFSENSE-LIMITER-NUMBER-WITNESS
在每次调用 dnctl 之前,对 GetNumber() 进行整数强制转换。在编辑时忽略 POST 传入的 number,或者将其与当前活动的 dummynet id 进行范围校验。创建操作已经会覆盖,让编辑操作也做同样处理。
9363ac5b8651a1c7a333180425ce7719070f95f9shaper.inc delete_queue / GetNumberfirewall_shaper_vinterface.php