thinkphp 5.0.10 缓存rce漏洞本质是cache::set未校验用户输入,导致攻击者可控缓存文件名与内容,在runtime/cache/下生成并直接执行恶意php文件。

ThinkPHP 5.0.10 缓存 RCE 漏洞本质是缓存写入过程未校验用户输入,导致攻击者可控制缓存文件名与内容,最终在 runtime/cache/ 下生成恶意 PHP 文件并直接访问执行。实操重点不在“能不能复现”,而在“怎么从代码里一眼看出风险点”。
定位缓存调用链:从 Cache::set 入手
在项目中全局搜索 Cache::set、cache( 或 $cache->set(,重点关注参数是否直接拼接了用户可控变量(如 $_GET['username']、input('name'))。典型危险写法:
-
Cache::set($_GET['key'], $_GET['value']);—— key 和 value 都未过滤 -
cache(input('file'), file_get_contents(input('path')));—— input() 返回值直接作缓存键名 - 使用字符串拼接构造缓存标识:
$key = 'user_' . $_GET['id'] . '_' . md5($data);,若$_GET['id']含../或特殊字符,可能影响写入路径
检查缓存驱动与存储路径是否可控
打开 config/cache.php,确认是否启用文件驱动('type' => 'File')且未禁用自动创建目录('data_path' 默认为 runtime/cache/)。关键风险点:
- 缓存路径未做 realpath 校验或白名单限制,允许通过
../跳出 cache 目录 - 缓存键名被直接用于生成文件名,未 strip 特殊字符(如
/、.、php后缀),导致可写入.php扩展名文件 - 运行时目录(
runtime/)被 Web 服务器直接可读可执行(常见于开发环境配置不当)
验证 payload 是否能落地成 PHP 文件
构造一个最小化测试请求,观察是否能在 runtime/cache/ 下生成含 PHP 代码的文件:
- 发送:
GET /public/?username=syst1m @eval($_GET[p]); - 触发缓存写入逻辑(如访问某个带缓存的接口或页面)
- 手动访问生成的缓存文件路径,例如:
http://127.0.0.1/runtime/cache/b0/68931cc450442b63f5b3d276ea4297.php?p=phpinfo(); - 若返回 phpinfo 页面,说明漏洞链路完整成立
修复必须同步切断三个环节
仅升级版本或加个 if 判断无效,需入口、参数、配置三端齐控:
- 入口拦截:所有缓存 key 必须经过
md5()或sha1()哈希,禁止原始用户输入直接作键名 - 参数过滤:对所有传入
Cache::set()的 value 做htmlspecialchars()或base64_encode(),避免写入可执行代码 - 配置加固:将
runtime/移出 Web 根目录;或在 Web 服务器层(Nginx/Apache)禁止访问runtime/cache/.*\.php类路径
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











