Paytium 3.0.13 WordPress插件中的存储型XSS漏洞
作者:Jonathan Bouman
概念验证
背景
WordPress目前是市场份额达60%的最常用内容管理系统。默认情况下,WordPress仅是一个博客平台,但通过安装插件,可以将其转换为网店、众筹平台甚至读心术工具。
任何人都可以创建和发布WordPress插件,没有质量控制机制,唯一参考是其他用户的插件评价。然而,已安装插件中的一个漏洞可能导致严重问题:客户数据可能被盗取,甚至攻击者可能获得网站管理员权限。
Paytium WordPress插件
我有时会接受朋友的挑战来测试他们网站的安全性。其中一位朋友运营一个销售在线培训课程的网站,这是一个简单的WordPress网站,部分内容仅限订阅者访问。她使用名为Paytium的插件来接收订阅者的在线支付。
Paytium允许用户在WordPress页面中插入支付表单,包括简单的捐赠表单或包含客户姓名和邮箱地址的扩展表单。截至2019年9月,该插件约有3000多次安装。
存储型XSS
我首先尝试在姓名字段中输入HTML代码,观察是否会被渲染。如果能够向该字段注入HTML,当网站管理员查看包含被篡改姓名的记录时,代码可能在WordPress管理员后台执行。
尝试在姓名字段加载图片:
|
|
HTML注入成功,这被称为存储型XSS。输入未经过适当验证,使我们能够添加自定义HTML内容。我们在WordPress后台获得了认证存储型XSS!
此外,Paytium插件还会向攻击者发送包含公开发票链接的邮件(发票ID经过哈希处理)。这导致了公开存储型XSS漏洞。
漏洞代码
由于Paytium插件是免费的,我们可以获取其代码。经过几分钟搜索,发现名为get_field_data_html()
的函数,它直接输出存储的数据而未进行HTML转义。该代码被WordPress后台用于显示订单概览。
|
|
从存储型XSS到完全接管WordPress
如果我们能静默添加具有预定义用户名和密码的新管理员用户呢?好主意!
WordPress有一个特殊页面,允许管理员邀请新用户并指定其角色。该表单受nonce保护。nonce是一个包含秘密值的隐藏参数,由浏览器发送到服务器。服务器使用它验证请求是否来自原始表单,否则恶意网站可能代表受害者提交表单,即CSRF攻击。
服务器将隐藏的nonce添加到每个渲染的表单中。外部恶意网站无法获取此nonce值,因为默认情况下浏览器不允许一个域查看另一个域的HTML内容。没有nonce,我们无法提交表单。
然而,通过JavaScript,我们可以请求同一域的页面。由于在受害者域中存在存储型XSS漏洞,我们能够请求user-new.php
页面并查看HTML响应,从而提取nonce值并使用预定义的登录详细信息提交user-new.php
表单。
攻击载荷
|
|
攻击载荷分为两个阶段:
- 请求
user-new.php
页面并使用正则表达式提取nonce值 - 向
user-new.php
页面提交POST请求,包含预定义的登录详细信息和步骤1中的nonce
短域名的必要性
您可以直接将脚本放在姓名字段的<script></script>
标签中。但大多数字段有字符数限制或不允许特殊字符。建议将攻击载荷放在文件(如1.js
)中,并在互联网上的短域名上托管。域名越短越好,以避免表单中的字符限制。因此,获取一个3或4字符长的域名并上传攻击载荷!
上传到外部域时,确保支持HTTPS,以避免浏览器关于"不安全内容"的警告。
最终攻击载荷
|
|
结论
由于Paytium插件对用户输入验证不当,我们能够向WordPress后台注入JavaScript。任何加载此JavaScript的WordPress管理员将自动添加具有我们预定义凭证的新管理员用户,导致完全接管WordPress。此外,我们能够通过未认证的发票URL查看存储型XSS攻击载荷,这对网络钓鱼者来说是完美的。
解决方案
- WordPress支持开箱即用的用户输入验证:https://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data。这允许轻松渲染用户输入并避免常见的HTML注入。
- WordPress应在执行重要操作前要求管理员手动输入密码。例如,在添加新管理员或安装插件前需要密码提示。另一种解决方案是设置不同的访问级别:只想查看新订单?使用没有超级权限但足以查看订单的用户登录。更多信息请参见角色和能力。
时间线
- 2019年7月31日:发现初始漏洞
- 2019年9月4日:撰写报告并通过邮件通知Paytium
- 2019年9月5日:Paytium要求更多细节
- 2019年9月6日:Paytium发布插件更新,未提及安全修复
- 2019年9月7日:Paytium发布插件更新,未提及安全修复
- 2019年9月28日:发现未认证存储型XSS漏洞,更新报告并邮件通知Paytium
- 2019年10月1日:Paytium回复报告评论,表示正在准备安全修复,本周晚些时候更新状态
- 2019年10月4日:添加关于WordPress角色和能力功能的内容,添加为特殊操作引入提示屏幕/手动输入的解决方案
- 2019年10月7日:Paytium发布修复并通过邮件通知客户
- 2020年5月12日:报告公开