ПИШЕМ БАЖНУЮ CGI'ШКУ НА PERL
Спецвыпуск Xakep, номер #022, стр. 022-024-2
Если ты думаешь что таких ошибок нигде не встретить, то ты сильно ошибаешься. Добрая половина бесплатных скриптов, написанных за полчаса, содержит подобные ошибки. Надо просто внимательно смотреть. В некоторых скриптах допускаются еще более грубые ошибки, позволяющие выполнять команды.
Строка, заключенная между обратными кавычкам (``), передается операционной системе для выполнения. Если скрипт не проверяет, что там передается, то мы получаем возможность выполнить любую команду. В нашем скрипте мы передаем параметр $date, который необходим для вставки даты в письмо:
print OUT "Date: " . `/bin/$date` . "\n";
Если в качестве параметра в $date передадим любую другую команду, то она выполнится.
Функция eval() выполняет полученную строку как perl-команду. В некоторых скриптах встречается использование внешней переменной внутри eval. Например:
eval("$gbname");
В параметре $gbname мы можем передать любые perl-команды, и они выполнятся. У нас в гостевой книге такой дыры нету просто потому, что я уже не смог придумать, куда ее вставить :).
ПОСЫЛАЕМ!
В нашей гостевой книге, конечно, не обойтись без отправки комментариев на почту. И, естественно, мы сталкиваемся с очередным багом. На этот раз это связанно со старой, как мир, программой sendmail. Посмотрим наш скрипт:
open(MAIL,"|$mailprog $to -s $subject");
Ты удивишься, но в этой одной строке у нас сразу две ошибки! Смотри, мы запускаем sendamil с параметром $to, который берется из формы и является адресом получателя. Параметр $subject также берется из формы и является темой сообщения.
Теперь, если в теме сообщения написать, скажем, "test;ls -s /", perl выполнит, передаст ОС следующую строку:
sendmail moof@real.xakep.ru -s test;ls -s /
И что? А то, что выполнится команда "ls -s" - и мы получим содержимое каталога. Опять же вместо "ls -s" можно написать любую команду (а нужно ли?).
И второй баг. Он очень похож на первый, и вдвоем они, я думаю, никогда в скриптах не встречаются, а вот поодиночке очень даже часто. Теперь мы вставим выполнение команды вместо адреса $to, например:
moof@real.xakep.ru ls -s > gb.cgi
И опять получим все содержимое каталога себе на мыло.
ЗАКЛЮЧЕНИЕ.
Как видишь, большинство ошибок сделано только из-за лени программиста. Из-за того, что он решил не проверять получаемые значения. Стоило ему вырезать все спецсимволы с кодом 0 из полученных данных, и от первой ошибки мы бы избавились. А вырезать очень просто:
$gbname = ~s/\0//g;
А еще было бы здорово экранировать все спецсимволы, использующиеся в ос unix:
& ; ' ` \ " * ? < > ^ ( ) { } $ \n \r
Кроме того, perl имеет встроенные возможности предупреждения о потенциально опасных конструкциях. Для этого существует специальный механизм меченных данных. Меченные данные это все переменные, которые perl-скрпит получил извне (например, из формы). Perl не будет использовать эти данные, пока они не будут проверены. Для включения безопасного режима достаточно указать ключ -T в заголовке скрипта:
Назад на стр. 022-024-1 Содержание Вперед на стр. 022-024-3
|