一、漏洞描述
ThinkPHP6.0.0到ThinkPHP6.0.1,由不安全的SessionId导致的任意文件操作漏洞。该漏洞允许攻击者在目标环境启用session的条件下创建任意文件以及删除任意文件,在特定情况下还可以getshell。
二、漏洞发现
首先我们下载好thinkphp6.0.0源码,网上搜一搜就出来了。将源码放在phpstudy的www目录下。注意需要运行环境php7.1+。先在/app/middleware.php中开启session。
然后在/app/controller/Index.php添加以get方式获取session值的语句,模拟真实情况下session可控。
从/app/middleware.php入手,调用了\think\middleware\SessionInit的handle方法做初始化,将getname方法的返回值给过来,cookie方法处理后传入sessionId做了setId的参数
而在setId中判断传过来的id是否为32位,如果是32位就直接用没有任何过滤
直接来看vendor/topthink/framework/src/think/session/Store.php中的save方法,用getId方法获得sessionId,而getId里面是我们刚刚用setId设置的id,也就刚刚没被过滤的东西。用serialize方法将内容反序列化。然后将这两个变量传入write方法中
跟进write方法在vendor/topthink/framework/src/think/session/driver/File.php。getFileName设置文件名字,
writeFile将内容写入文件里面。
在getFileName方法中,直接拼接sess_+刚刚传来的sessID
在writeFile方法中,将序列化的内容直接写进去,写在/ runtime/session/sess_(可控sessionId)里面,文件名可控和内容可控导致任意文件操作漏洞
三、漏洞利用
已知index.php的zk变量通过get方式提交可控传进session里面
构造payload:
zk参数后面是文件里面的内容,phpsessid是文件名字。如果字符串等于32位则直接命名,不做任何处理,所以这里只要前面写28个z后面.php占4个字节,一共32字节。
文件路径为/runtime/session/sess_aaaaaaaaaaaaaaaaaaaaaaaaaaaa.php,直接访问。
利用成功。
也可以将内容替换为一句话木马,用菜刀,蚁剑链接。
payload:
看一下session记录的文件