В течении года я занимался разработкой системы автоматического поиска уязвимостей в PHP коде. Она анализирует исходный код и строит отчет о найденных уязвимостях. С тестовыми примерами система справлялась достойно, умела находить практически любые XSS, SQL PHP инъекции, сообщала функции и переменные порождавшие их. Перейдя на полномасштабное тестирование анализатора стало интересным провести тестирование известных открытых движков CMS, форумов, интернет магазинов, поискать уязвимости в них. И практически сразу появились очень интересные результаты. Не дожидаясь окончания тестирования всех запланированных движков, решил подготовить обзор того что уже было исследовано.
За последнюю неделю было протестировано 5 CMS и один движок интернет магазина. А это в сумме это больше 300 000 строк кода. Тестирование сайтов проводилось следующим образом. Устанавливался сайт локально, и проводилась его настройка до рабочего состояния. После чего сайт прогонялся анализатором. И последним действием был просмотр отчета анализатора и ручная проверка всех тех мест, которые он обнаруживал.
Было увлекательно замечать как анализатор на больших проектах после 20 минут работы отваливался, из-за каких то хитрых конструкций языка, которые он неправильно понимал. После поправки анализатора, проходило те же 20 минут и он отваливался, но уже в другом месте. Этот этап отладки, очень помог, сейчас в большинстве случаев анализатор уже пережил свой детский возраст и без каких либо неожиданностей может протестировать довольно объемный сайт от и до, пройдясь по каждой строчке кода.
Результаты
1.Первая из протестированных CMS (повезло так повезло) оказалась самой уязвимой. Во первых она содержит добротную кучку уязвимостей в админпанели, которыми может воспользоваться админ сайта (да, админ сайта это еще не админ сервера или хостинга). Но самое интересное, это уязвимость в модуле info.
Начнем с менее интересного. Если вы администратор этой CMS но при этом не имеете доступа по ftp - не беда, вы можете создавать/удалять/читать любые файлы с правами пользователя apache.
Координаты:
Скрипт cms/apanel/filebrowser.php; строки 597, 599, 784, 855; операторы mkdir, chmod, fopen, unlink, copy; и переменные $ndir, $file, $gofolder, все они не экранируются.
А вот с модулем info все намного интересней. Уязвимость в параметре pa. Через него можно прочесть абсолютно любой файл на сервере.
Код расчитан на подгрузку шаблона *.tpl, при этом не валидируется исходная строка. Но дополнив строку нуль байтом получаем возможность чтения любых файлов, в том числе и скриптов.
Для примера, читаем хост, название базы, логин и пароль к БД вот такой строчкой:
index.php?dn=info&pa=../../base/danneo.setting.php%00
после чего можно открыть удаленное соединение с базой.
Всего анализатор нашел много много xss и 15 php уязвимостей, но при этом все они кроме одной относятся к админпанели. В любом случае использовать эту CMS не советую.
2.Уязвимостей как таковых не нашлось, однако если в .htaccess отключить register_globals то возможно открывается пара пасивных xss, о чем мне сообщил анализатор. Почему я написали “возможно”? Просто не взялся изучать код на каких-то экзотических случаях, когда перенастраиваются искусственно конфигурации .htaccess. Если кому интересно могу скинуть отчет анализатора, сами пороетесь.
3.Хоть анализатор и нашел уязвимости в админке, но после ручной проверки они оказались ложными.
4.Ребята этой CMS подошли к вопросу безопасности оригинально. Добавили такую себе заглушку которая вне зависимости от register_globals обнуляет переменные. По сути их код не является чистым и красивым. Например такие конструкции там повсюду:
if($query == <some>)
$query = ...;
mysql_query($query);
5.Всё чисто
6.Тестировался бесплатный вариант Shop Script Free в котором анализатор нашел несколько пассивных XSS на странице входа в админку и странице восстановления пароля(которая в бесплатной версии скрипта не работает).
Примером будет запрос:
/access_admin.php?errorStr=alert('hello')
Переменная errorStr никак не экранируется и отправив подготовленную ссылку по электронной почте указанной на сайте магазина с большой вероятностью можно увести административные куки авторизации. Валидации по ip там нет.
Заключение
Пока что это всё. Подводя итоги, хочу сказать что в процессе ручного анализа кода часто удивлял подход к его разработке. Процедурное программирование оказывается еще в моде. Наверное процесс переписывания кучи кода не всегда целесообразен. А из технологий чаще всего применяется проапгрейженый велосипед с дудкой. Особенно в этом преуспел довольно популярный osCommerce. Его в обзор не добавил, замечу что уязвимостей в нем не нашлось, но общее впечатление осталось. Ради обратной совместимости в нем применяются дедовские хардкорные заплатки. Например вместо того чтоб отрефакторить код и заменить $https_GET_VARS на $_GET проще ведь написать $https_GET_VARS = &$_GET, или например в хедер добавить:
// check support for register_globals
if (function_exists('ini_get') && (ini_get('register_globals') == false) && (PHP_VERSION < 4.3) ) {
exit('Server Requirement Error: register_globals is disabled in your PHP configuration. This can be enabled in your php.ini configuration file or in the .htaccess file in your catalog directory. Please use PHP 4.3+ if register_globals cannot be enabled on the server.');
}
В целом в популярных движках, код которых открыт и проверяется сообществом сложно что либо найти. На сколько я знаю в компаниях за одну SQL Injection можно лишиться работы. Однако все таки человек не машина и упустить где-то, то же экранирование переменной, можно очень легко. Так что будьте бдительны при написании кода.