在 Portainer CE 2.19.4 中发现了一个用户枚举漏洞。该问题出现在用户身份验证过程中,响应时间的差异可能允许远程未认证用户判断用户名是否有效。
该漏洞已通过 Portainer 的 issue #11736 修复,该修复随 Portainer CE 2.19.5 和 2.20.2 版本一起发布。
我是在尝试对 Portainer 实例的登录页面进行密码喷洒(password spray)攻击时发现该漏洞的。我向 Portainer 应用程序的登录表单提交了多个包含不同用户名和密码的请求。
无论用户是否存在,只要用户名 + 密码组合不正确,Portainer 应用程序的后端就会返回相同的 HTTP 状态码。这符合防止(或阻碍)枚举有效用户尝试的最佳做法。
然而,在查看密码喷洒的结果时,我注意到对某些用户名的登录尝试始终需要一定的平均时间,而对其他用户名的登录尝试则始终需要明显更长的平均时间。
系统必须检查现有用户密码的有效性,但如果用户名本身无效,则无需检查。因此,我推测登录尝试平均时间的明显变化与此有关。随后,我安装了本地版本的 Portainer CE 2.19.4,并尝试复现该行为,得到了相同的结果。
这是我发送的请求格式。选择了用户名和密码字段来插入载荷。

这些是我在用户名字段中插入的用户。在此测试中,只有 "admin" 和 "felipe" 用户是有效的。列表中的其他用户名均不对应现有用户。

而这些是我在密码字段中插入的密码。

对于每一对唯一的用户名-密码组合,都向服务器发送了一个请求。结果如下所示。

当用户名对应现有用户时,与非现有用户的登录尝试相比,登录尝试始终且明显需要更长的时间。
这意味着该版本的 Portainer 系统容易受到有效用户枚举攻击——通过观察后端响应登录尝试所花费的时间,攻击者能够枚举应用程序的用户。