当前位置: 当前位置:首页 > 知识 > thinkphp命令执行漏洞正文

thinkphp命令执行漏洞

作者:热点 来源:娱乐 浏览: 【大 中 小】 发布时间:2026-10-17 06:06:56 评论数:

ThinkPHP命令执行漏洞:一次命中注定的命令事故

2018年12月,一个ThinkPHP 5.0.x版本的执行远程代码执行漏洞被公开。当时我还在某安全公司做渗透测试,漏洞客户连夜打电话说官网被篡改。命令登录服务器一看,执行web目录里躺着一排排的漏洞webshell,攻击者用同一个payload打进来的命令——就是那个经典的`?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id`。

这个漏洞的执行根源并不复杂。ThinkPHP的漏洞路由解析把用户输入直接拼进了类名和方法名,而框架的命令`invokefunction`方法又允许动态调用任意函数。说白了,执行框架开发者为了“灵活”留了后门,漏洞却忘了检查调用者是命令谁。攻击者只需要构造一个URL,执行就能让服务器执行任意系统命令——连密码都不用猜。漏洞

有意思的是,官方在2018年12月9日就发布了修复补丁,但漏洞爆发的高峰期却持续到了次年1月。为什么?因为太多老项目还在跑着5.0.5甚至更早的版本,运维人员压根不知道要更新。我见过一家做电商的公司,后台订单系统直接暴露在公网,ThinkPHP版本还是5.0.3,补丁发布两周后他们才从新闻里听说这事——而那时候数据库早被拖走了。

这个漏洞的杀伤力在于它不需要任何前置条件。你不需要登录,不需要传特殊格式的POST数据,甚至不需要知道目标站点用什么架构。只要在URL后面加上那串payload,服务器就乖乖听话了。我试过对一个使用ThinkPHP的政府网站发起请求,返回结果直接是`uid=0(root)`——那一刻我理解了为什么黑产圈子里管这叫“送分题”。

修复本身倒是简单,把路由解析中的正则表达式收紧,禁止`\`符号出现在控制器名里,再对`invokefunction`加个白名单就完事。但真正的问题在于,ThinkPHP在国内中小型项目里的普及率太高了。很多开发者用它是因为文档全、上手快,可他们从来没意识到——框架的“便捷”特性,恰恰是攻击者的“便捷”入口。你图它写代码快,黑客图它拿shell快,大家都有光明的未来。

后来我总结过一个规律:凡是框架自带“动态调用”功能的,几乎都出过类似漏洞。Laravel的`call_user_func`反序列化、Java的Fastjson、Python的eval——本质都是同一件事。框架为了灵活性把安全边界模糊了,而开发者又习惯性相信默认配置。所以你说这漏洞是ThinkPHP的锅?它确实背锅,但真正的坑在于使用者的盲目信任。

现在回看那个冬天,国内至少有上万台服务器因为这个漏洞被植入了挖矿程序。有些站点至今没修复——你随便在FOFA上搜ThinkPHP特征,还能捞到不少响应`root`权限的。技术圈总爱说“漏洞是代码写的,不是人写的”,但现实是,补丁发了没人打,扫描器扫了没人管,这才是常态。

别问我怎么防御,问就是先把框架升级到最新版,再关掉debug模式,最后祈祷你的运维明天还记得看安全公告。如果这些都做不到——那至少别把`system`函数暴露给用户输入,对吧?