Lucene search
K

SA2K01.txt

🗓️ 02 Mar 2001 00:00:00Reported by MaxType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 18 Views

Fixes exploit RFP2101 for PHP-Nuke to prevent user and password theft. Tested on version 4.4.

Code
`-----/ SA2K01 /-------------------------------/ SecurityApex.com /----  
  
A quick fix against RFP2101  
  
------------------------------------/ Max / [email protected]  
  
Table of contents:  
  
-/ 1 / Information on the exploit  
-/ 2 / Fix for the exploit  
-/ 3 / Credits  
  
--------------------------------------------------------------------------  
Note: This was only tested on PHP-Nuke 4.4 but SHOULD work on PHP-Nuke 4.3  
--------------------------------------------------------------------------  
  
-/ 1 / Information on the exploit /------------------------------------  
  
Recently Rain Forest Puppy released his advisory RFP2101 which contains  
exploits to steal usernames of users on a PHP-Nuke based site and to get  
passwords from the admins who run a PHP-Nuke site. This is a fix for the  
exploit to steal usernames. What the sploit does is exploit this code in  
every script:  
  
if(!isset($mainfile)) { include("mainfile.php"); }  
if(!isset($sid) && !isset($tid)) { exit(); }  
  
if($save) {  
cookiedecode($user);  
mysql_query("update users set umode='$mode', uorder='$order',  
thold='$thold' where uid='$cookie[0]'");  
getusrinfo($user);  
$info = base64_encode("$userinfo[uid]:$userinfo[uname]:".  
"$userinfo[pass]:$userinfo[storynum]:$userinfo[umode]:".  
"$userinfo[uorder]:$userinfo[thold]:$userinfo[noscore]");  
setcookie("user","$info",time()+$cookieusrtime);  
}  
  
So as you can see in the second line of that code your need an $sid and  
a $tid variable, which can both just be set to 0. But next you see, you  
need a $save variable, which should be set to 1. So far we have:  
  
index.php?save=1&sid=0&tid=0  
  
But what can you do with that, you need a user to sploit. Say you want  
to steal the user "Wang". so youd try:  
  
index.php?save=1&sid=0&tid=0&user=Wang  
  
but that wont do much but say your logged in as your ip, which you can  
do nothing with. So next youd want to see why it does that. Notice in  
the code above that it has the function cookiedecode(). The call to   
cookiedecode() takes the string in $user, base64 decodes it, and then  
splits it into parts around the ':' character, putting it into the  
array $cookie[]. This makes sense, since the above SQL query is using  
$cookie[0], the first element of the array. As seen here:  
  
  
function cookiedecode($user) {  
global $cookie;  
$user = base64_decode($user);  
$cookie = explode(":", $user);  
$result = mysql_query("select uid from users where   
uname='$cookie[1]'");  
if (!mysql_num_rows($result)) {  
unset($user);  
unset($cookie);  
}   
return $cookie;  
}  
  
Also, it calls the function getusrinfo():  
  
function getusrinfo($user) {  
global $userinfo;  
$user2 = base64_decode($user);  
$user3 = explode(":", $user2);  
$result = mysql_query("select uid, name, uname, email, femail,   
url, user_avatar, user_icq, user_occ, user_from, user_intrest,   
user_sig, user_viewemail, user_theme, user_aim, user_yim,   
user_msnm, pass, storynum, umode, uorder, thold, noscore, bio,   
ublockon, ublock, theme, commentmax from users where   
uname='$user3[1]' and pass='$user3[2]'");  
if(mysql_num_rows($result)==1) {  
$userinfo = mysql_fetch_array($result);  
} else {  
echo "<b>".translate("A problem ocurred.")."</b><br>";  
}  
return $userinfo;  
}  
  
Which if you look cantains the pass variable. If you want to read more  
on this then read RFP2101. But the basic idea is to tamper with the user  
variable to see if you can use an account WITHOUT the password. Like:  
  
index.php?save=1&sid=0&tid=0&user=1:Wang:blah' or uname='Wang  
  
But there is 1 big problem, PHP has built in ways to escape SQL hacking.  
It adds a / to every ' and the only way to remove it is to user the  
function stripslashes() which nuke does not. But, if you look. it needs  
to Base64 decode the user variable, and it shouldnt add a / to the ' if  
it was encoded in the url, so lets do that. We encode:  
  
1:Wang:blah' or uname='Wang  
  
An easy way to do this in PHP is:  
  
echo base64_encode("1:Wang:blah' or uname='Wang");  
  
And what we come up with is:  
  
MTpXYW5nOmJsYWgnIG9yIHVuYW1lPSdXYW5n  
  
So we try:  
  
index.php?save=1&sid=0&tid=0&user=MTpXYW5nOmJsYWgnIG9yIHVuYW1lPSdXYW5n  
  
And as you can see, it works. Where the biggest problem is, is a user  
doing this:  
  
/user.php?save=1&sid=0&tid=0&user=MTpXYW5nOmJsYWgnIG9yIHVuYW1lPSdXYW5n  
&email=NEWEMAIL&pass=NEWPASS&vpass=NEWPASSAGAIN&uid=1  
&op=saveuser  
  
Which will change the users password AND the email so the user cant get  
their pass back. Ending up in a stolen account.  
  
-/ 2 / Fix for the exploit /------------------------------------  
  
Well when the $user cariable is decoded it MUST have a ' in it, what if  
we recreate the built in PHP anti SQL hacking precedures. Normally we  
can use the AddSlashes() function, but for some odd reason that doesnt  
work. So why not jsut manually add the slashes? Easy, we can do that  
but when that happens, for some reason NO user can log in. Every will  
seem to be logged in as their IP, so why not only do that if there is a  
' in the string after you decode it. And that is how this fix works.  
  
function MaxSlashes($string){  
$string = ereg_replace("'", "\"", $string);  
}  
  
function cookiedecode($user) {  
global $cookie;  
$user = base64_decode($user);  
if(StrStr($user, "'")) {  
$user = MaxSlashes($user);  
$cookie = explode(":", $user);  
$result = mysql_query("select uid from users   
where uname='$cookie[1]'");  
if (!mysql_num_rows($result)) {  
unset($user);  
unset($cookie);  
}   
return $cookie;  
} else {  
$cookie = explode(":", $user);  
$result = mysql_query("select uid from users   
where uname='$cookie[1]'");  
if (!mysql_num_rows($result)) {  
unset($user);  
unset($cookie);  
}   
return $cookie;  
}  
}  
  
If you dont already know, to implement this goto mainfile.php and  
replace the WHOLE cookiedecode() function with these 2 functions.  
From now on users can log in just fine AND when someone tries the  
exploit, it will show them logged in as their IP, which as I said  
earlier, lets them do nothing bad.  
  
-/ 3 / Credits /------------------------------------  
  
Rain Forest Puppy | [email protected] | http://www.wiretrip.net/rfp/  
Article Look, Quotes, Code Snippets, Quotes, RFP2101 Itself  
http://www.wiretrip.net/rfp/p/doc.asp?id=60  
  
NOBODY ELSE ;)  
  
-----/ RFP2101 /-----------/ SecurityApex.com / [email protected] /----`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation