Yorick Koster, November 2016

Pwning WordPress with Cross-Site Scripting



Last July we organized the Summer of Pwnage, which resulted in 118 security findings in WordPress Core and Plugins. By far the most found vulnerability is Cross-Site Scripting, 66% of the findings fall into this category. When targeting a WordPress Administrator, Cross-Site Scripting can result in a full compromise of the WordPress site. In this blog I'll describe one method to achieve this.

Stored Cross-Site Scripting vulnerability in 404 to 301

The vulnerability we're going to exploit is an unauthenticated stored Cross-Site Scripting vulnerability in the 404 to 301 WordPress Plugin. This plugin automatically redirects, logs and notifies all 404 page errors to any page using 301 redirect for SEO.

The vulnerability was discovered by Alyssa Milburn and allows for a Cross-Site Scripting attack against a logged on Administrator (that views the 404 error log). This issue can be exploited by using a specially crafted User-Agent and/or Referer header. It is resolved in 404 to 301 WordPress Plugin version 2.3.1.

The attack

The goal of the attack is to run arbitrary code on a WordPress server. To do so, the attack is divided into following steps:

- Inject Cross-Site Scripting payload using the vulnerability in the 404 to 301 Plugin.
- Wait for an Administrator to view the 404 error log - this triggers the payload.
- Fetch the 2n stage payload from a remote server, which:
   - clears the error log.
   - modifies a Theme (PHP) file; inject arbitrary PHP code.
   - visits the modified file to run the injected PHP code.

WordPress uses jQuery, which we can also use to perform our attack. In order to perform these actions we must also take into account that WordPress has measures implemented to mitigated Cross-Site Request Forgery attacks. Due to this we first need to obtain a valid anti-CSRF token (nonce). For example, if we would like to alter the file footer.php of the active WordPress Theme, we can do the following to get the token:

   url: 'theme-editor.php?file=footer.php',
   dataType: 'text',
   success: function(data) {
      var form = jQuery('<div>').html(data)[0].getElementsByTagName("form")[1];
      _wpnonce = jQuery('form[name=template] input[type=hidden][name=_wpnonce]').val();
      _wp_http_referer = jQuery('form[name=template] input[name=_wp_http_referer]').val();

Metasploit exploit module

The attack described above was implemented in a Metasploit exploit module. If the exploit module is successful, a Meterpreter Session will be started on the target WordPress site. Before the attack is initiated the module first tries to determine whether the 404 to 301 Plugin is installed and activated. The Metasploit exploit module can be downloaded from the following URL: /exploit/SFY20161115/wp_404-to-301_xss.html


Work with us →