怎么将php文件改成web的servlet文件_thinkphp6 session 任意文件创建漏洞复现 含POC

775956cd34ba71a02c6b9d8bc2182d46.png

欢迎关注公众号:漏洞推送,获取更多漏洞分析


0x1:漏洞复现

首先通过composer创建thinkphp6的框架目录

composer create-project topthink/think think6

创建好了以后,默认是thinkphp6最新版本的,漏洞是已经修复了的,所以我们需要对程序进行降级

编辑程序根目录下的composer.json文件,改成如红框所示

60dd3e7912929be686fd84f30e54d1b7.png

然后执行

compose update

如图所示,即是降级成功

60b86d41ff642bf71dff9af651c548dc.png

然后是非常重要的一步,很多复现的文章都没有写,就因为这个浪费了我一两个小时的时间

thinkphp6默认是没有开启session功能的,我们需要在appmiddleware.php文件中,取消session中间件的注释,设置为如图

522a81c27d694a4441b89ea6834c4a69.png

终端运行 php think run 启动调试环境

f672084ba90a52885528e57aaf9f98e0.png

appcontrollerIndex.php中添加测试代码

72e83f2a4501c887b3ad7e6f7e4ab2b7.png

在浏览器f12 console里面执行poc,然后刷新页面

7c1d68c50a35bd0b439012c51e2b3be9.png

document.cookie="PHPSESSID=aaaaaaaaaaaaaaaaaaaaaaaaaaaa.php";

runtimesession文件夹下就会生成php文件

cbc8feac77fc48c90b4d69ea7431dc10.png

如果要利用这个漏洞getshell的话,还要解决两个问题

1.文件内容可控,而生成的文件里面的内容,就是将session内容的反序列化

aa1c33f20eaa58c5fdb6a38309ae8ff4.png

如果后端代码里面有类似,这种代码的话就是可以利用的

Session::set('name', $_POST['a']);

2.thinkphp的网站一般会把 /public 设置为网站的根目录,而生成的文件是在/runtime/session文件夹下面的,默认是访问不到的

但是这个通过,即可绕过

PHPSESSID=/../../../public/aaaaaaaaaaa.php

Python漏洞检测POC

https://github.com/lanyi1998/pochub/blob/master/thinkphp6_file_write.py​github.com

ac0820f8b770098bb9a37347559aa362.png

0x2:漏洞分析

根据tp官方的提交记录来看,是对setId函数做了修改,那么漏洞一定和这个函数有关,全局搜索一下这个函数

a1b3dc06514ca2eb10cb76c31265233f.png

找到在 vendor/topthink/framework/src/think/middleware/SessionInit.php中

dae18c764f6e0062b0f936c9e0b7d6cf.png

第一步:

4360540ad177c0cd48c31043c197edf1.png

从cookie中取出phpsessid的值,赋值给sessionId

第二步:

7bc992ab8bc58bc72cf336f4fa26f0a2.png

通过setid函数把session类id设置为,刚才从cookie中取到的值

第三步:

执行session类中的init方法,本来以为写入操作是在这个函数里面进行的,但是debug以后发现不是的

看thinkphp文档

3ec3c1fe468838e75644f234b1dad51d.png

tp6会在请求结束的时候进行session写入

vendortopthinkframeworksrcthinkHttp.php

4aff949c88d3f6280c35ab6791277411.png

会调用vendortopthinkframeworksrcthinkmiddlewareSessionInit.php下的end方法

7bcbd011deac529b6ba300ae1efba3a8.png

接下来调用vendortopthinkframeworksrcthinksessionStore.php中的save方法

0828a3ab110c9cc59c312f0c719d95f4.png

跟进到红框所示的write方法,会执行vendortopthinkframeworksrcthinksessiondriverFile.php中

08da77758547a6573ddcb2ecd2d6c4af.png

通过getFileName函数,完成session文件名的拼接,然后再调用writeFile函数

caba97e9be809570f21a0933c7feb2ac.png

session文件写入流程完成!

调用流程图

fc3cbc4de1150ff16fe71abac4e3bfea.png

0x3:漏洞修复

5982734b732886d1c41e0c759c0e5255.png

查看补丁是对id增加了一个ctype_alnum函数,查一下文档

df4bdafe2e5360786839c92ef736b288.png

如果传进来的id里面含有如 . 这样的,就会使用下面的代码来随机生成一段id,而不会实用传进来的ID

md5(microtime(true) . session_create_id()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值