Laravel 5 Deserialization Chain Summary - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

Laravel 5 Deserialization Chain Summary

一叶飘零 技术 2020-08-19 09:49:48
473043
收藏

导语:Laravel 7中由于一些有所类修复,导致一些pop chain无法使用,于是这次在Laravel 5系列中,也做一次总结,列举比较适合的切入点和查找新链的思路。

前言

Laravel 7中由于一些有所类修复,导致一些pop chain无法使用,于是这次在Laravel 5系列中,也做一次总结,列举比较适合的切入点和查找新链的思路。

遍地撒网

为了更好的找出切入点,我这里直接写了一个脚本,列举出所有包含__destruct的class和其__destruct的定义,并将laravel 5和laravel 7进行比对:

2020-07-22-11-31-17.png

其实不难发现,Laravel 7和Laravel 5在切入点这一块,并无太多的区别,几乎一致,一般修改均为一些微调。

同时我们可以搜寻一下切入点,一般分为如下几类:

· __destruct中$this->xxxx()调用形式

· __destruct中$this->xxx->yyy()调用形式

· __destruct中built-in function调用形式

那么本文对于laravel 5的pop chain寻找也围绕这3点进行展开。

$this->xxxx()调用形式

根据这个调用形式进行寻找,有比较知名的CVE-2019-9081,我们可以看到其函数定义:

Illuminate\Foundation\Testing\PendingCommand::__destruct
public function __destruct()
{
    if ($this->hasExecuted) {
        return;
    }
    $this->run();
}

此处run函数可以引入RCE风险,此处分析不再赘述,可以参考文章:

https://laworigin.github.io/2019/02/21/laravelv5-7%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96rce/

当然这个类在Laravel 7中已经被修复。

除此之外,还有包括上篇文章我们分析过的:

Illuminate\Routing\PendingResourceRegistration::__destruct
public function __destruct()
{
    if (! $this->registered) {
        $this->register();
    }
}

此处register函数可以引入RCE风险,也不再赘述,可以参考上一篇文章。

类似的调用情况同样很多,我简单列举几个:

GuzzleHttp\Cookie中常见的:

$this->save();

Monolog\Handler和Symfony\Component中常见的:

$this->close();

League\Flysystem中常见的:

$this->disconnect()

除此之外,还有一些在__destruct中出现频率不高的,如果感兴趣的都可以跟进进行尝试构造。

$this->xxx->yyy()调用形式

而对于这种调用形式,我们在之前的文章中提到过,其有2种思路进行利用:

· __call魔法方法

· 同名函数

我们看几个典型的例子:

Illuminate\Broadcasting\PendingBroadcast::__destruct
public function __destruct()
{
    $this->events->dispatch($this->event);
}

此处由于$this->events和$this->event均可控,因此可利用同名函数或__call的方式进行RCE pop chain的构造。

除此之外:

Symfony\Component\Routing\Loader\Configurator\ImportConfigurator::__destruct
public function __destruct()
{
    $this->parent->addCollection($this->route);
}

同样有着相似的问题,虽然可能没有同名危险函数,但可以利用__call来进行构造,配合Faker\Generator来构造RCE pop chain。

并且如下类也存在类似的问题:

Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator::__destruct
public function __destruct()
{
    if (null === $this->prefixes) {
        $this->collection->addPrefix($this->route->getPath());
    }
        $this->parent->addCollection($this->collection);
}

相应的,其实我们在构造同名函数RCE pop chain的时候其实还算好,但当构造__call的时候,由于call name一般不可控,毕竟Faker\Generator中name可通过数组控制的情况不算特别多,那么此时可能会遇到瓶颈。

所以这种形式的利用手段并不是想象中那么丝滑(,还是需要精心构造的。

built-in函数

此类情况一般偏少,我们将搜寻锁定在敏感函数上,例如:

call_user_func、call_user_func_array、system、eval......

这里不难直接发现一个类:

GuzzleHttp\Psr7\FnStream::__destruct
public function __destruct()
{
    if (isset($this->_fn_close)) {
        call_user_func($this->_fn_close);
    }
}

我们发现其直接调用了call_user_func,同时参数可控,为 $this->_fn_close,但难点在于该函数只可控第一个参数,因此这里我们可以想到能否调用类内方法,如果该方法不需传递参数且方法内敏感函数参数可控,为类内属性,那么即可利用。

这里不难想到,诸如:Illuminate\Foundation\Testing\PendingCommand的run方法,Illuminate\Routing\PendingResourceRegistration的register方法,都是可以通过其进行利用的。

当然这会显得有些取巧,如果你有兴趣的话,可以过一遍危险函数所在的方法,看看是不是其可以无参调用~

但是不幸的是,当前这个例子中,我们跟进类进行分析:

public function __wakeup()
{
    throw new \LogicException('FnStream should never be unserialized');
}

由于存在__wakeup,我们在利用这个chain的时候会抛出'FnStream should never be unserialized'的错误,而导致无法利用。

当然,我们也可以不仅仅找__destruct函数内的危险函数,尝试搜寻一些危险函数所在的方法和类,不难找到如下几个情况:PHPUnit\Framework\MockObject\Stub\ReturnCallback::invoke,关键代码如下:

public function invoke(Invocation $invocation)
{
    return \call_user_func_array($this->callback, $invocation->getParameters());
}

又如Mockery\Loader\EvalLoader::load,关键代码如下:

public function load(MockDefinition $definition)
{
    if (class_exists($definition->getClassName(), false)) {
        return;
    }
        eval("?>" . $definition->getCode());
}

诸如此类情况,我们都可以将其整合进call_user_func或者call_user_func_array可控2个参数的地方,例如和Illuminate\Broadcasting\PendingBroadcast::__destruct组合,构造新的chain。

后记

Laravel 5由于过滤相对于Laravel 7来说缺失了一些,因此更容易被组建pop chain,同时laravel由于提供了大量的可用于构造的模块,也会衍生出各种排列组合的pop chain,但万变不离其中,最关键的还是寻找切入点。

本文提出的一些寻找pop chain的思路也是抛砖引玉,实际上寻找切入点的方式远远不止__destruct和文中所提及的3种类型,如果你有好的想法也欢迎和我联系交流~

总之还是那句话,求求CTF里别再出laravel的pop chain构造了。

本文为 一叶飘零 原创稿件,授权嘶吼独家发布,如若转载,请注明原文地址:
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务