YZMCMS V5.3后台 SSRF
當(dāng)改變命運的時刻降臨,猶豫就會敗北。
前言
此前在測試過程中遇到過此CMS,久攻不下,于是便嘗試代碼審計,不得不說這套CMS還是挺安全的,讀起來也簡單,也適合初學(xué)代碼審計的同學(xué)去閱讀,不過漏洞真的不多,本人絞盡腦汁終于算是審計出一個弱雞漏洞。
漏洞分析
漏洞位于 application\collection\controller\collection_content.class.php 中的 collection_test 函數(shù),此函數(shù)為獲取一個網(wǎng)頁中的URL,并獲取此URL的值輸出。類似于爬蟲,爬取網(wǎng)頁中URL對應(yīng)的文章。以下為主要功能函數(shù):
首先查看 get_content()函數(shù):
可以看到傳進來的URL不進過任何檢測規(guī)則就帶入 file_get_content()函數(shù),那么倘若此 $url 為 file:// 偽協(xié)議的話,如此則產(chǎn)生任意文件讀取漏洞。那么此時回頭看 $url的值是否可控。
可以看到,$url 的值來自于 collection_node 表中的 urlpage 字段的值。如果要 $url 可控,那么就要找到一個數(shù)據(jù)庫寫入操作,并且 urlpage 字段的值可控。再看:
此函數(shù)則是將$_POST的數(shù)據(jù)寫入到表中。看 insert 函數(shù)如何寫。
可以看到在寫入過程中經(jīng)過過濾函數(shù) safe_data() :
假設(shè)payload為:file://C:/Windows/System32/drivers/etc/hosts? 可以看到此過濾函數(shù)對此payload并無任何影響,所以導(dǎo)致插入數(shù)據(jù)庫中的urlpage字段的值可控,由此導(dǎo)致$url的值可控。再往下查看 get_sub_content()函數(shù):
可以看到此函數(shù)是將 $html 中的 $start 和 $end 之間的值取出來,而 $start 表示區(qū)間開始的html表示,$end 表示區(qū)間結(jié)束的html標(biāo)識。并且這兩個標(biāo)識不能為空。于是可以構(gòu)造payload為:<test123>file://C:/Windows/System32/drivers/etc/hosts</test123>,如此進過上述函數(shù)則會取出payload并返回。再往下:
進入get_all_url()函數(shù):
1 public static function get_all_url($html, $url_contain='', $url_except='') { 2 3 $html = str_replace(array("\r", "\n"), '', $html); 4 $html = str_replace(array("</a>", "</A>"), "</a>\n", $html); 5 preg_match_all('/<a ([^>]*)>([^\/a>].*)<\/a>/i', $html, $out); 6 $data = array(); 7 foreach ($out[1] as $k=>$v) { 8 if (preg_match('/href=[\'"]?([^\'" ]*)[\'"]?/i', $v, $match_out)) { 9 if ($url_contain) { 10 if (strpos($match_out[1], $url_contain) === false) { 11 continue; 12 } 13 } 14 15 if ($url_except) { 16 if (strpos($match_out[1], $url_except) !== false) { 17 continue; 18 } 19 } 20 $url2 = $match_out[1]; 21 $url2 = self::url_check($url2, self::$url); 22 23 $title = strip_tags($out[2][$k]); 24 25 if(empty($url2) || empty($title)) continue; 26 27 $data['url'][$k] = $url2; 28 $data['title'][$k] = $title; 29 30 } else { 31 continue; 32 } 33 } View Code?
發(fā)現(xiàn)其中有一個正則過濾:?preg_match_all('/<a ([^>]*)>([^\/a>].*)<\/a>/i', $html, $out);?,此正則獲取<a (value)>(value)</a>括號中的值,并將其合并為一個數(shù)組。再往下看,又出現(xiàn)一個正則過濾:?
preg_match('/href=[\'"]?([^\'" ]*)[\'"]?/i', $v, $match_out)?,此規(guī)則為href="(value)",并獲取括號中value的值給$match_out,那么此時我們的payload需更改為:
1 <test123><a href="file://C:/Windows/System32/drivers/etc/hosts">test</a></test123>?此時在往下看,有一個url_check函數(shù):
可以看到會檢測最后取出payload的值中是否有? ://? ,巧的是我們的payload正好符合,所以該檢測函數(shù)并未對payload造成影響。再往下回到最初的函數(shù)中:
至此,$articleurl 的值為我們最后的payload:? ?file://C:/Windows/System32/drivers/etc/hosts? ? ? ,直至此時,$article 的值為讀取到的本地任意文件的內(nèi)容,再往下看 get_filter_html()函數(shù):
$data['content'] = self::replace_item(self::get_sub_content($html, $config['content_rule'][0], $config['content_rule'][1]), $config['content_html_rule']);return $data;
由于篇幅限制,只拿出影響讀取內(nèi)容的代碼,其實這段代碼對結(jié)果并無影響,有興趣自己下來閱讀。在往下看到:
admin_tpl()函數(shù)為加載模板的函數(shù),此模板位于:application\collection\view\collection_test.html
此處只截出影響此漏洞的代碼。此處可以看到,將讀取出的任意文件內(nèi)容顯示出來,到此則漏洞分析完畢。
?
漏洞復(fù)現(xiàn)
復(fù)現(xiàn)環(huán)境
操作系統(tǒng):windows 7
php版本:5.5.38 + Apache
mysql版本:5.5.53
?
首先登陸后臺,進入 模塊管理--->采集管理
添加節(jié)點
此處網(wǎng)站配置框中,可以在自己的vps服務(wù)器中搭建一個html網(wǎng)頁,其內(nèi)容為payload:
<test123><a href="file://C:/Windows/System32/drivers/etc/hosts">123</a></test123>?
獲取網(wǎng)站中的區(qū)域開始html為<test123>,區(qū)域結(jié)束的HTML為</test123>。點擊保存。
再次點擊測試采集,則讀取payload中的hosts文件。
復(fù)現(xiàn)成功。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/Spec/p/11188198.html
總結(jié)
以上是生活随笔為你收集整理的YZMCMS V5.3后台 SSRF的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj3714:[PA2014]Kug
- 下一篇: PAT_B_1006 换个格式输出整数