NibbleBlog 4.0.3: Code Execution

NibbleBlog 4.0.3: Code Execution

Date: 2015-09-01 10:36:33
Security Advisory – Curesec Research Team

1. Introduction

Affected Product: NibbleBlog 4.0.3
Fixed in: not fixed
Fixed Version Link: n/a
Vendor Contact: Website: http://www.nibbleblog.com/
Vulnerability Type: Code Execution
Remote Exploitable: Yes
Reported to vendor: 07/21/2015
Disclosed to public: 09/01/2015
Release mode: Full Disclosure
CVE: CVE-2015-6967
Credits Tim Coen of curesec GmbH

2. Vulnerability Description

When uploading image files via the "My image" plugin - which is delivered with NibbleBlog by default - , NibbleBlog 4.0.3 keeps the original extension of uploaded files. This extension or the actual file type are not checked, thus it is possible to upload PHP files and gain code execution.

Please note that admin credentials are required.

3. Proof of Concept

  1. Obtain Admin credentials (for example via Phishing via XSS which can be gained via CSRF, see advisory about CSRF in NibbleBlog 4.0.3)
  2. Activate My image plugin by visiting http://localhost/nibbleblog/admin.php?controller=plugins&action=install&plugin=my_image
  3. Upload PHP shell, ignore warnings
  4. Visit http://localhost/nibbleblog/content/private/plugins/my_image/image.php. This is the default name of images uploaded via the plugin.

4. Code

if( $plugin->init_db() ) { // upload files foreach($_FILES as $field_name=>$file) { $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $destination = PATH_PLUGINS_DB.$plugin->get_dir_name(); $complete = $destination.'/'.$field_name.'.'.$extension; // Upload the new file and move if(move_uploaded_file($file["tmp_name"], $complete)) { // Resize images if requested by the plugin if(isset($_POST[$field_name.'_resize'])) { $width = isset($_POST[$field_name.'_width'])?$_POST[$field_name.'_width']:200; $height = isset($_POST[$field_name.'_height'])?$_POST[$field_name.'_height']:200; $option = isset($_POST[$field_name.'_option'])?$_POST[$field_name.'_option']:'auto'; $quality = isset($_POST[$field_name.'_quality'])?$_POST[$field_name.'_quality']:100; $Resize->setImage($complete, $width, $height, $option); $Resize->saveImage($complete, $quality, true); } } } unset($_POST['plugin']); // update fields $plugin->set_fields_db($_POST); Session::set_alert($_LANG['CHANGES_HAS_BEEN_SAVED_SUCCESSFULLY']); } }

5. Solution

This issue was not fixed by the vendor.

5. Report Timeline

07/21/2015 Informed Vendor about Issue
07/22/2015 Vendor Replied
08/18/2015 Reminded Vendor of release date (no reply)
09/01/2015 Disclosed to public