PHPCMS v9本地文件包含漏洞Getshell
時(shí)間:2023-04-20 22:48:01 | 來源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2023-04-20 22:48:01 來源:網(wǎng)站運(yùn)營(yíng)
PHPCMS v9本地文件包含漏洞Getshell:
漏洞原理
文件包含函數(shù)加載的參數(shù)沒有經(jīng)過過濾或者嚴(yán)格定義,可以被用戶控制,包含了其他惡意文件,導(dǎo)致執(zhí)行了非預(yù)期的代碼。
漏洞危害
文件包含是指程序代碼在處理包含文件的時(shí)候沒有嚴(yán)格控制。導(dǎo)致用戶可以構(gòu)造參數(shù)包含遠(yuǎn)程代碼在服務(wù)器上執(zhí)行,并得到網(wǎng)站配置或者敏感文件,進(jìn)而獲取到服務(wù)器權(quán)限,造成網(wǎng)站被惡意刪除,用戶和交易數(shù)據(jù)被篡改等一系列惡性后果。主要包括本地文件包含和遠(yuǎn)程文件包含兩種形式,由于開發(fā)人員編寫源碼,開放著將可重復(fù)使用的代碼插入到單個(gè)的文件中,并在需要的時(shí)候?qū)⑺鼈儼谔厥獾墓δ艽a文件中,然后包含文件中的代碼會(huì)被解釋執(zhí)行。由于并沒有針對(duì)代碼中存在文件包含的函數(shù)入口做過濾,導(dǎo)致客戶端可以提交惡意構(gòu)造語句提交,并交由服務(wù)器端解釋執(zhí)行。
PHPCMS v9本地文件包含漏洞Getshell
全局搜索“include”關(guān)鍵字
追蹤變量
/phpcms/modules/block/block_admin.php
向上追蹤$str變量,判斷$str是否可控:
注意到: $str = $tpl->template_parse(new_stripslashes($template));
向上追蹤$template變量,判斷$template是否可控:
全局搜索new_stripslashes()函數(shù):
全局搜索template_parse()函數(shù):
結(jié)論:$str變量為用戶可控變量。
那么當(dāng)惡意用戶構(gòu)造 template=');?> 時(shí),經(jīng)過文件寫入再到文件包含,就能成功生成shell.php木馬文件。
如何才能執(zhí)行到這段代碼?
必須$data['type']==2 漏洞才會(huì)產(chǎn)生。
而 $data = $this->db->get_one(array('id'=>$id))
全局搜索定義get_one()的地方:
發(fā)現(xiàn)2處,函數(shù)內(nèi)容都一樣:
$data = array('id'=>$id)
$table是由phpcms模塊指定的。調(diào)用get_one()函數(shù)的文件是/phpcms/modules/block/block_admin.php,所以模塊為block。即$table=block
下面即為block表及其相應(yīng)的字段:
array_walk(數(shù)組,"myfunction"); —— 對(duì)數(shù)組中的每個(gè)元素使用用戶自定義函數(shù)處理。在函數(shù)中,數(shù)組的鍵名和鍵值是參數(shù)。
例:
所以定位 add_special_char() 函數(shù):
這個(gè)函數(shù)可以忽略掉。
所以最終SQL查詢語句為:select id from phpcmsv9.v9_block limit 1;
定位 fetch_next() 函數(shù):
使用 MYSQL_ASSOC 字符索引作為結(jié)果集。
所以要想 $data['type']==2 只需要 v9_block 表的某一行數(shù)據(jù)中的type字段的值為2即可。
那么如何向 v9_block 表中插入數(shù)據(jù)呢?
最終在/phpcms/modules/block/block_admin.php文件中找到向 v9_block 表中添加數(shù)據(jù)的函數(shù)體:
$_POST['name']的值在v9_block表中不存在時(shí)才會(huì)插入數(shù)據(jù)。
如何調(diào)用 add() 函數(shù):
請(qǐng)求:
http://IP/index.php?m=block&c=block_admin&a=add&pos=任意值
發(fā)送數(shù)據(jù)包:dosubmit=任意值&name=v9_block表name字段不存在的值&type=2
還需要登錄管理后臺(tái)獲取hash值:
提交第一個(gè)Payload,向數(shù)據(jù)庫中插入數(shù)據(jù):
查看數(shù)據(jù)庫:
頁面跳轉(zhuǎn)到:
到這個(gè)頁面時(shí),就已經(jīng)進(jìn)入了/phpcms/modules/block/block_admin.php文件中,執(zhí)行block_update方法了:
但我們需要執(zhí)行 publi_view()方法進(jìn)行文件包含:
所以在頁面上查找是否有執(zhí)行 publi_view() 方法模塊,最終如下:
點(diǎn)擊"預(yù)覽"后會(huì)執(zhí)行public_view()方法,在根目錄下生成shell.php木馬文件:
漏洞利用條件
1、block_admin.php需要登錄認(rèn)證管理員賬號(hào);
2、POST數(shù)據(jù)包中name值在v9_block表name字段中不存在;
3、POST數(shù)據(jù)包中type值必須為2。
Getshell:
修復(fù)建議
- PHP:配置php.ini關(guān)閉遠(yuǎn)程文件包含功能(allow_url_include = Off)
- 嚴(yán)格檢查變量是否已經(jīng)初始化。
- 建議假定所有輸入都是可疑的,嘗試對(duì)所有輸入提交可能可能包含的文件地址,包括服務(wù)器本地文件及遠(yuǎn)程文件,進(jìn)行嚴(yán)格的檢查,參數(shù)中不允許出現(xiàn)../之類的目錄跳轉(zhuǎn)符。
- 嚴(yán)格檢查include類的文件包含函數(shù)中的參數(shù)是否外界可控。
- 不要僅僅在客戶端做數(shù)據(jù)的驗(yàn)證與過濾,關(guān)鍵的過濾步驟在服務(wù)端進(jìn)行。
- 在發(fā)布應(yīng)用程序之前測(cè)試所有已知的威脅。