ThinkPHP 6.0.1 漏洞分析

漏洞分析

需在全局的中间件定义文件中加上session的中间件定义开启session 根据官方给出的更新代码定位到src/think/session/Store.phpsetId() 此函数为session_id设置,全局搜索发该函数现在src/think/middleware/SessionInit.php的session初始化时处调用 其中的$sessionId参数是通过cookie($request->cookie($cookieName))获取的
getName()默认获取的值为为PHPSESSID
意思是只要PHPSESSID为32位长度,这32位的值我们可随意控制 通过setId()设置了可控的$this->id,可通过getId()函数获取其值 注意到到Store.phpsave()函数中有write()delete()操作
save()src/think/middleware/SessionInit.phpend()触发(开启session后每次刷新页面都会触发) 下面分别再跟入delete()write()操作:

delete

delete()调用了src/think/session/driver/File.php中的 getFileName()$name参数直接拼接在$filename尾部 session格式为sess_32位可控字符 可以看出存在任意文件删除漏洞
在非Windows系统中,PHP的unlink()从不存在的目录往上跳时会报错No such file or directory 所以此任意文件删除仅在Windows操作系统中有效

write

默认情况下$this->data为空,无法进入write()操作 假设这里$this->data非空,进入src/think/session/driver/File.php 也是通过getFileName()获取文件名
再通过writeFile()写入文件 可知若传入的$data可控,我们即可写入任意文件 这里的$data就是session的值,利用thinkphp的session操作才能触发漏洞
如果将用户可控的输入(用户名等)不慎直接放入session中,即可造成RCE

 

参考文章

ThinkPHP 6.0.2 更新
ThinkPHP 6 任意文件写入漏洞风险通告
ThinkPHP 6 任意文件操作漏洞分析