yii文件包含漏洞
- 触发点
public function actionIndex()
{
// $this->render('index');
$name =Yii::app()->request->getParam( 'name' );
$this->render('index', $name);
}
render 函数
public function render($view, $params = [], $context = null)
{
$viewFile = $this->findViewFile($view, $context);
return $this->renderFile($viewFile, $params, $context);
}
$params 参数保证可控,renderFile函数
public function renderFile($viewFile, $params = [], $context = null)
{
····
····
if ($this->beforeRender($viewFile, $params)) {
Yii::debug("Rendering view file: $viewFile", __METHOD__);
$ext = pathinfo($viewFile, PATHINFO_EXTENSION);
if (isset($this->renderers[$ext])) {
if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) {
$this->renderers[$ext] = Yii::createObject($this->renderers[$ext]);
}
/* @var $renderer ViewRenderer */
$renderer = $this->renderers[$ext];
$output = $renderer->render($this, $viewFile, $params);
} else {
$output = $this->renderPhpFile($viewFile, $params);//
}
$this->afterRender($viewFile, $params, $output);
}
array_pop($this->_viewFiles);
$this->context = $oldContext;
return $output;
}
文件包含在renderPhpFile 函数中
public function renderPhpFile($_file_, $_params_ = [])
{
$_obInitialLevel_ = ob_get_level();
ob_start();
ob_implicit_flush(false);
extract($_params_, EXTR_OVERWRITE);
try {
require $_file_;
return ob_get_clean();
} catch (\Exception $e) {
while (ob_get_level() > $_obInitialLevel_) {
if (!@ob_end_clean()) {
ob_clean();
}
}
throw $e;
} catch (\Throwable $e) {
while (ob_get_level() > $_obInitialLevel_) {
if (!@ob_end_clean()) {
ob_clean();
}
}
throw $e;
}
}
extract函数,变量覆盖,未作限制,如果传进来数组key可控,可以覆盖$_file_值,造成文件包含。在Yii1.0版本中尝试了几个版本,发现没有renderPhpFile函数,对应有renderInternal函数,在extract时有前缀限制,无法覆盖任意变量。
yii1.*
public function renderInternal($_viewFile_,$_data_=null,$_return_=false)
{
// we use special variable names here to avoid conflict when extracting data
if(is_array($_data_))
extract($_data_,EXTR_PREFIX_SAME,'data');
else
$data=$_data_;
if($_return_)
{
ob_start();
ob_implicit_flush(false);
require($_viewFile_);
return ob_get_clean();
}
else
require($_viewFile_);
}
漏洞利用条件,render函数param参数,key和value都可控。
这里直接写死
public function actionIndex()
{
$name =Yii::app()->request->getParam( 'name' );
$data=array();
$this->render('index', array('_file_'=>'D:\\tools\\111.txt'));
}