![]() |
Поиск PHP уязвимостей на примере phpBB
Данная статья рассматривает способы подключения файлов в PHP скриптах, способы проверки данных, передаваемых в функции "include" и "require", возможные случаи передачи данных в эти функции. Так же рассматриваются возможности подключения файлов "сторонних" производителей. В конце рассматривается возможность подключения файла загруженного как аватар. Статья преследует цель показать методику поиска и анализа мест, потенциально уязвимых для PHP-инъекций. Она будет интересна людям, делающим первые шаги на пути поиска и эксплуатирования ошибок в PHP приложениях, давая возможность проследить за ходом поиска уязвимых мест в скриптах, также будет интересна и программистам, показывая на примерах способы проверки данных и выявление неточности в логике построения проверок. Для тестиования выбран форум phpBB 2.0.21, и перед тем как читать дальше я рекомендую установить этот продукт.
Поискав require и include во всех исходниках форума я нашел подключения различных файлов. Много подключений однотипных, например подключается файл так "$phpbb_root_path . 'includes/functions_validate.'.$phpEx", т.е. указание на директорию, которая в зависимости от расположения подключающего файла меняется, затем точное указание на файл, добавление к нему расширения. Скорее всего $phpbb_root_path создана для удобной возможности перемещения файла из одного каталога в другой, и изменение этой переменной позволит легко переопределить пути подключения файла. Изменение этой переменной привело бы к возможности удаленного инклюда. $phpEx определяет расширение PHP скриптов, связано это с тем, что WWW сервис определяет PHP скрипт по его расширению. На некоторых серверах возможны такие варианты как "php3","php5","phtml". Итак, что же сделано для того чтобы никто не смог переписать эти переменные? В файлах, где переменная "$phpbb_root_path"и "$phpEx" не задается явно, стоит проверка определена ли константа IN_PHPBB, если нет, то скрипт умирает сообщая "Hacking attempt". В файлах, где определяется эта константа, в самом начале определяются и эти две переменные $phpbb_root_path и $phpEx. Изменить эти переменные можно только если register_globals включен (по умолчанию он выключен), и программист забыл поставить проверку константы. Архитектурно неверно использовать подобные приемы, лучше всего жестко определять пути для подключаемых файлов, либо для определения пути использовать константы. Так же лучше всего определить фиксированное расширение для подключаемых файлов и выделить для них отдельный каталог, закрытый, например, с помощью .htaccess, от передачи оттуда файлов . Хотя такие решения с переменными дают возможность использовать данное приложение на различных WWW сервисах. Из друг на друга похожих икнлюдов выделяются и интересуют нас следующие: в файле admin/admin_styles.php PHP код:
PHP код:
PHP код:
Стоит добавить проверки, которые поставлены в рассматриваемом далее инклюде, он так же находится в этом файле PHP код:
PHP код:
В исходнике admin/index.php был найден такой инклюд "include('./' . $file);". Выглядит инклюд очень заманчиво, но передать в него любые данные не получится, поскольку в $file, передаются имена файлов и каталогов из "admin/". А затем происходит проверка preg_match("/^admin_.*?\." . $phpEx . "$/", $file). Рассмотри алгоритм проверки: первым проверяется наличие в начале строки admin_, дальше может идти любое значение, заканчиваться строка должна .php. Действительно, "^" означает начало строки в которой осуществляется поиск и за началом следует "admin_", отсутсвие утверждения о начале, приведет к тому, что "admin_" сможет находится везде, что приведет к подключению файла с именем "mySTRING_admin_.php". "$" утверждает об окончании строки (или множества строк). На конце строки должен находится php. Без данного утверждения preg_match возвращал бы true даже в том случае, если имя файла было бы "admin_.php.mySTRING" . В принципе, существование директории "admin_.php" вызовет ошибку в работе скрипта. Можно было бы, добавить проверку на не директорию и не ссылку. Так как единственная возможность выполнить include с вредоносным кодом это записать этот файл в директорию "phpBB2/admin", то я думаю следует ограничить эту директорию правами только чтение и запуск. Так же в "faq.php" замечен интересный инклюд PHP код:
В common.php так определяется $board_config: PHP код:
То есть, если существует возможность SQL инъекции, то нападающий сможет изменить значение в таблице, тем самым установив значение $board_config['default_lang'], например, на файл аватара. Скрипт faq.php обламывает такие попытки функцией init_userprefs (includes/functions.php). В этой фунции есть проверка basename'ом. В связи с тем, что basename отсечет все попытки прорваться в другие каталоги с помощью конструкций вида /../../, то можно указать на файл находящийся в language и начинающийся lang_ и заканчивающийся "\x0". Как говорилось выше в функции init_userprefs происходит вызов basename($board_config['default_lang']), затем полученный результат передается в $default_lang, проверяется наличие файла для инклюда, если файл не существует, то $default_lang становится равным "english". А перед вызовом include, $board_config['default_lang'] приравнивается $default_lang. В функции setup_style есть вот такое подключение файла PHP код:
PHP код:
Инзменив таким образом $template_name мы получаем возможность загрузить вместо стиля по умолчанию наш скрипт, загруженный как аватар. Данная уязвимость работает (скорее всего) на всех версиях phpBB2 (я проверил на последней 2.0.21 и 2.0.10). Внеся такие изменения попробуйте теперь загрузить главную страницу и вы получите запуск "shell.jpg". Осталась функция message_die PHP код:
И это уже задача, твоя, читатель - jonny - Цитата:
|
http://forum.milw0rm.com/showthread.php?t=471
в тему |
| Время: 02:11 |