Authenticated Arbitrary File Upload Vulnerability in WordPress Download Manager
Two weeks ago we found an arbitrary file upload vulnerability in the plugin XData Toolkit. After finding that we wanted to see if there were any very popular plugins that might have similar issue in them. We didn’t find any with such a serious issue, but we did find that the WordPress Download Manger plugin, which has 80,000+ active install according to wordpress.org, does have a more limited arbitrary file upload issue.
When you attempt to upload a file through this plugin that happens through the uploadFile() function in the file /admin/menus/class.Packages.php:
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | function uploadFile(){ check_ajax_referer('wpdm_admin_upload_file'); if(!current_user_can('upload_files')) die('-2'); if(file_exists(UPLOAD_DIR.$_FILES['package_file']['name']) && get_option('__wpdm_overwrrite_file',0)==1){ @unlink(UPLOAD_DIR.$_FILES['package_file']['name']); } if(file_exists(UPLOAD_DIR.$_FILES['package_file']['name'])) $filename = time().'wpdm_'.$_FILES['package_file']['name']; else $filename = $_FILES['package_file']['name']; move_uploaded_file($_FILES['package_file']['tmp_name'],UPLOAD_DIR.$filename); //@unlink($status['file']); echo "|||".$filename."|||"; exit; } |
That checks to make sure that there is a valid nonce, to prevent cross-site request forgery (CSRF), and that the user has the capability to upload_files, which is usually available to Author level users and above. What it doesn’t do is any way restrict what type of files you can upload, so an Author level user could upload .php files with malicious code in them.
If you try to download such a file through the plugin you get the following error message “Invalid File Type (.php)!”, so it doesn’t look like the uploading .php files through the plugin is something the developers intended. They also restrict the downloading of file with .js and .html extensions:
34 | if(in_array($ext, array('php', 'js', 'html'))) wp_die("Invalid File Type (.{$ext})!"); |
Having to be logged in as a Author level user or above limits the threats of this vulnerability and it is further limited by the fact that the directory the files uploaded by the plugin are stored in, /wp-content/uploads/download-manager-files/, contains a .htaccess file that restricts access to the files. That .htaccess could be worked around by combining this with a local file inclusion (LFI) vulnerability to load the file indirectly or with a vulnerability that allows deleting files and deleting the .htaccess file. Its protection also would not exist if you are using Nginx or IIS as your web server software, since those don’t use .htaccess files (both of those web servers are supported by WordPress).
We notified the developer that issues exists as of the current version, 2.8.97, but have not heard back from them so far.
Proof of Concept
Log in as an Author level user, add a new download through the Download menu, and upload a .php file (or other file of your choosing) on that page. You can then find the file at /wp-content/uploads/download-manager-files/.
Timeline
- 6/20/2016 – Developer notified.
- 3/17/2017 – Version 2.9.46 released, which fixes vulnerability.