Введение Добрый вечер. Многие сталкивались с perl скриптами. кому-то это было нужно для системных нужд. каким-нить скрипткидисам запустить очередной сплойт, не поняв как он работает. Ну а кто-то занимается cgi программированием. Конечно это не так популярно, как PHP но все же иногда очень незаменимо, именно для этих людей я пишу данную статью. В ней будет рассказано о двух возможных ошибках, которые вполне могут помочь взломщику повысить свои права в системе, а также о защите. Поехали. Некая особенность Если все хорошо настроено, то все приложения CGI выполняются под юзером права которого в системе очень небольшие, но к сожалению(а может и счастью), если удается добиться выполнения системных команд, то во многих случаях, есть возможность эти права повысить. Поэтому к безопасности CGI приложений нужно отнести очень серьезно. Ошибка # 1 Опасная работа с файлами. Вообще по сути как в perl так и В php, многие операции с файлами вызывают какую-то долю риска. Я накалякал простенький бажный скрипт. Code: #!/usr/bin/perl use CGI qw(:standard); $file=param(load); print "Content-Type: text/html\n\n"; open(F,$file); while(<F>) { print } close(F); __ Проанализируем: 1 строчка - путь к интерпретатору. 2 строчка-подключаем необходимую библиотеку. 3 строчка - присваиваем значение переменной $file параметра load . 4 строчка выводим заголовок Content-Type 5 строчка открываем файл какой именно указывет переменная $file 6 строчка загоняем в цикл и выводим построчно 7 закрываем файл __ Т.е Передать значение $file можно прямо из браузера. Code: http://site.ru/script.pl?load=file Не трудно догадаться, что если мы передадим переменной $file значение к примеру ../../../../../../../etc/passwd, скрипт нам выдаст его содержимое. Ну тут ясно в чем ошибка, хочу обратить внимание на ещё один трюк, который мы можем проделать с этой ошибкой. Волшебный символ '|' разберемся, что он делает. Он заставляет наш скрипт, который открывает файл по-просту выполнить его. то есть если $file примет значение |ls , то в итоге нам будет выведен результат выполнения команды ls. С виду казалось, что ничего страшного в этом нет, а на самом-то деле все совсем иначе. Подходить к безопасности cgi надо очень серьезно способы защиты Первый способ универсальный способ, а именно фильтровать ненужные символы например Code: #!/usr/bin/perl use CGI qw(:standard); print "Content-Typ: text/html\n\n"; $file=param(load); $file =~ s/([|])/\\$1/g; open(F,$file); while(<F>) { print } close(F); мы добавили фильтр Code: $file =~ s/([|])/\\$1/g; на '|' и теперь трюк с выполнением команд не прокатит. Однако читать файлы это не помешает нужны более жесткие фильтры типа Code: $file =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g; вот теперь уже далеко с чтением не уйти. А вообще у меня в мыслях более интересный подход к ситуации а именно Code: #!/usr/bin/perl use CGI qw(:standard); print "Content-Typ: text/html\n\n"; $file=param(load); if ($file eq file1) { open(F,"файл, который вы хотите загрузить"); while(<F>) { print } close(F); } if ($file eq file2) { open(F,"другой файл который вы хотите загрузить"); while(<F>) { print } close(F); } else { print"файл не прочтен"; } Думаю тут все ясно, идет отбор по условию, если запрашиваемая строчка не подходит ни к одному условию, мы заставляем скрипт ругаться то есть что-то print'ить. Единственный минус может всплыть, когда условий очень много. А так больше добавить нечего. На этом с первой ошибкой закончу. Подопытный скрипт слишком упрощен, чаще встречаются более сложные версии подобных скриптов и это вполне логично. Однако, если скрипт более наворочен-это не значит, что он является безопасным, и там вполне может быть допущена подобная ошибка. Ещё раз повторю, глаза на это лучше не закрывать. Ошибка # 2 Sendmail. Просто отправка писем. Кажется, что безобидно, на самом деле все иначе. Вот пример бажного скрипта Code: #!/usr/bin/perl use CGI qw(:standard); print "Content-Type: text/html\n\n"; $query = new CGI; $prog='| /usr/sbin/sendmail'; $address= $query->param('mail'); $from='hackme@localhost'; open (MAIL,"$prog $address"); print MAIL "From: $from\nSubject: YO!\n\n"; print MAIL "; )\n"; close MAIL; Проанализируем Думаю, что вы поняли суть работы скрипта. Для удобства иногда создают удобную формочку для отправки данных на скрипт, но это не важно. что будет, если мы присвоим $adrdess Значение |ls| ? | - заставит выполнится нашу команду, и результат ее выполнения будет нам выдан самым явным образом . Кроме того, хочу обратить внимание, передаваться пользователем может не только адрес почтового ящика, а все что угодно. способы защиты Очевидно, что в данном случае можно также использовать фильтр, только на этот раз мы действуем с почтой, и тут надо быть внимательнее, так как в адресе почты используются некоторые символы, которые фильтровать просто недопустимо. Фильтровать, но с умом. Например символ @ (Собачк0) лучше оставить в покое. Хотя не совсем можно намутить некоторый шаблон. типа 'одно значение'@'другое значение', то есть передавать не одно значение ака почтовый адрес целиком. а два то есть имя почтового ящика и домайн. Дополнения Если удается обнаружить бажный Perl скрипт, частенько не удается залить шелл чисто потому, что не работают программы, которые нам бы помогли залить шелл. Встречается часто. Но этих программ придуманно много. -wget -fetch -lynx -links -get -curl При помощи which можно посмотреть, какие установлены, обычно такие все-таки находятся. Просто часто отключают Wget. $IFS-пробел,табуляция,перевод строки - можно использовать вместо пробела, когда стандартный пробел не канает.
продолжение Итак после того, как мы разобрались с ошибками характерных для perl, перейдем к следующему виду ошибок, которые касаются не только cgi, но и остальных приложений, например php Ошибка # 3 межсайтовый скриптинг Вы думали не актуально? ага щас... В perl подобное тоже присутствует. В чем же все заключается? Да все просто, эта ошибка начинается сразу после того, как мы ввели print "Content-Type: text/html\n\n"; Теперь и Script тоже будет выполняться, и если программист разрешил пользователю скрипта присваивать значения некоторым переменным, которые в итоге выводятся в контенте страницы, причем без всяких ограничений, то это выливается в XSS рассмотрим наипростейший скрипт. Code: #!/usr/bin/perl use CGI qw(:standard); $parametr=param(load); print "Content-Type: text/html\n\n"; print "$parametr"; в последней строчке, мы просто выводим переменную, которую может определить пользователь, а ему ничто не мешает в качестве параметра передать. Code: www.site/cgi-bin/script.pl?load=<script>alert('xak')</script> То есть присвоить $parametr злое значение, которое в итоге выводится и выскакивает алертом. Многие программисты используют вывод в контент. Обычно можно наблюдать в полях поиска и в других ситуациях, когда нужна некая определенность. Защита Если уж сильно приспичило, выводите на здоровье, но поставьте хоть банальный фильтр на ненужные символы. Code: #!/usr/bin/perl use CGI qw(:standard); $parametr=param(load); print "Content-Type: text/html\n\n"; $parametr =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"\n])/\\$1/g; print "$parametr"; Такой код очень попортит затеи хакера, если попытаться присвоить нашей переменной то же самое значение Code: www.site/cgi-bin/script.pl?load=<script>alert('xak')</script> то фильтр хорошенько попортит скрипт и в результате выдастся что-то вроде. Code: \<script\>alert\(\'xak\'\)\</script\> Такое чучело конечно же не подлежит выполнению. Ошибка # 4 неаккуратное использование команды system() Известны такие скрипты, которые используют для работы сие чудо. Эта функция несет самую, что есть прямую опасность. Code: #!/usr/bin/perl use CGI qw(:standard); $parametr=param(load); print "Content-Type: text/html\n\n"; system($parametr); Опять же простенький скрипт. И если передать параметру Load передать значение id который потом присвоится переменной $parametr. В результате мы будем наблюдать. Результат выполнения этой команды. Что не есть хорошо. Скрипты испольщующие эту функцию иногда встречаются, не так часто как вышеперчисленный, но встречаются. Как защитить? Выход всегда есть. Самое главное давать system'у только свои значения, нельзя, чтобы они как-то передавались пользователем скрипта. Code: #!/usr/bin/perl use CGI qw(:standard); $parametr=param(load); print "Content-Type: text/html\n\n"; if ($parametr eq com1) { system("ваша команда"); } if ($parametr eq com2) { system("другая ваша команда"); } else { print"error"; } вроде как ничего сложного, а обезопасить подобные скрипты всегда стоит. Ошибка # 5 sql injection И в perl есть модули для работы с базами данных. На этом особо внимание зациклиать не буду, так как проведение sql inj, и защита в perl. Мало чем отличается от этого например в php. Google Сайтов-жертв найти можно ООЧЕНь большое количество. Можно использовать для этих целей гугл например: Code: inurl:"/cgi/bin/index.cgi?file=" inurl:"/cgi/bin/index.pl?id=" B тому подобные запросы. Уязвимых скриптов хватает. Заключение Вот и все, что я хотел на данный момент рассказать, если есть дополнения или ошибки, жду комментариев, чтоб поправить или дополнить. На этом все, спасибо за прочтение. (С)ImpLex
статья чисто моя. Писалась с нуля ... И использованы чисто мои знания. + статья не закончена. Ещё будет несколько пунктов А вообще, если сомнения терзают, найди такую же статью в интернете с более ранней датой публикации, тогда и говори, что я ее стырил, а если сомнения терзают, тогда лучше бы не оффтопил в моей теме
на qwerty.nanko.ws такое было, вгоду эдак 2000-2001..... перловые цги баги не актуальны! борода дремучая! в 8-м или 9-м выпуске defaced zine была статья с интересными финтами :Р вот там да!... а тут, автор звиняй. но ничего нового %\ пс: а вообще напомнинает сборную солянку из древних паперов rst, kodsweb
Конечно, это правда, cgi баги-Довольно старая тема... Ну как же они не актуальны? Раз присутствуют на ресурсах интернета cgi, скрипты, значит, вполне ещё актуальная тема, что старо - ещё не значит, что неактуально Вот теперь статья дописана. Может тема и избита... Но достойного нормальных факов на античате я не находил... Да в интернете мало нормального материала