zoukankan      html  css  js  c++  java
  • Thinkphp 5.0.x 变量覆盖导致的RCE 漏洞分析

    Thinkphp5.X的RCE分为两大版本:

    ThinkPHP 5.0-5.0.24

    ThinkPHP 5.1.0-5.1.30


    tp5.0.x

    代码执行漏洞:

    URL:http://tp5019.com/index.php

    POST请求

    _method=__construct&method=GET&filter[]=system&s=whoami
    _method=__construct&method=GET&filter[]=system&get[]=whoami
    

    自己搭建的环境是 thinkphp5.0.5 php 5.4.x

    payload:_method=__construct&filter[]=system&method=GET&get[]=whoami

    测试,成功执行命令!

    漏洞分析:

    这条payload不受debug影响,因为触发了两次request->param()

    首先是来到 Route::RouteCheck方法中

    接着进行 Route::check 方法中

    继续跟中method方法中,这里是关键,因为这里存在变量覆盖漏洞,最后导致了命令的执行

    这里只是单纯的调用了__construct方法,我们去__construct中看看如何进行调用的,发现是一个 foreach循环将每个post的参数进行变量覆盖

    接着回到了App->run()的方法中

    调试有一处触发了param,这里我们不跟,跟另外一处(在self::module中)

    此时走到self::module这里,已经是走过了 initCommon 初始化配置参数,routeCheck 路由检测,来到了如下的地方,此时的post数据有如下

    继续跟进去,这个module方法主要就是进行 相关的控制器 动作 的初始化

    来到最后app->module方法中的最后 进行调用了路由所指向的动作

    继续跟进去return self::invokeMethod($call, $vars),来到了参数绑定的方法中,继续跟进去

    参数绑定的方法实质就是接收请求过来的方法的参数,它最后又继续进去了 request->param方法中 ,继续跟

    开始获取各种请求方法请求过来的数据

    此时我们是post请求,所以进post中

    接接着将$_POST的数据带进了input方法中,在这里$name为空所以直接退出来

    然后将数据合并 再一次进去 input方法中

    此时的$name不为false 所以往下走,此时来到了array_walk_recursive,这个方法 就是 进filterValue方法中 $data作为第一个参数 $filter作为第二个参数,用$filter函数进行处理$data每个一个值

    但是这里观察,$filter 为什么能被我们控制呢?往上看一下,当$filter不是字符串的时候,则进行转化为array赋值

    再继续走,处理完之后 $data其中的值 就为如下

    最后通过渲染,展现在页面上!

    同样的为什么会显示处两个一样的值呢?

    因为$_POST中有个get[]=whoami,当变量覆盖的时候$this->get[]=whoami,导致Request类中又多了一个whoami

    总结:

    第一个重点: $this->method 可控导致可以调用 __contruct() 覆盖Request类的filter字段

    然后App::run()执行判断 debug 来决定是否执行 $request->param(),

    并且还有$dispatch['type'] 等于controller或者 method 时也会执行$request->param()

    第二个重点: 最终 $request->param()会进入到input()方法,在这个方法中将被覆盖的filter回调call_user_func(),造成rce。

    关系图如下:


    最后还需要知道的是: 5.0.13版本之后需要开启debug才能RCE

    URL:http://tp5019.com/index.php?s=captcha

    POST请求:

    payload:_method=__construct&method=GET&filter[]=system&s=whoami

    发现没有响应,但是开启debug模式之后就可以进行命令执行

    但是开启 captcha 路由之后,在debug关闭了之后也可以进行了

    没开DEBUG,不能RCE的原因:在进入module方法中对$request->filter中的变量进行了清空

    开启debug之后能够进行RCE的原因:走的就不是module分支,而是method的分支

    参考文章:https://y4er.com/post/thinkphp5-rce/#505

  • 相关阅读:
    使用c#读取/解析二维码
    MVVM中的RelayCommand与AsyncCommand
    MVVM模式下的OpenFileDialog
    集成Source Monitor至VS中
    [转]异步command的实现
    使用Messenger实现MVVM的对话框弹出
    使用NPOI访问、控制Excel
    win11更新
    Codeforces Round #749 总结
    Codeforces Round #697 (Div. 3)
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12622077.html
Copyright © 2011-2022 走看看