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