FineCMS前臺getshell 2016-09-30 #php #finecms
FineCMS企業網站管理系統(簡稱免費版或企業版)是一款基于PHP+MySql+CI框架開發的高效簡潔的中小型內容管理系統,面向多終端包括Pc端網頁和移動端網頁,支持自定義內容模型和會員模型,并且可以自定義字段,可面向中小型站點提供重量級網站建設解決方案,適用于小型站點、企業級網站、新聞內容網站等。
漏洞概要
finecms某處過濾不嚴格,導致可上傳任意腳本文件。
漏洞詳情
依舊是AttachmentController
,當然這次不再是kindeditor_upload
的上傳文件然后包含文件這么簡單了,而是直接上傳腳本執行。
這次出現問題的是ajaxswfuploadAction
方法,這個方法代碼不是很多,我就直接全部貼出來了:
/**
* Swf上傳
*/
public function ajaxswfuploadAction() {
if ($this->post('submit')) {
$_type = explode(',', $this->post('type'));
if (empty($_type)) {
exit('0,' . lang('att-6'));
}
$size = (int)$this->post('size');
if (empty($size)) {
exit('0,' . lang('att-5'));
}
$data = $this->upload('Filedata', $_type, $size, null, null, $this->post('admin'), 'swf', null, $this->post('document'));
if ($data['result']) {
exit('0,' . $data['result']);
}
//唯一ID,文件全路徑,擴展名,文件名稱
exit(time() . rand(0, 999) . ',' . $data['path'] . ',' . $data['ext'] . ',' . str_replace('|', '_', $data['file']));
} else {
exit('0,' . lang('att-4'));
}
}
聰明的人,一眼就能看出來,從post請求中獲取了type
,
那么這個type是干啥用的?沒錯,他是設定允許上傳的文件類型的,并且在第289行左右直接帶入了upload
函數?。?!我的天哪??!
本以為這樣就可以直接上傳php文件進行getshell了,但是發現其實finecms也不傻~~在upload
函數中進行了強制性的黑名單過濾:
$ext = $upload->fileext();
if (stripos($ext, 'php') !== FALSE
|| stripos($ext, 'asp') !== FALSE
|| stripos($ext, 'aspx') !== FALSE
) {
return array('result' => '文件格式被系統禁止');
首先是獲取了文件后綴,用了fileext()
函數,跟進來看看:
/**
* 取得文件擴展
*
* @return 擴展名
*/
public function fileext() {
return strtolower(trim(substr(strrchr($this->file_name['name'], '.'), 1, 10)));
}
先取出.
和后面的所有字符,然后從.
往后取出10個字符,最終全部轉成小寫。
然后我們繼續看這個看似很牛逼的黑名單:
if (stripos($ext, 'php') !== FALSE
|| stripos($ext, 'asp') !== FALSE
|| stripos($ext, 'aspx') !== FALSE
) {
return array('result' => '文件格式被系統禁止');
stripos
函數從前往后查找php
、asp
、aspx
如果查到了就直接return了。
那好…… 我們利用phtml來進行繞過,不知道phtml是啥請自行百度。。。
先構造上傳的html表單
?
然后上傳一個帶有一句話木馬的phtml文件,答案是可行的:
訪問上傳的文件看看:
那么我們再用工具連接下這個一句話木馬看看:
至此,一個前臺getshell,bingo!
漏洞修復
文件/controllers/AttachmentController.php
第224行的判斷添加phtml限制:
if (stripos($ext, 'php') !== FALSE
|| stripos($ext, 'phtml') !== FALSE
|| stripos($ext, 'asp') !== FALSE
|| stripos($ext, 'aspx') !== FALSE
) {
return array('result' => '文件格式被系統禁止');
}
另外不是很推薦用黑名單,用白名單會比黑名單有效得多。(其實這個修復方式還是可以繞過的)