天天看點

dedeCMS /data/mysql_error_trace.php DB error rais

dedeCMS /data/mysql_error_trace.php DB error raised PHP Code Injection Via /include/dedesql.class.php Log FIle Without Access Validation

目錄

1. 漏洞描述
2. 漏洞觸發條件
3. 漏洞影響範圍
4. 漏洞代碼分析
5. 防禦方法
6. 攻防思考      

1. 漏洞描述

dedecms采用面向對象封裝的方式實作了功能操作的子產品集中化,例如對于資料庫管理

1. /include/dedesql.class.php: mysql資料庫操作
2. /include/dedesqli.class.php: mysqli資料庫操作      

當發生資料庫操作語句執行錯誤的時候,架構代碼會集中對錯誤相關資訊進行收集,并儲存到一個指定的檔案中(/data/mysql_error_trace.php),但是這裡存在一個安全上的漏洞

1. MySQL字段數值采用了C語言同樣的定義,當傳入的數值大于字段定義的類型的時候,将引發整型上溢出錯誤

2. /data/mysql_error_trace.php沒有進行正确的通路認證
/*
security practice
在不需要被通路的日志檔案頭應該加上以下代碼
die('Request Error!');
or
exit();
*/

3. 日志檔案最好使用例如".txt"的文本檔案進行儲存      

真正導緻漏洞的原因是資料庫處理庫(/include/dedesql.class.php),而觸發這個漏洞的檔案有很多,攻擊向量路徑很多,理論上隻要調用了如下代碼即存在漏洞

/*
$dsql->ExecuteNoneQuery("Update `$maintable` set scores = scores + {$cfg_caicai_add},goodpost=goodpost+1,lastpost=".time()." where id=$id");
*/      

目前已知的可以成為攻擊向量的檔案有

1. /plus/digg_frame.php
2. /plus/digg_ajax.php
3. /plus/comments_frame.php      

Relevant Link:

http://icarusli.iteye.com/blog/610715
http://www.007hack.com/?p=522      

2. 漏洞觸發條件

3. 漏洞影響範圍

1. < dede 5.7      

4. 漏洞代碼分析

/include/dedesql.class.php

//顯示資料連結錯誤資訊
function DisplayError($msg)
{
    $errorTrackFile = dirname(__FILE__).'/../data/mysql_error_trace.inc';
    //這裡将日志檔案的字尾改為了.inc,是一個好的防禦方法
    if( file_exists(dirname(__FILE__).'/../data/mysql_error_trace.php') )
    {
        @unlink(dirname(__FILE__).'/../data/mysql_error_trace.php');
    }
    $emsg = '';
    $emsg .= "<div><h3>DedeCMS Error Warning!</h3>\r\n";
    $emsg .= "<div><a href='http://bbs.dedecms.com' target='_blank' style='color:red'>Technical Support: http://bbs.dedecms.com</a></div>";
    $emsg .= "<div style='line-helght:160%;font-size:14px;color:green'>\r\n";
    $emsg .= "<div style='color:blue'><br />Error page: <font color='red'>".$this->GetCurUrl()."</font></div>\r\n";
    $emsg .= "<div>Error infos: {$msg}</div>\r\n";
    $emsg .= "<br /></div></div>\r\n";

    echo $emsg;

    $savemsg = 'Page: '.$this->GetCurUrl()."\r\nError: ".$msg;
    //儲存MySql錯誤日志
    $fp = @fopen($errorTrackFile, 'a');
    //直接将錯誤資訊寫入了可執行的.PHP檔案中
    @fwrite($fp, '<'.'?php'."\r\n/*\r\n{$savemsg}\r\n*/\r\n?".">\r\n");
    @fclose($fp);
}      

5. 防禦方法

//顯示資料連結錯誤資訊
    function DisplayError($msg)
    {
        $errorTrackFile = dirname(__FILE__).'/../data/mysql_error_trace.inc';
        if( file_exists(dirname(__FILE__).'/../data/mysql_error_trace.php') )
        {
            @unlink(dirname(__FILE__).'/../data/mysql_error_trace.php');
        }
        $emsg = '';
        $emsg .= "<div><h3>DedeCMS Error Warning!</h3>\r\n";
        $emsg .= "<div><a href='http://bbs.dedecms.com' target='_blank' style='color:red'>Technical Support: http://bbs.dedecms.com</a></div>";
        $emsg .= "<div style='line-helght:160%;font-size:14px;color:green'>\r\n";
        $emsg .= "<div style='color:blue'><br />Error page: <font color='red'>".$this->GetCurUrl()."</font></div>\r\n";
        $emsg .= "<div>Error infos: {$msg}</div>\r\n";
        $emsg .= "<br /></div></div>\r\n";
        
        echo $emsg;
        
        $savemsg = 'Page: '.$this->GetCurUrl()."\r\nError: ".$msg."\r\nTime".date('Y-m-d H:i:s');
        //儲存MySql錯誤日志
        $fp = @fopen($errorTrackFile, 'a');
        @fwrite($fp, '<'.'?php' . "\r\n" . "die('Request Error!');" . "\r\n/*\r\n{$savemsg}\r\n*/\r\n?".">\r\n");
        @fclose($fp);
    }      

6. 攻防思考

Copyright (c) 2014 LittleHann All rights reserved