首页 代码审计

1 影响范围

ThinkPHP 5.0.5 - 5.0.22

2 实验环境

ThinkPHP 5.0.12
php 5.6.27

3 漏洞分析

漏洞主要成因是对Request对象的构造方法进行调用,然后实现成员属性的覆盖
POST传入:_method=__construct&method=GET&filter[]=system&s=whoami
20258-nica3w20rz.png

3.1 变量覆盖

下面上payload进行分析
15603-s30jyvk95ss.png

一直跟进至method(),调用栈如下:
68999-3qlyf2p4bm3.png
var_method默认值为_method
51914-0iocmfyxspl9.png
代码向下跟进,通过POST传入_method参数,即会进入到红框内的条件中,通过控制_method及$_POST数组即可实现对Request类的任意方法进行调用
86246-3iwijmjtdo5.png
这里传入的_method为构造函数__construct,跟进到当前类的构造函数,在红框内通过foreach对当前对象已经定义的属性值进行覆盖。这里覆盖了filter,此值为用于全局过滤的函数
41885-l2gjw80kju8.png
最后得到的值为:

$this
    method = "GET"
    filter = {array}[1]
        0 = "system"
    input = "_method=__construct&method=GET&filter%5B%5D=system&s=whoami"

这部分变量覆盖就结束了

3.2 代码执行

跟进第一部分的解析可知,最后会在input()中使用filter对参数进行处理,所以这半部分最主要是跟进到input()

然后回到thinkApp::run(),进入exec()
42417-mxe73g2g4op.png
然后进入module()
77432-gn8a4aq3e2.png
然后再进入invokeMethod()
26891-bfrtmrp7vr5.png
然后再进入bindParams()
53338-rr0zslnm9x.png
然后再跟进到param()
03680-5tivsd00183.png
这里我们请求的方式为POST,但是在POST条件中$vars = $this->post(false);进入post()后再进入的input()方法会直接返回,所以这里不直接跟进到param()最终返回的input()中
49310-sipa33f8odj.png
进入input(),首先是获取过滤器
71132-c6k5zs3drih.png
进入getFilter(),默认传入filter为'',所以这里取Request对象下的filter,这里即为前面覆盖的值
56138-dp3wfyw7fyr.png
继续回到input(),在继续跟进到array_walk_recursive()
05560-6x84eqdrvl2.png
然后会进入到filterValue(),这里面会对提交的参数值进行过滤,通过call_user_func执行代码
78174-9grlyi1515f.png

最后结果
42433-h35jaltjhkk.png

3.3 其他

网上部分payload使用的index.php?s=captcha,这个在\vendor\topthink\think-captcha\src\helper.php下注册了路由
00051-03fzv95ai5um.png
使用的请求方式为GET,所以在传参时会传入method=GET,上面分析的那个payload可以不传入



文章评论

评论已关闭

目录