Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
pfsense-api-example-ssl-verify — pfSense Plus MIM API 工具包 b4acd7ca - 中危 - 远程 - 权限残留 - 官方示例 verify_ssl=False | Kitploit
工具/GitHubGitHub/abraxas/pfsense-api-example-ssl-verify
防御工具漏洞分析漏洞利用信息收集Web安全网络安全渗透测试身份验证论文与研究

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
GitHubabraxas/pfsense-api-example-ssl-verify

pfsense-api-example-ssl-verify

pfSense Plus MIM API 工具包 b4acd7ca - 中危 - 远程 - 权限残留 - 官方示例 verify_ssl=False

查看仓库
11天前尚未审核

Abraxas Labs - pfsense-api-example-ssl-verify

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  pfsense-api-example-ssl-verify

pfsense-api-example-ssl-verify

类别: 权限残留 可达性: 远程

pfSense Plus MIM API(Netgate/pfsense-api b4acd7ca)- Netgate

生成的 Client / AuthenticatedClient 默认 verify_ssl=True,并将其传入 httpx。文档已将 verify_ssl=False 称为安全风险,并首先展示 PEM 捆绑包路径。每个官方 Python 示例和 helper_funcs.py 仍然使用 verify_ssl=False 构造它们。example.js 设置 NODE_TLS_REJECT_UNAUTHORIZED=0,因此整个 Node 进程跳过验证。登录 JSON 将用户名和密码放入 base64。这是 OpenAPI 契约,不是加密。TLS 是机密性层。

:8443 的路径中间人呈现任意证书。示例仍然 POST /login。中间人捕获 base64 管理员登录并铸造 JWT。该令牌就是链条:G4 export-key、G5 ACME dump、G6 fleet JWT、G7 ACB userkey、预期的 php/shell,以及 G1 插值到 SSH 的 JSON。

这是 pfSense Plus MIM API 工具包的第 9 部分。即使它是 Medium,也请先阅读此残留。被盗的 JWT 是其余部分如何从复制了 example.py 的工作站变得可达的方式。

ID暂无 CVE
类别权限残留(示例 TLS 验证关闭)
可达性远程(到 :8443 的路径中间人)
CWECWE-295
CVSS中危:6.8 CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
产品Netgate/pfsense-api(Plus Nexus MIM 客户端;不是 CE REST 包)
受影响公共 main b4acd7ca21dbca739a530403a1f62a7440f7726f(2026-05-25)官方示例和 helper_funcs.py
认证操作员复制并针对控制器运行示例;无需额外控制器角色
许可证GNU Affero GPL v3.0
实验室仅 127.0.0.1:19191。不组合 pfSense Plus。

AC:H 是操作员工作站与 MIM 控制器之间的路径中间人。UI:R 是复制/运行示例。

攻击者能做什么

受害者:操作员工作站针对 https://controller:8443 运行官方示例或 helper_funcs.py。攻击者:该 HTTPS 的路径中间人(LAN、流氓 DHCP、被入侵的 VPN 跳点、ARP)。不是未认证的互联网到防火墙。

方法汇聚点权限
在样本以 verify_ssl=False / NODE_TLS_REJECT_UNAUTHORIZED=0 POST /login 或 /api/login 时出示任意证书httpx verify=False(Python 样本)或 Node TLS reject-unauthorized 0机密性(实验室验证): 读取登录 JSON。实验室:替身捕获了 base64 编码的 admin / lab-controller-secret(captured_b64_admin=yes)。解码只需一条 base64 -d。
同样的 MITM,200 LoginResponse样本接受任意证书机密性(实验室验证): 窃取访问 JWT。实验室:INJECT 获得了一个携带 PFSENSE-API-EXAMPLE-SSL-VERIFY-WITNESS 的令牌。
同样的 MITM,登录时的 Set-Cookie样本将 client.get_httpx_client().cookies 复制到 AuthenticatedClient机密性(实验室验证 cookie,推断重放): 24 小时刷新 JWT。在刷新 TTL 内,用该 cookie 加上 base64 用户名重放 POST /login/refresh。实验室捕获了 Set-Cookie: refresh=...。针对实时控制器的刷新未执行。
将窃取的 Bearer 重放到真实控制器(如果攻击者也能路由到它)加上 MIM /api 和 /api/device/pfsense/{device_id}/api完整性(推断): 在此 API 上等同于已登录用户的管理员权限。Schema 包含 POST /diag/cmd/php、POST /diag/cmd/shell、POST /diag/editfile、POST /diag/backup/restore、POST /diag/control 停机/重启。此处未实际演练。本实验室是控制器替身,不是 Plus。
将窃取的 Bearer 作为遗留项 6(fleet 令牌)重放一个 POST /login JWT 被复用于每个 device_id完整性(推断): 以本应为防火墙 A 认证的用户身份与防火墙 B 通信。LoginResponse 没有按设备的允许列表。利用包:pfsense-api-fleet-jwt。Plus RBAC 未执行。
将窃取的 Bearer 作为遗留项 4 重放GET /system/certauth/{refid}/export-key、GET /system/certificates/{refid}/export-key、GET /system/certificates/{refid}/export-p12机密性(推断): 提取 CA 和叶私钥,PKCS12 文档记载无密码保护,然后冒充 VPN / WebGUI TLS / IPsec。利用包:pfsense-api-export-key-get。
将窃取的 Bearer 作为遗留项 5 重放GET /services/acme机密性(推断): 窃取 Let's Encrypt 账户密钥以及防火墙为每个主机名签发的证书密钥。利用包:pfsense-api-acme-key-dump。
将窃取的 Bearer 重放,或从 GET ACB 的样本中泄露 userkey,作为遗留项 7GET /services/acb?userkey= 和 GET /services/acb/bkp?userkey=机密性(推断): 列出并获取 Auto Config Backup blob(完整配置)。利用包:pfsense-api-acb-userkey。
将 ControllerSummary JSON 塑形为遗留项 1对 verify_ssl=False HTTPS 的 MITM 提供 JSON,example-add-devices.py 对其做引号转义后 .format 进 SSH完整性(推断): 控制器字段中的 $() / 反引号 / 换行会在 pfsense_addresses 中的每个地址上以 SSHUSER 身份执行。利用包:pfsense-api-enroll-json-ssh。
向客户端注入响应skip-verify 接受任意证书完整性(实验室验证令牌,推断 fleet): 铸造一个样本会保留的 JWT。实验室:INJECT 令牌带有见证。针对实时样本的伪造设备列表 / 升级进度 / 登录成功是同一道门。
POST /diag/control、固件 POST、恢复损坏的备份(在窃取 Bearer 之后)TLS 消失后本应受管理员保护的界面可用性(推断): 停机 / 重启 / 损坏镜像。同样的 Bearer。未做实验室验证。

实验室验证 vs 推断: CONTROL 握手失败、INJECT 令牌以及捕获的 base64 admin 登录均在 127.0.0.1:19191 上经实验室验证。将该 Bearer 重放到实时 Plus 控制器、diag php/shell、G4-G7、G1 JSON 塑形,以及用刷新 cookie 铸造新的访问 JWT,均是从 OpenAPI 和样本推断而来。

要求: 操作员复制并通过 helper_funcs.py 运行 example.py、example-add-devices.py、example-upgrade-devices.py、example-set-alias.py / example-upgrade-devices-async.py,或运行 example.js。攻击者位于通往 :8443 的路径上。

保持关闭的相邻攻击面

攻击面为何关闭
生成的 Client(base_url=...) 且无 kwargsverify_ssl=True。实验 CONTROL:CERTIFICATE_VERIFY_FAILED,零 HTTP 捕获。
跨主机 3xx 凭据转发生成的 follow_redirects=False。
伪造的 JWT 被此客户端接受为登录客户端不是资源服务器;载荷解析仅用于 exp 显示。
未经操作员客户端对 8443 的未认证互联网访问Plus MIM 绑定/ACL 是关闭的服务器,而非此工具包。
example.conf 中提交的密码PASSWORD 行已被注释。
CE REST 包(jaredhendrickson / pfrest.org)不同的产品。
pfSense Plus 本身不在此 GitHub 树中;本实验不组合 Plus。

跳过验证的示例本身并不会在 pfSense 设备上导致未认证 RCE。它们导致的是对复制了示例的操作员的 MITM。Shell/PHP 诊断是在窃取管理员 Bearer 后推断出的 schema 权限。

client = Client(base_url=CONTROLLER_URL+"/api",
				verify_ssl=False,
				headers={"Content-Type": "application/json"})

example.py:47、example.py:78、example.py:120;helper_funcs.py:135、helper_funcs.py:167,以及 createDeviceApiChild / clone;example-add-devices.py:64、example-add-devices.py:94;example-upgrade-devices.py:57、:86、:132。helper_funcs.get_settings() 没有 VERIFY_SSL 环境变量(与 PASSWORD 不同)。

// To be able to use with self-signed Controller TLS certificates:
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

生成的默认值,由样本覆盖:

_verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")

py/pfapi/client.py:42 以及 AuthenticatedClient 上的同一字段。两者都将 verify=self._verify_ssl 传入 httpx。py/README.md 先展示 verify_ssl="/path/to/certificate_bundle.pem",然后展示 False,并附有 this is a security risk。

我是如何发现的

我固定了 b4acd7ca,并将生成的客户端与手写示例并排阅读。库默认值为 True。每个官方构造仍然传入 False。JS 是进程全局的。我差点因为已发布的包会进行验证,就把这当作 gist 级别的“不是这个问题”而搁置。然后我数了数示例调用点。十三个 Python。全部为 False。接着我在回环地址上搭建了一个自签名控制器。

弯路:把这当作 gist 级别的库遗留问题(生成的默认值会验证);把 OpenAPI base64 登录字段当作密码哈希漏洞;把 JWT 的 split(".")[1] 当作跳过签名的认证(它其实是 exp 显示);组合 Plus;声称跳过验证本身就能导致未认证 RCE。

实验环境

python3 pfsense-api-example-ssl-verify-Abraxas-Labs.py

或

cd lab
./run.sh

仅回环:HTTPS 127.0.0.1:19191。Compose 项目 pfsense-api-example-ssl-verify。自签名替代证书,CN 为 pfsense-controller.lab,SAN 不包含回环 IP。CONTROL ssl/httpx verify=True 必须失败。INJECT verify=False POST 到 /login,并且必须获得携带见证的 JWT。不组合 pfSense Plus。运行结束后栈拆除。

SUCCESS pfsense-api-example-ssl-verify control_verify_true=fail inject_verify_false=token captured_b64_admin=yes PFSENSE-API-EXAMPLE-SSL-VERIFY-WITNESS

固定 SHA b4acd7ca21dbca739a530403a1f62a7440f7726f。

修复方案

让示例保持库默认的 verify_ssl=True。记录固定控制器 CA 的方法(verify_ssl="/path/to/certificate_bundle.pem")。从 example.js 中移除 NODE_TLS_REJECT_UNAUTHORIZED=0,或将其作用域限制为控制器代理。为 helper_funcs.py 添加一个默认值为 True 的 VERIFY_SSL 开关。

参考资料

下载工具