Компьютер для продвинутых пользоватлей Выпус по безопасности. Ошибка в PHP.
Компьютер для продвинутых
пользователей
Содержание:
PHP
ПО: PHP
Версия: 4,5
О софте:
PHP это сетевой язык позволяющий разнообразить вашу Web-страницу.
Уязвимость:
При исследовании PHP было найдено более 20 уязвимостей в PHP4 и PHP 5.
Возможно, что эти же уязвимости актуальны и для более поздних версий.
1) Переполнение буфера.
Функция wordwrap() применяется к строкам. Она возвращает символа,
используемого в строка, как символ прерывания. Переполнение буфера
происходит в функции wordwrap() происходит из-за пересчёта
целочисленного значения при посылке в функцию слишком длинных строк. При
определенном размере строки, возможно, переполнить функцию Memcpy().Есть
множество способов провести переполнение, я же опишу один из них.
Целое число 'alloced' высчитывается длинной строки, вводимой
пользователем. Возможно осуществить ввод длинной строки(около 1 МБ), что
позволит вычислить какое-либо число и использовать его в распределении
памяти. Вся строка, введенная пользователем, копируется в созданные
буфер 'newtext', который является слишком коротким и происходит
переполнение буфера в memcpy(). При этом в размере копии 'current' будет
содержать длину строки, введённую пользователем.
Уязвимый код в php-4.4.2/ext/standard/string.c:
--------------------------------------------------------
PHP_FUNCTION(wordwrap)
{
const char *text, *breakchar = "\n";
char *newtext;
int textlen, breakcharlen = 1, newtextlen, alloced, chk;
long current = 0, laststart = 0, lastspace = 0;
long linelength = 75;
zend_bool docut = 0;
...
if (linelength > 0) {
chk = (int)(textlen/linelength + 1);
alloced = textlen + chk * breakcharlen + 1;
} else {
chk = textlen;
alloced = textlen * (breakcharlen + 1) + 1;
}
if (alloced <= 0) {
RETURN_FALSE;
}
newtext = emalloc(alloced);
...
if (laststart != current) {
memcpy(newtext+newtextlen, text+laststart,
current-laststart);
newtextlen += current - laststart;
}
...
}
--------------------------------------------------------
Если значение поля memory_limit высоко, то возможно провести DoS
атаку.
2) DoS атака.
Функция array_fill() заполняет массив 'num' параметрами из поля 'value',
параметром из поля 'start_index'. Возможно установить большое значение
'num', которое полностью заблокирует память на несколько минут, что
приведет к зависанию системы. Это возможно провести только на тех
системах, где значение memory_limit находиться в php.ini.
Уязвимый код php-4.4.2/ext/standard/array.c:
--------------------------------------------------------
PHP_FUNCTION(array_fill)
{
zval **start_key, **num, **val, *newval;
long i;
....
....
....
convert_to_long_ex(num);
i = Z_LVAL_PP(num) - 1;
if (i < 0) {
zend_hash_destroy(Z_ARRVAL_P(return_value));
efree(Z_ARRVAL_P(return_value));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of
elements must be positive");
RETURN_FALSE;
}
3) DoS атака.
Функция substr_compare() используется для двоичного сравнения 2 строк из
'offset' до символов 'length'. По какой-то причине функция имеет прямой
доступ к памяти, что позволяет нам провести DoS атаку.
Уязвимый код php-5.1.2/ext/standard/string.c:
------
PHP_FUNCTION(substr_compare)
{
...
int s1_len, s2_len;
long offset, len=0;
zend_bool cs=0;
...
cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));
...
if (!cs) {
RETURN_LONG(zend_binary_strncmp(s1 + offset, (s1_len -
offset), s2, s2_len, cmp_len));
} else {
RETURN_LONG(zend_binary_strncasecmp(s1 + offset, (s1_len -
offset), s2, s2_len, cmp_len));
}
...
}
------
Использование:
1) wordwrap()
------