Опаньки! Да ведь функция open языка Perl негласно поддерживает конвейер! Вместо открытия файла происходит его запуск! Вряд ли стоит объяснять, какие последствия вытекают из этого! Так, одна из версий SendMail позволяла в качестве обратного адреса отправителя письма подставить строчку “|/usr/bin/sh” и оболочка действительно запускалась, предоставив атакующему привилегированный доступ в систему (от имени демона).

Огромное количество защит оказалось взломано именно «благодаря» поддержке конвейера, позволяющего выполнять на удаленной машине любой код [95]. Аналогично перенаправлению ввода-вывода, конвейерные дырки могут быть обнаружены не только тщательным изучением исходных тестов приложений, но и простой подстановкой знака “|” во все доступные строки ввода и поля заголовков. Не так уж и редко это срабатывает.

Важно отметить, подобной «вкусности» подвержена не только операционная система UNIX, но и множество других, в частности Windows 9x/Windows NT. Убедиться в этом поможет приведенный выше код “pipe.hack.pl”. Достаточно запустить его на платформе Windows и ввести следующую команду:

· dir |· Том в устройстве F не имеет метки· Серийный номер тома: 2F42-0AE8· Содержимое папки F:\TPNA\src·. «ПАПКА» 28.06.00 23:14.·… «ПАПКА» 28.06.00 23:14…· IO C 294 06.07.00 10:29 io.c· IO OBJ 775 06.07.00 10:18 io.obj· IO EXE 32 768 06.07.00 10:18 io.exe· IOSTD C 228 06.07.00 10:30 iostd.c· IOSTD OBJ 627 06.07.00 10:26 iostd.obj· IOSTD EXE 32 768 06.07.00 10:26 iostd.exe· MYFILE 16 06.07.00 10:53 myfile· OUT TXT 89 06.07.00 10:53 out.txt· IOHACK C 295 06.07.00 15:18 iohack.c· IOHACK OBJ 827 06.07.00 14:58 iohack.obj· IOHACK EXE 32 768 06.07.00 14:58 iohack.exe· PIPEHA~1 PL 65 06.07.00 22:29 pipe.hack.pl· 12 файлов 101 520 байт· 2 папок 1 710 641 152 байт свободно

Методы противодействия и защиты от подобных ошибок будут описаны в главе «Атака на WEB-сервер», а ниже будет объяснено почему символ конвейера появляется то слева от команды (как в примере с “|/usr/bin/sh”), то справа (“dir |”). Вообще-то «классический» конвейер состоит минимум из двух программ, и вывод первой из них попадает на ввод второй. То есть конструкцию “program 1 | program 2” можно изобразить как “stdin ® program 1 ® program 2® stdout”. А в случае, когда используется всего лишь одна программа, вывод программы, стоящей до символа конвейера, перенаправляется в открываемый функцией “open” манипулятор, а вывод программы, стоящей за символом конвейера, никуда не перенаправляется и идет прямиком на терминал.

Сказанное позволяет продемонстрировать приведенный ниже код (на диске, прилагаемом к книге, он находится в файле “/SRC/pipe.test.pl”):

· open(FH,«»);· if (FH)· {· while( $x=«FH» )· {· print “Этот текст прочитан из файла:$x” ;·}·}

Строка «Этот текст прочитан из файла», предваряющая переменную $x, позволит отличить символы, получаемые чтением из файла, от текста непосредственно выводимого программой на экран.

· echo Hello, Sailor |

· Этот текст прочитан из файла:Hello, Sailor

· |echo Hello, Sailor!

· Hello, Sailor!

В первом случае, когда команда “echo” стоит до символа конвейера, результат ее работы направляется в открываемый функцией open манипулятор, откуда он может читается оператором “«»” и выводится на экран вызовом “printf”.

В другом случае, когда команда “echo” стоит после символа конвейера, результат ее работы направляется в стандартное устройство вывода, и минует оператор “print”.

И так-то славно дело пошло! Я сижу на мачте верхом, кручу бочку одной рукой, другой снимаю с конвейера готовую продукцию, передаю Фуксу, тот Лому, а Лом считает, записывает и выпускает на берег. Часа за три весь остров заселили.

Александр Некрасов
Удаленное выполнение программ (глава для начинающих)

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

O История возникновения telnet

O Устройство telnet-сервера

O Настойка telnet-клиента

O Вход в удаленную систему

Перейти на страницу:

Похожие книги