国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

深入分析sugarcrm php代碼注入

2024-05-04 21:50:23
字體:
來源:轉載
供稿:網友

這篇文章準備通過通過請求語句來看傳入的數據在代碼中流向,這樣或許更方便來理解這個漏洞。

http://[host]/[sugar]/index.php?module=Connectors&action=RunTest&source_id=ext_rest_insideview&ext_rest_insideview_[%27.phpinfo().%27]=1

最后的效果就是程序會執行phpinfo()函數。

流程分析

入口函數action_RunTest()

當訪問POC時,程序會進入到modules/Connectors/controller.php中的action_RunTest()函數中。

其中的source_id就是PoC中傳入的ext_rest_insideview,至于為什么會傳入這個,之后的分析會講到。

SourceFactory::getSource()

跟蹤SourceFactory::getSource()函數,進入include/connectors/sources/SourceFactory.php

發現在其中調用了ConnectorFactory::load()方法,其中的$class就是傳入的ext_rest_insideview

load()

跟蹤ConnectorFactory::load()函數,進入include/connectors/ConnectorFactory.php。發現load()函數又調用loadClass()函數。

在loadClass()函數中,會嘗試導入一個文件,導入的格式就是.../connectors/{$type}/{$dir}/$file。其中$type是傳入的sources,$dir是將$class(在本PoC中為ext_rest_insideview)字符串中的_替換為/的一個路徑,所以最后$dir的值為ext/rest/insideview,這個在圖片上也有顯示,$file就是路徑的最后一個值insideview.php。最后程序就會嘗試去尋找對應的文件,如果沒有找到就會報錯。

所以Poc中的source_id=ext_rest_insideview并不能隨便寫為任意值。假若寫為source_id=a_b_c,那么在執行loadClass()的時候無法找到文件導致程序無法往下執行,那么payload就無用了。

setsetProperties()

在對loadClass()分析完畢之后,最后回到入口函數action_RunTest()。

程序往下執行進入到setProperties()方法中。

其中的foreach()就會對傳入值賦值到$properties中,最后得到的$properties的值如左邊的圖所示,即為

[''][''.phpinfo().''] = '1';。

跟蹤setProperties(),進入include/connectors/sources/default/source.php,setProperties()代碼如下:

  1. public function setProperties($properties=array()) 
  2.     if(!emptyempty($this->_config) && isset($this->_config['properties'])) { 
  3.        $this->_config['properties'] = $properties
  4.        $this->config_decrypted = true; // Don't decrypt external configs 
  5.     } 

那么最后,得到在config中得到就是:

  1. $config['properties'][''][''.phpinfo().''] = '1'
  2. saveConfig() 

對setProperties()分析完畢之后,回到入口函數action_RunTest()。

程序繼續往下執行,進入到saveConfig()中。

其中關鍵的地方就在于將變量$this_config中的鍵值對,調用override_value_to_string_recursive2()函數變為一個字符串。

override_value_to_string_recursive2()

跟蹤override_value_to_string_recursive2(),進入到include/utils/array_utils.php中。

  1. function override_value_to_string_recursive2($array_name$value_name$value$save_empty = true) { 
  2.  if (is_array($value)) { 
  3.   $str = ''
  4.   $newArrayName = $array_name . "['$value_name']"
  5.   foreach($value as $key=>$val) { 
  6.    $str.= override_value_to_string_recursive2($newArrayName$key$val$save_empty); 
  7.   } 
  8.   return $str
  9.  } else { 
  10.   if(!$save_empty && emptyempty($value)){ 
  11.    return
  12.   }else
  13.    return "/$$array_name" . "['$value_name'] = " . var_export($value, true) . ";/n"
  14.   } 
  15.  } 

可以看到這就是一個普通的將一個數組類型的變量轉化為一個字符串,最后$this_conifg變為:

  1. /***CONNECTOR SOURCE***/ 
  2. $config['name'] = 'InsideView©'
  3. $config['order'] = 65; 
  4. $config['properties'][''][''.phpinfo().''] = '1'

這個賦值給變量$config_str

PoC執行

回到saveConfig()函數中,程序最后執行

file_put_contents("custom/modules/Connectors/connectors/sources/{$dir}/config.php", $config_str);

其中的$dir為ext/rest/insideview,那么最后程序就會在custom/modules/Connectors/connectors/sources/ext/rest/insideview/config.php寫入$config_str的值,最后就會觸發其中的phpinfo()函數,導致代碼執行。

最后在config.php中寫入的代碼是:

  1. $config = array ( 
  2.   'name' => 'InsideView©'
  3.   'order' => 65, 
  4.   'properties' => array ( 
  5.       ), 
  6. ); 

自此漏洞就分析完畢了。

修復

修復方法很簡單,在override_value_to_string_recursive2()函數中進行修復:

  1. function override_value_to_string_recursive2($array_name$value_name$value$save_empty = true) { 
  2.     $quoted_vname = var_export($value_name, true); 
  3.  if (is_array($value)) { 
  4.   $str = ''
  5.         $newArrayName = $array_name . "[$quoted_vname]"
  6.   foreach($value as $key=>$val) { 
  7.    $str.= override_value_to_string_recursive2($newArrayName$key$val$save_empty); 
  8.   } 
  9.   return $str
  10.  } else { 
  11.   if(!$save_empty && emptyempty($value)){ 
  12.    return
  13.   }else
  14.             return "/$$array_name" . "[$quoted_vname] = " . var_export($value, true) . ";/n"
  15.   } 
  16.  } 

修復的代碼就是使用了var_export()函數對$value_name變量進行了字符串的表示。這樣寫之后,最終得到$config_str的值是:

  1. /***CONNECTOR SOURCE***/ 
  2. $config['name'] = 'InsideView©'
  3. $config['order'] = 65; 
  4. $config['properties']['']['/'.phpinfo()./''] = '1'

上面的代碼就可以正常地寫入到文件中,不會觸發代碼執行了。

總結:

通過分步調試的方法,能夠對這個漏洞理解得更加的透徹,通過這個漏洞也增加了自己調試漏洞的能力。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江津市| 安阳县| 东宁县| 马关县| 盐城市| 大连市| 合江县| 呼伦贝尔市| 兴海县| 永修县| 平定县| 平阴县| 昌乐县| 临邑县| 梅州市| 石狮市| 通辽市| 城步| 临清市| 潼南县| 泾源县| 五指山市| 博乐市| 新乡市| 色达县| 建阳市| 会东县| 年辖:市辖区| 清丰县| 清流县| 宾川县| 防城港市| 昌吉市| 益阳市| 洪洞县| 革吉县| 来凤县| 佛坪县| 英吉沙县| 行唐县| 电白县|