国庆复习了三个tp框架的反序列化漏洞,感觉复现的时候能学到好多,这里再分析一个Ecshop 2.x-3.x 远程代码执行漏洞
源码下载: https://www.mycodes.net/44/9232.htm
elseif ($action == 'login')
{
if (empty($back_act))
{
if (empty($back_act) && isset($GLOBALS['_SERVER']['HTTP_REFERER']))
{
$back_act = strpos($GLOBALS['_SERVER']['HTTP_REFERER'], 'user.php') ? './index.php' : $GLOBALS['_SERVER']['HTTP_REFERER']; //$back_act可控
}
else
{
$back_act = 'user.php';
}
}
...
$smarty->assign('back_act', $back_act);
$smarty->display('user_passport.dwt');
}
function assign($tpl_var, $value = '')
{
if (is_array($tpl_var))
{
foreach ($tpl_var AS $key => $val)
{
if ($key != '')
{
$this->_var[$key] = $val;
}
}
}
else
{
if ($tpl_var != '')
{
$this->_var[$tpl_var] = $value; //$this->_var[$tpl_var]可控
}
}
}
function display($filename, $cache_id = '')
{
$this->_seterror++;
error_reporting(E_ALL ^ E_NOTICE);
$this->_checkfile = false;
$out = $this->fetch($filename, $cache_id);
if (strpos($out, $this->_echash) !== false)
{
$k = explode($this->_echash, $out);
foreach ($k AS $key => $val)
{
if (($key % 2) == 1)
{
$k[$key] = $this->insert_mod($val);
}
}
$out = implode('', $k);
}
error_reporting($this->_errorlevel);
$this->_seterror--;
echo $out;
}
function fetch($filename, $cache_id = '')
{
...
if (strncmp($filename,'str:', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}
else
{
...
$out = $this->make_compiled($filename); //$filename = C:/FakeD/Software/phpstudy/PHPTutorial/WWW/ecshop/themes/default/user_passport.dwt
...
}
return $out;
function make_compiled($filename)
{
$name = $this->compile_dir . '/' . basename($filename) . '.php';
...
if ($filestat['mtime'] <= $expires && !$this->force_compile)
{
if (file_exists($name))
{
$source = $this->_require($name); //$name = C:/FakeD/Software/phpstudy/PHPTutorial/WWW/ecshop/temp/compiled/user_passport.dwt.php
if ($source == '')
{
$expires = 0;
}
}
else
{
$source = '';
$expires = 0;
}
}
...
return $source;
}
function _require($filename)
{
ob_start();
include $filename;
$content = ob_get_contents();
ob_end_clean();
return $content;
}
回到display函数
if (strpos($out, $this->_echash) !== false)
{
$k = explode($this->_echash, $out);
foreach ($k AS $key => $val)
{
if (($key % 2) == 1)
{
$k[$key] = $this->insert_mod($val);
}
}
$out = implode('', $k);
}