ThinkPHP5.0.0~5.0.23RCE 漏洞分析及挖掘思路

发布时间:2024年01月16日
前言

本节我将分析thinkphp5.0.x 版本的RCE漏洞,根据漏洞的研究模拟挖掘此漏洞的思路

本次分析框架下载,由于官方已经下架了相关的下载接口,这里我们用三方下载 一份v5.0.22版本的升级中...icon-default.png?t=N7T8https://www.codejie.net/5828.html

附赠?thinkphp5.0官方开发手册

架构总览 · ThinkPHP5.0完全开发手册 · 看云ThinkPHP V5.0是一个为API开发而设计的高性能框架——是一个颠覆和重构版本,采用全新的架构思想,引入了很多的PHP新特性,优化了核心,减少了依赖,实现了真正的惰性加载,支持composer,并针对API开发做了大量的优化。ThinkPHP5是一个全新的里程碑版本,包括路由、日志、异常、模型、数据库、模板引擎和验证等模块都已经重构,不适合原有3.2项目的升级,请慎重考虑商业项目升级,但绝对是新项目的首选(无论是WEB还是API开发),而且最好是忘记3.2版本的思维习惯,重新理解TP5。icon-default.png?t=N7T8https://www.kancloud.cn/manual/thinkphp5/122950

漏洞复现

这里先上payload 大家可以验证环境是否可行

?接下来我们就略过漏洞分析,模拟一下这个漏洞发现的思路

Request类中危险函数

在request类filterValue方法下有一个call_user_func()函数

如果传进去的两个参数$filter与$value都是可控的话,则会产生漏洞

函数调用链倒逆分析

接下来分析谁可以调用filtervalue方法

在requestl类中1026行,调用了此方法filtervalue,传入了相关值

?这段代码是位于994行input函数内,其中data 没有更改的,filter在1023行有本类的成员filter赋予

?那么我们继续分析谁可以调用input函数

仍然在requesr类中661行调用了此函数input,且传入input的data数组参数是本类的param赋予的

这段代码位于request类中的param方法中

?继续分析谁可以调用param函数,现在就不用这考虑传参的问题了,我只需request类的中param成员与filter成员为可控参数即可,且filter为数组包含一个system,param为这个数组包含命令语句为最佳。

让参数变得可控

在app类中exec方法中有调用调用request类的param

?需要注意的是这个框架的对象的创建模式是单例模式,也就是说469行instance得到的对象在前提request对象存在的情况下,得到的还是之前的request而非新的对象。

那么我们到底可不可以控制request对象的成员呢?看看名字-request!用户请求!似乎是可控的,不能说全不吧总有一两个属性是为用户准备的,?

现在继续分析函数调用链。要确保dispatch的type为merhod,我们才能正常调用param函数

谁调用了exec?函数,

在app类中77行run函数调用了exec函数

此外还有了两个意外的收获,1是我们找到了request对象2是我们发现了dispatch的赋值

函数调用链正向分析?

由此我们追入routecheck函数,一是寻找让dispatch对象的成员type值为method,二则是继续寻找让request对象的filter成员与param成员成为可控变量的契机。(不要乱 不要乱)

看到result不妨大胆的猜测,它最终就是这个函数执行的返回值

在643行,就有了result结果,而且联系了request对象

?追进route的check方法

在857看到了敏感参数method ,保证type为method跟它有没有关呢!再分析返回值

method会与rules有关,rules在87行会与返回值有关。

也没有找到type赋值的地方,我们大胆进入strtolower($request->method());,且这还还是调用request对象的方法,那更要分析了

(在下图 由注释信息当前的请求类型,猜测与type有关)

根据逻辑语句(我们都没有传参),它会进入524行

$_POST是什么参数!它一般都是用户输入的post数据,这是我们可控的。代码之后就把取出的值放在了method,看看它做了什么。它居然被调用了,而且传入的参数就是$_post,这是我们控制的,也就是说现在,我们可以任意调用request类的方法,且是参数还是我们可控的,

那这样的话,我用对象的方法去改对象的值岂不是轻轻松松!到request类中好好看看!

非常顺利 __construct就有成员属性赋值的机制。

我们可以将request对象的filter成员与param成员赋值了 ,(理论就是这样不过实际上你要调试的更多,因为要考虑到很多细节嘛)

至于type类型,这个我还真没分析出来,不过我们可以尝试调用接口方法,参看type类型这也不失为一种分析方法,像我调用/public/index.php的时候type就为module 调用/public/index.php?s=captcha就为method 这正是我们想要的

如果上述都可行,那我们构造好的参数,就可以RCE了, 谁调用app.run 完全不用管,一定会调用的

————————————————————————-----------——————————

总结

现在那么的RCE漏洞,那些大佬是怎么探索出来的,思路是什么,有没有0day大佬交个朋友!...我只能尽力追赶吧....

文章来源:https://blog.csdn.net/shelter1234567/article/details/135629540
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。