Pull to refresh

Выполнение кода в PHP 5.3.9

Reading time2 min
Views7.8K
Одним из новшеств релиза PHP 5.3.9 стало введение нового параметра конфигурации max_input_vars, который устанавливает максимальное возможное количество входящих параметров в запросе. Новая директива является мерой против атак Hash Collision DoS, которые могут привести к отказу в обслуживании при отправке большого количества входящих параметров. Однако в коде, отвечающим за ограничение количества параметров в запросе, была допущена ошибка, которая приводит к удаленному выполнению кода. Уязвимость была обнаружена специалистом в области информационной безопасности Стефаном Эссером, известным за публикацию ряда серьезных уязвимостей в PHP, а также за разработку джейлбрейка для Apple iOS.

Уязвимость возникает в случае, когда количество входящих параметров превышает значение max_input_vars (по умолчанию 1000).


Уязвимая функция php_register_variable_ex (php_variables.c@194):
  1. PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array TSRMLS_DC)
  2. {
  3. /* ... */
  4. if (is_array) {
  5. /* ... */
  6.     while (1) {
  7. /* ... */
  8.         if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
  9.             if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
  10.                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
  11.             }
  12.             MAKE_STD_ZVAL(gpc_element);
  13.             array_init(gpc_element);
  14.             zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
  15.         }
  16.     }
  17.         /* ... */
  18.         symtable1 = Z_ARRVAL_PP(gpc_element_p);
  19. /* ... */

Ограничение количества параметров реализовано циклом с условием if, причем отсутствует блок else, который должен был бы останавливать проход цикла. В следствие этого, на выходе из цикла в макрос Z_ARRVAL_PP (строка 18), который возвращает ссылку на обновленную hash-таблицу, попадет gpc_element_p со значением последней обработанной в цикле переменной, что ведет к выполнению кода.

Уязвимости не подвержены сервера с установленным расширением Suhosin patch, автором которого является Стефан Эссер. Примечательно, что накануне linux-дистрибутив Debian отказался от Suhosin patch, тем самым подвергая своих пользователей новой угрозе. А самое интересное это то, что уязвимость найдена в фиксе другой уязвимости.
Tags:
Hubs:
+32
Comments11

Articles