Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Проблемы CGI на Perl.

Проблемы CGI на Perl




div.main {margin-left: 20pt; margin-right: 20pt}
Проблемы CGI на Perl





-------[ Phrack Magazine --- Vol. 9 | Issue 55 --- 09.09.99 --- 07 of 19 ]


-------------------------[ Проблемы CGI на Perl ]


--------[ rain.forest.puppy / [ADM/Wiretrip] ]


----------------[ Введение

Мне кажется, что я должен немного пояснить о чем будет идти речь. По большей
части я сам писал и просматривал различные CGI и пытался разобраться с тем,
как убрать те несколько проблем, которые, по-моему, являются дырками в
системе. На этом я закруглюсь перейду к дыркам.


----------------[ Полуфабрикат

----[ Ядовитый NULL байт

Обратите внимание: название `Poison NULL byte` изначально был использован
Olaf Kirch в письме в Bugtraq. Мне оно понравилось и оно подходит. Поэтому я
его использую. Благодаря Olaf.

Когда "root" != "root", но в тоже время "root" == "root" (уже смущены?)? Когда
вы смешиваете языки программирования.

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

Как вы видите, я пытался открыть конкретный файл, "rfp.db". Я использовал
фальшивый web-сценарий чтобы получить входное значение "rfp" к которому
добавляется ".db" и затем открывается файл. В Perl основная часть скрипта
выглядит примерно так:

# parse $user_input
$database="$user_input.db";
open(FILE "$file");}

Это проскочит и (если на самом деле существует /etc/passwd) откроет его на
запись.

Решение? Очень простое! Удалите нули. В Perl это всего лишь

$insecure_data=~s///g;

ЗАМЕЧЕНИЕ: не заменяйте их набором метасимволов! Полностью удалите их!

----[ Обратный Слэш

Если вы загляните в FAQ по вопросам безопасности на WWW сервере W3C, то
найдете, что рекомендуется следующий список метасимволов:

&;`'"|*?~^()[]{}$nr

Я же нашел весьма интересным, что все, кажется, забыли про обратный слэш (''),
может быть это из-за того, как записывается управляющий код на Perl:

s/([&;`'\|"*?~^()[]{}$nr])/\$1/g;

Со всеми этими обратными слешами, которые комментируют [](){} и т.д. забываешь
о необходимости убедиться, что и обратный слеш здесь так же перечислен (здесь
он '\'), из-за того, что некоторые люди просто не разбираются в регулярных
выражениях и, видя присутствие обратного слеша, думают что он так же
перечислен.

Так, в конце концов, почему же это важно? Представьте, что у вас есть следующая
строка в CGI:

user data `rm -rf /`

И вы прогоняете ее через вашу командную последовательность, которая превращает
ее в

user data `rm -rf /`

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

user data `rm -rf / `

ваш код превращает ее в:

user data \`rm -rf / \`

Двойной обратный слеш будет обращен о одиночный обратный слеш в данных,
оставляя кавычку не закомментированной. Что приведет к успешному выполнению
`rm -rf / `. Конечно, при таком подходе вам всегда приходится иметь дело с
подложным обратным слешем. То, что вы оставите обратный слеш как последний
символ в строке вызовет ошибку при обращении Perl к системному вызову или ошибку
с кавычкой (по крайней мере в предыдущем примере). Вы должны ускользнуть от
этого ;) (это вполне возможно)...

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

s/..//g;

Все, что он делает - удаляет двойные точки, эффективно устраняя обращение к
файлам более высокого уровня, так что

/usr/tmp/../../etc/passwd

превратится в

/usr/tmp///etc/passwd

что не сработает (имейте ввиду - повторные слеши разрешены. Попробуйте 'ls -l
/etc////passwd')

А теперь введем нашего друга - обратный слеш. Давайте дадим следующую строчку:

/usr/tmp/../../etc/passwd

регулярное выражение не совпадет из-за обратного слеша. А теперь смотрите,
как использует такое имя Perl:

$file="/usr/tmp/.\./.\./etc/passwd";
$file=s/..//g;
system("ls -l $file");

Обратите внимание: в примере использован двойной обратный слеш, чтобы Perl
вставил одиночный - иначе Perl будет считать, что вы просто комментируете
точку.
С точки зрения данных строка является /usr/tmp/../../etc/passwd

В тоже время, это работает только на вызове system и вызове с обратной
кавычкой. -e в Perl и open (не-конвейерный) не будут работать:

$file="/usr/tmp/.\./.\./etc/passwd";
open(FILE, ">$bug")
и т.д. и т.п.

не работает. Если вы хотите читать файл, то откройте "i
# Written by Leif M. Wright
# leif@conservatives.net


Лейф заносит данные в %contents и не комментирует метасимволы shell. Затем он
делает следующее:

$output = $basedir . $contents{'file'};
open(RESULTS, ">>$output");

Используя обычный обратный путь в директориях мы можем даже не добавлять NUL.
Но опять де нам необходимо везение с разрешениями на файл, который мы хотим
открыть. И опять же дырка с конвейером не будет работать, поскольку используется
режим добавления к файлу ('>>').

Теперь LWGate, который является WWW-интерфейсом ко многим популярным спискам
рассылки.

# lwgate by David W. Baker, dwb@netspace.org #
# Version 1.16 #

Дэйв помещает разобранные переменные форм в %CGI, затем:

# The mail program we pipe data to
$temp = $CGI{'email'};
$temp =~ s/([;*|`&$!#()[]{}:'"])/\$1/g;
$MAILER = "/usr/sbin/sendmail -t -f$temp"

open(MAIL,"| $MAILER") || &ERROR('Error Mailing Data')

Хм... кажется Дэйв забыл обратный слэш в регулярном выражении. Ай-яй-яй.

Так. Теперь давайте посмотрим на одно из многих приложений - "тележек для
покупок". Опять же с freecode.com, Perlshop.

$PerlShop_version = 3.1;
# A product of ARPAnet Corp. -
perlshop@arpanet.com, www.arpanet.com/perlshop

Интересным является следующее:

open (MAIL, "|$blat_loc - -t $to -s $subject")
|| &err_trap("Can't open $blat_loc!n")

$to это явно определяемый пользователем email. Blad - почтовая программа NT.
Метасимволы в NT это &|% (что-то еще?).

Помните про вредную трубу? (надеюсь, что помните... это всего парой параграфов
выше!). Признаюсь, это не самая удачная ошибка, но это я ее нашел. Давайте
пройдемся далее по архиву скриптов Матта.

# File Download Version 1.0
# Copyright 1996 Matthew M. Wright mattw@worldwidemart.com

Сначала он выбирает данные в $Form (ничего не комментируя). Затем выполняет
следующее:

$Request_File = $BASE_DIR . $Form{'s'} . '/' . $Form{'f'};

if (!(-e $filename)) {
&error('File Does Not Exist');
}
elsif (!(-r $filename)) {
&error('File Permissions Deny Access');
}

open(FILE,"$Request_File");
while () {
print;
}

Это вполне удовлетворяет критериям 'проблемы вредной трубы' (tm). Имеется
проверка '-e', так что мы не можем использовать аргументы командной строки.
Поскольку вначале он приклеивает $BASE_DIR нам придется использовать обратный
путь в директории.

Уверен, что читая выше вы встретились с более простой проблемой. Как насчет
f=../../../../../../etc/passwd? Да, он существует и может быть прочитан. таким
образом вам его должны показать. И покажут. Но с другой стороны: весь доступ к
download.cgi записывается в журнал следующим кодом:

open(LOG,">>$LOG_FILE");
print LOG "$Date|$Form{'s'}|$Form{'c'}|$Form{'f'}n";
close(LOG);

Так что, скрытая камера наблюдает за всем, что вы делаете. Но в любом случае -
не хорошо причинять зло серверам посторонних людей. ;)

Теперь полетаем вместе с BigNoseBird.com. Я имею ввиду:

bnbform.cgi
#(c)1997 BigNoseBird.Com
# Version 2.2 Dec. 26, 1998

Самое интересное происходит после того, как скрипт открывает конвейер
к сендмейлу как MAIL:

if ($fields{'automessage'} ne "")
{
open (AM,"< $fields{'automessage'}");
while ()
{
chop $_;
print MAIL "$_n";
}

Еще одна простая вещь. BNB не делает какого-либо разбора входных переменных
пользователей ($fields), так что мы можем указать любой файл как 'automessage'.
Если он доступен на чтение контексту веб-сервера он будет послан на любой адрес,
который мы укажем (по крайней мере теоретически).


----------------[ А вот и конец

Да, так. К этому времени я слегка устал от разбора программ на Perl. Я оставлю
немножко и вам, в качестве домашнего задания. И если вы что-то найдете -
черкните мне пару строчек - особенно если вы найдете скрипты, где можно
использовать 'проблему вредной трубы'. На этом все. До новых встреч.

.rain.forest.puppy. [ADM/Wiretrip] rfp@wiretrip.net

Greets can be found at http://www.el8.org/~rfp/greets.html

----[ EOF

  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте