Техника сетевых атак
Шрифт:
Но все безоблачно лишь на первый взгляд. В UNIX есть два типа процессов - наследующие права пользователя и исполняющиеся от имени системы. Примером последних может служить почтовый демон SendMail, обычно исполняющийся с наивысшими привилегиями. Ранние версии поддерживали перенаправление ввода-вывода и позволяли приаттачить к письму любой файл, даже недоступный простому пользователю.
Разумеется, SendMail не одинок, и подобные ошибки допущены во множестве приложений, щедро разбросанных по серверам. Часто для их поиска даже не требуется кропотливого изучения исходных текстов программы - достаточно во всех вводимых строках (или полях заголовка) подставить символ “«” и посмотреть на реакцию программы - нет-нет,
Однако возможности перенаправления ввода-вывода очень ограничены. Рассмотрим это на следующем примере, - пусть требуется получить отсортированный в обратном порядке список файлов текущей директории. Команда ‘ls’ не предоставляет такого сервиса, поэтому придется воспользоваться утилитой ‘sort’ Сперва сохраним результат работы команды ‘ls’ (или dir в MS-DOS) в файле temp. Затем используем его в качестве входного потока данных утилиты ‘sort’, запушенной с ключом ‘-r’ для задания обратного порядка сортировки.
· $ ls»temp
· $ sort -r «temp
· temp
· sioux.pl
· passwd
· iohack.o
· iohack.c
· index_hack.htm
· demos.txt
· bomb.pl
· attack2.htm
Да, это работает, но требует создания лишнего файла на диске и в целом недостаточно удобно. А нельзя ли связать стандартный вывод одной программы со стандартным вводом другой? Можно! И такая конструкция называется конвейер или труба (от английского pipe).
Для создания конвейера необходимо использовать символ “|”, разделяющий запускаемые программы следующим образом: “программа 1 параметры | программа 2 параметры | программа 3 параметры”. Разумеется, стандартный ввод первой программы в цепочке и стандартный вывод последней могут быть перенаправлены с помощью символов “«” и “»” соответственно (результат попытки перенаправления остальных непредсказуем, и обычно разрывает цепочку конвейера).
Интереснее проследить, как происходит взаимодействие процессов и передача данных по конвейеру. Конвейер - сути дела тот же файл, но скрытый от пользователя, построенный по принципу FIFO (от английского First Input First Output – первый пришел - первым и уйдешь). Так, запись в конвейер, из которого никто не читает, рано или поздно вызывает его переполнение (а размер буфера обычно порядка четырех килобайт) и приводит к блокировке процесса-писателя, до тех пор, пока хотя бы один байт из конвейера не будет прочитан. Точно так, попытка чтения из пустого конвейера приводит к остановке процесса-читателя до тех пор, пока в нем не окажется хотя бы один байт.
Схематическое изображения конвейера
Но в любом случае, при обработке конвейера программы поочередно запускаются слева направо, и приведенный выше пример, переписанный с учетом конвейера, может выглядеть так:
· $ ls | sort -r
· sioux.pl
· passwd
· iohack.o
· iohack.c
· index_hack.htm
· demos.txt
· bomb.pl
· attack2.htm
Не правда ли намного проще и элегантнее? Между прочим, конвейеры поддерживаются не исключительно одной UNIX, - не хуже с ними справляется и старушка MS-DOS. Доказывает это эксперимент, приведенный ниже:
· dir /b | sort /r
· sioux.pl
· passwd
· iohack.o
· iohack.c
· index_hack.htm
· demos.txt
· bomb.pl
· attack2.htm
Кажется, в этом нет ничего удивительного, но зададим простой вопрос, - как однозадачная операционная
С первого взгляда в таком подходе ничего дурного нет, но некоторые примеры могут работать некорректно или и вовсе не работать. К таким относится, например, UNIX-утилита “yes”, посылающая на стандартный вывод бесконечный поток символов ‘y’. За кажущейся бесполезностью она часто требуется для пакетного выполнения программ, периодически отвлекающих пользователя запросами на подтверждение выполнения какой-нибудь операции.
В UNIX конвейер полностью заполняется символами ‘y’, и выполнение утилиты “yes” приостанавливается, до тех пор, пока другой процесс не возьмет из конвейера один или несколько символов. Но в MS-DOS два процесса не могут исполняться параллельно, и пока процесс “yes” не закончит выполнение, никакое другое приложение не сможет получить управление, а поскольку выполнение ”yes” не завершиться никогда (программа-то умышленно зациклена) система скинет ласты и впадет в дурной цикл.
Сравнение конвейеров в UNIX и MS-DOS. В MS-DOS конвейер больше похож на «бассейн», чем на «трубопровод»
Поддержка конвейеров - штука замечательная, но только не с точки зрения безопасности. Следующий код доказывает это утверждение (на диске он находится под именем “/SRC/pipe.hack.pl”).
· open(FH,«»);
· if (FH)
· {
· while(«FH»)
· {
· print;
·}
·}
На первый взгляд, программа предназначена для вывода содержимого файла на экран, но ниже показано, что произойдет, если воспользоваться символом конвейера:
· ls|
· sioux.pl
· passwd
· iohack.o
· iohack.c
· index_hack.htm
· demos.txt
· bomb.pl
Опаньки! Да ведь функция open языка Perl негласно поддерживает конвейер! Вместо открытия файла происходит его запуск! Вряд ли стоит объяснять, какие последствия вытекают из этого! Так, одна из версий SendMail позволяла в качестве обратного адреса отправителя письма подставить строчку “|/usr/bin/sh” и оболочка действительно запускалась, предоставив атакующему привилегированный доступ в систему (от имени демона).
Огромное количество защит оказалось взломано именно «благодаря» поддержке конвейера, позволяющего выполнять на удаленной машине любой код [95]. Аналогично перенаправлению ввода-вывода, конвейерные дырки могут быть обнаружены не только тщательным изучением исходных тестов приложений, но и простой подстановкой знака “|” во все доступные строки ввода и поля заголовков. Не так уж и редко это срабатывает.
Важно отметить, подобной «вкусности» подвержена не только операционная система UNIX, но и множество других, в частности Windows 9x/Windows NT. Убедиться в этом поможет приведенный выше код “pipe.hack.pl”. Достаточно запустить его на платформе Windows и ввести следующую команду: