概述
2020 年 1 月 10 日,ThinkPHP 团队发布一个补丁更新,修复了一处由不安全的 SessionId 导致的任意文件操作漏洞。
该漏洞允许攻击者在目标环境启用 session 的条件下创建任意文件以及删除任意文件,在特定情况下可 getshell。
具体受影响版本为 ThinkPHP 6.0.0 - 6.0.1。
环境搭建
composer 创建项目。
composer create-project --prefer-dist topthink/think=6.0.0 thinkphp6.0.0 |
在 app/controller/Index.php 中加一行代码,使 session 内容可控,方便漏洞复现。
class Index extends BaseController { |
PS:TP 6 默认没开启 session,手动开下,在 app/middleware.php 取消注释即可。
|
复现
分析
https://github.com/top-think/framework/commit/1bbe75019ce6c8e0101a6ef73706217e406439f2
如果传入的 $id 长度为 32 即可控。TP 6.0.2 加了个条件,用 ctype_alnum
检测了下 $id,只能是字母或数字。
# src/think/session/Store.php |
handle
函数将 cookie 中的 PHPSESSID
对应的值设为 sessionId。
// middleware/SessionInit.php |
剩下的文件处理其实就是 session 本身的处理了,比如 $_SESSION 数组被序列化后写入文件保存以及清除。
// src/think/session/Store.php |
跟进 $this->handler->write($sessionId, $data);
的具体实现。
// session/driver/File.php |
总结
总的来说还是比较鸡肋,需要能控制 session,直接打不了。
所以要与具体的业务结合,寻找 session 的输入点,比如某些系统将用户名直接存入 session 中。
另外,那个删除点就更难控制了,那也是 TP 清除 session 的正常功能,所以能删的文件必须以 sess_
开头。
参考
https://mp.weixin.qq.com/s/UPu6cE20l24T6fkYOlSUJw
https://mochazz.github.io/2020/01/14/ThinkPHP6.0%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E5%86%99