一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Ecmall最新SQL注射漏洞分析

时间:2014-04-06 编辑:简简单单 来源:一聚教程网

你的域名/index.php 土淘网
用的Ecmall的建站模板,用过这个模板的应该都通杀了吧
存在搜索框注入,注入点为:
你的域名/index.php?app=store&act=search&id=45&keyword=aaa&min_price=100&max_price=10000
首先将获取get传来的参数,然后组合到一个sql查询语句condition中:
1.search.app.php中的这段代码就是构建查询min和max价格的sql代码,没有过滤:

 代码如下 复制代码

/**

 * 取得查询条件语句

 *

 * @param   array   $param  查询参数(参加函数_get_query_param的返回值说明)

 * @return  string  where语句

 */

function _get_goods_conditions($param)

{

/* 组成查询条件 */

$conditions = " g.if_show = 1 AND g.closed = 0 AND s.state = 1"; // 上架且没有被禁售,店铺是开启状态,

if (isset($param['keyword']))

{

$conditions .= $this->_get_conditions_by_keyword($param['keyword'], ENABLE_SEARCH_CACHE);

}

if (isset($param['cate_id']))

{

$conditions .= " AND g.cate_id_{$param['layer']} = '" . $param['cate_id'] . "'";

}

if (isset($param['brand']))

{

$conditions .= " AND g.brand = '" . $param['brand'] . "'";

}

if (isset($param['region_id']))

{

$conditions .= " AND s.region_id = '" . $param['region_id'] . "'";

}

if (isset($param['price']))

{

$min = $param['price']['min'];

$max = $param['price']['max'];

$min > 0 && $conditions .= " AND g.price >= '$min'";

$max > 0 && $conditions .= " AND g.price <= '$max'";

}

return $conditions;

}
2.下面这部分代码是query执行部分,直接将上面的参数带入查询了:
/* 按价格统计 */

if ($total_count > NUM_PER_PAGE)

{

$sql = "SELECT MIN(g.price) AS min, MAX(g.price) AS max FROM {$table} WHERE" . $conditions;

$row = $goods_mod->getRow($sql);

$min = $row['min'];

$max = min($row['max'], MAX_STAT_PRICE);

$step = max(ceil(($max - $min) / PRICE_INTERVAL_NUM), MIN_STAT_STEP);

$sql = "SELECT FLOOR((g.price - '$min') / '$step') AS i, count(*) AS count FROM {$table} WHERE " . $conditions . " GROUP BY i ORDER BY i";

$res = $goods_mod->db->query($sql);

while ($row = $goods_mod->db->fetchRow($res))

{

$data['by_price'][] = array(

'count' => $row['count'],

'min'   => $min + $row['i'] * $step,

'max'   => $min + ($row['i'] + 1) * $step,

);

}

}

}

利用另一个文件来注入

缺陷文件:/app/coupon.app.php

 代码如下 复制代码

function extend()

{

    $coupon_id = isset($_GET['id']) ? trim($_GET['id']) : '';

    if (empty($coupon_id))

    {

        echo Lang::get('no_coupon');

        exit;

    }

    if (!IS_POST)

    {

        header("Content-Type:text/html;charset=" . CHARSET);

        $this->assign('id', $coupon_id);

        $this->assign('send_model', Lang::get('send_model'));

        $this->display("coupon_extend.html");

    }

    else

    {

        if (empty($_POST['user_name']))

        {

            $this->pop_warning("involid_data");

            exit;

        }

        $user_name = str_replace(array("r","rn"), "n", trim($_POST['user_name']));

        $user_name = explode("n", $user_name);

        $user_mod =&m ('member');

        $users = $user_mod->find(db_create_in($user_name, 'user_name'));

        if (empty($users))

        {

            $this->pop_warning('involid_data');

            exit;

        }

        if (count($users) > 30)

        {

            $this->pop_warning("amount_gt");

            exit;

        }

        else

        {

            $users = $this->assign_user($coupon_id, $users);

            $store = $this->_store_mod->get_info($this->_store_id);

            $coupon = $this->_coupon_mod->get_info($coupon_id);

            $coupon['store_name'] = $store['store_name'];

            $coupon['store_id'] = $this->_store_id;

            $this->_message_to_user($users, $coupon);

            $this->_mail_to_user($users, $coupon);

            $this->pop_warning("ok","coupon_extend");

        }

    }

}
首先是coupon_id只过滤了空格,随后在else语句里进入了get_info函数:
function get_info($id)

{

    $goods = $this->get(array(

        'conditions' => "goods_id = '$id'",

        'join'       => 'belongs_to_store',

        'fields'     => 'this.*, store.state'

    ));

... 省略
读过代码的就知道了,其实上面的conditions之类的都是拼接成SQL语句最终要进入数据库的。
所以注射产生
POST index.php?app=coupon&act=extend&id=1[exp]

data:user_name=test(当前已经登录的用户名)


注意:文章只告诉各位有什么bug,让各位站长及时补上哦,并且本文章只供学习使用,一切后果与本站无关。

热门栏目