漏洞介绍:
2020年1月10日,ThinkPHP团队发布一个补丁更新,修复了一处由不安全的SessionId导致的任意文件操作漏洞.
-
在目标环境为Windows且开启session的情况下,容易遭受任意文件删除攻击。
-
在目标环境开启session且写入的session可控的情况下,容易遭受任意文件写入攻击。
漏洞环境:
版本:
1 | ThinkPHP V6.0.0-v6.0.1 |
回退thinkphp版本的方法
1 | 修改composer.json文件的下面内容,指定"topthink/framework": "6.0.1", |
环境搭建
-
进入\tp6.0\app\middleware.php开启session
-
在Index.php文件中添加可以控制session内容的方法
漏洞分析:
1.sessionId的控制
thinkphp开启session初始化后,每次处理网页请求会调用SessionInit::handle对session进行初始化。
开启session后在默认的配置下是会将cookie中PHPSESSID的值作为$sessionid的值
再进入第60行的SessionInit::setId方法。可以发现只要我们的$sessionid
长度为32个字节,即可控制$this->id
为$sessionid
。
2.session值的控制
再来分析通过助手函数session()保存传入的session值的逻辑
进入session(),顺着处理逻辑继续进入Session::set,发现Arr::set
然后再继续进入Arr::set,可以发现在这里Arr::set的作用就是给$this->data
数组添加键值对对'session_name'=>$_POST['value']
。
现在我们已经知道session的内容保存在$this->data
中
3.session文件操作
session文件的生成的处理函数在SessionInit::end中
进入save方法,这里write对应于session文件的生成,delete对应于session文件的生成
任意文件上传漏洞
先来分析write方法,该方法位于tp6.0\vendor\topthink\framework\src\think\session\driver\File.php的File类中
所以通过控制PHPSEEIONID和写入session的内容我们可以实现上传可控文件名和内容的文件到\tp6.0\runtime\session\目录下
payload数据包类似以下形式
1 | POST /tp6.0/public/index.php/index/test HTTP/1.1 |
在runtime/session/目录生成可控文件名文件内容的php文件
任意文件删除漏洞
再来分析delete方法,该方法也位于File类中
在windows平台下可以绕过sess_实现文件删除,linux下就不可以了
payload数据包类似以下形式,注意PHPSESSIONID为32个字节
1 | //这个数据宝将会删除/runtime/session/目录下的a.php文件(如果该目录下有这个文件的话) |
漏洞总结:
-
在目标环境为Windows且开启session的情况下,容易遭受任意文件删除攻击。
-
在目标环境开启session且写入的session可控的情况下,容易遭受任意文件写入攻击。