Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
PHP parse_str() arbitrary variable overwrite |

07.09.2007, 08:57
|
|
♠ ♦ ♣ ♥
Регистрация: 18.05.2006
Сообщений: 1,828
Провел на форуме: 8042357
Репутация:
3742
|
|
PHP parse_str() arbitrary variable overwrite
Удаленная перезапись переменной в ф-ии parse_str() в PHP.
Оригинал http://www.acid-root.new.fr/advisories/14070612.txt
[I]. Вступление
PHP.Net: PHP Это популярный язык программирования с открытым исходным кодом, который в первую очередь используют для разработки серверных приложений, создания динамического вэб-контэнта и другого софта.
Название PHP:Гипертекстовый процессор является рекурсивным акронимом. Более того это ретроним (ретроним - это обозначение, состоящее из существительного и дополнения к нему, имеющего тоже самое значение что и сущ). Смотрите историю пхп.
[II]. Руководство.
Функция void parse_str ( string $str [, array &$arr] ) парсит строку str, которая должна иметь формат типа URL и присваивает значения переменным в текущем контексте, если не передан второй аргумент arr. В последнем случае значения будкт сохранены в этой переменной как элементы массива.
Замечание: Поддержка необязательного второго аргумента была добавлена в PHP 4.0.3.
Замечание: Для получения текущей строки запроса (QUERY_STRING) может быть использована переменная $_SERVER['QUERY_STRING']. Также ознакомьтесь с разделом "Переменные вне PHP".
Замечание: Опция magic_quotes_gpc влияет на выходящее значение ф-ии, т.к. parse_str() использует тот же механизм, что пхп использует для заполнения $_GET, $_POST.
[III]. Исходный код.
Код:
--- ./ext/standard/string.c ---
4025. /*
4025. {{{ proto void parse_str(string encoded_string [, array result])
4026. Parses GET/POST/COOKIE data and sets global variables
4026. */
4027. PHP_FUNCTION(parse_str)
4028. {
4029. zval **arg;
4030. zval **arrayArg;
4031. zval *sarg;
4032. char *res = NULL;
4033. int argCount;
4034.
4035. argCount = ZEND_NUM_ARGS();
4036. if (argCount < 1 ||
4036. argCount > 2 ||
4036. zend_get_parameters_ex(argCount,&arg,&arrayArg) == FAILURE)
4036. {
####. /* Not enough or too many args */
4037. WRONG_PARAM_COUNT;
4038. }
4039.
4040. convert_to_string_ex(arg);
4041. sarg = *arg;
4042. if (Z_STRVAL_P(sarg) && *Z_STRVAL_P(sarg)) {
4043. res = estrndup(Z_STRVAL_P(sarg), Z_STRLEN_P(sarg));
4043.
####. /* Allocate Z_STRLEN_P(sarg)+1 bytes of memory and copy
####. Z_STRLEN_P(sarg) bytes from Z_STRVAL_P(sarg) to the
####. newly allocated block */
4044. }
4045.
####. /* parse_str(argv1) */
4046. if (argCount == 1)
4046. {
4047. zval tmp;
4048. Z_ARRVAL(tmp) = EG(active_symbol_table);
4049.
####. /* The problem is here, there is no conditions before setting
####. the variable. If a variable already exists, it will overwrite it */
4049.
4050. sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
4051. }
####. /* parse_str(argv1,argv2) */
4051. else
4051. {
4052. /* Clear out the array that was passed in. */
4053. zval_dtor(*arrayArg);
4054. array_init(*arrayArg);
4055.
4056. sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC);
4057. }
4058. }
[IV]. Пояснения
Как вы уже увидели в мануале, пользователь, использующий эту ф-ию не защищен от перезаписи переменных. Девелоперы просто забыли проверить этот момент. Простой PoC:
PHP код:
<?php
# ?var=new
###########
$var = 'init'; #
parse_str($_SERVER['QUERY_STRING']); #
print $var; # new
# ?array[]=new # Array
############## # (
$array = array('init'); # [0] => init
parse_str($_SERVER['QUERY_STRING']); # [1] => new
print_r($array); # )
# ?array=new
############ # Array
$array = array('init'); # (
parse_str($_SERVER['QUERY_STRING'],$array); # [array] => new
print_r($array); # )
?>
Этот тип уязвимости открывает дверь к многим другим уязвимостям, поэтому в данном случае достаточно сложно обозначить уровень риска. В отлчиие от extract(), тут нет опции на подобии EXTR_SKIP, которая отвечает за защиту от перезаписи переменной (если переменная с таким именем существует, будет сохранено её прежнее значение). Поэтому если вы хотите чтобы ваш код был безопасным - не используйте эту ф-ию. Я не связывался с пхп-тимой, но возможно они зарелизят фикс на эту уязвимость.
Избранные мысли из [V]. Комменты
1. Даже если register_globals отключено, уязвимость есть как минимум на пхп 4.4.4
2. Hardened-PHP и PHP с сухосин патчем тоже уязвимы.
3. При тесте уязвимости она имело место на
Apache/2.0.59 (FreeBSD) DAV/2 PHP/4.4.7 with Suhosin-Patch
и
Apache/2.2.4 (Darwin) PHP/5.2.3
__________________
Привет! Меня зовут Джордж, и я хотел бы рассказать вам про реинкарнацию (ц) 2x2
|
|
|

07.09.2007, 16:33
|
|
Постоянный
Регистрация: 14.01.2007
Сообщений: 459
Провел на форуме: 1469995
Репутация:
589
|
|
Сколько двигов перерыл, но что-то эту функцию видел в применении всего несколько раз. Так что особой "опасности" и чего-то сверхестественного тут не вижу. Просто нужно думать, когда используешь. // и не только тут)
|
|
|

11.09.2007, 03:06
|
|
Banned
Регистрация: 10.07.2005
Сообщений: 224
Провел на форуме: 1062041
Репутация:
50
|
|
2blackybr:маладец, спасибо, только одно замечание - если дословный перевод получается бредом, то можно смело высказать мысль своими словами.
RE:"Замечание: Опция magic_quotes_gpc влияет на выходящее значение ф-ии, т.к. parse_str() использует тот же механизм, что пхп использует для заполнения $_GET, $_POST."
2Helios:
RE:"Сколько двигов перерыл, но что-то эту функцию видел в применении всего несколько раз. Так что особой "опасности" и чего-то сверхестественного тут не вижу." - оттого что ты не нашел применение данной уязвимости, опасность и актуальность данной баги не уменьшается
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|