在cnvd看到了v1.1.9注入:

因为v1.1.8修复方式为:

$string = htmlspecialchars(trim($string), ENT_QUOTES);
$string = addslashes($string);

所以在v1.1.9中产生sql注入的原因可能就是没有单引号包裹造成的。

于是我下载了v1.1.9与v1.2.1两个版本,利用Beyond Compare 4工具来对比。(我也不知道我为啥要用这两个版本来对比,而不是v1.1.8与v1.1.9来对比,想到感觉差不多)

V1.1.9中的一处注入:

appsapicontrollerCmsController.php 中的search函数:

// 搜索 public function search() {
if (! $_POST) {
json(0, 请使用POST提交!);
}

$acode = get(acode) ?: $this->lg;
$num = get(num) ?: $this->config(pagesize);
$order = get(order) ?: date;

switch ($order) {
case date:
case istop:
case isrecommend:
case isheadline:
case visits:
case likes:
case oppose:
$order = $order . DESC;
break;
default:
$order = $order . ASC;
}
$order .= ",sorting ASC,id DESC";

// 获取主要参数 $field = post(field);
$keyword = post(keyword);
$scode = post(scode);

// 匹配单一栏位及关键字搜索方式 $where = array();
if ($field && $keyword) {
$where[$field] = $keyword;
} elseif ($keyword) {
$where[title] = $keyword;
}

// 数据处理 $cond = array(
d_source => post,
d_regular => /^[^s]+$/ );
foreach ($_POST as $key => $value) {
$where[$key] = filter($key, $cond);
if ($_POST[$key] && ! $where[$key]) {
json(0, 您的查询含有非法字元,已被系统拦截);
}
}

// 去除特殊键值 unset($where[keyword]);
unset($where[field]);
unset($where[scode]);
unset($where[page]);
unset($where[appid]);
unset($where[timestamp]);
unset($where[signature]);
unset($where2[from]);
unset($where2[isappinstalled]);

// 读取数据 $data = $this->model->getList($acode, $scode, $num, $order, $where);

可以看到:

$order = get(order) ?: date;

switch ($order) {
case date:
case istop:
case isrecommend:
case isheadline:
case visits:
case likes:
case oppose:
$order = $order . DESC;
break;
default:
$order = $order . ASC;
}
$order .= ",sorting ASC,id DESC";

这里的$order变数为get方式获取,除了单双引号反斜杠都可以引入(不知道这个get方法的,移步:bbs.ichunqiu.com/thread

然后传递进入了getList函数:

// 列表内容 public function getList($acode, $scode, $num, $order, $where = array()) {
....
return parent::table(ay_content a)->field($fields)
->where($where1, OR)
->where($where2)
->where($where, AND, AND, true)
->join($join)
->order($order) //$order变数又直接传入进了order方法。 ->page(1, $num)
->decode()
->select();
}
final public function order($order) {
if (is_array($order)) {
$order_string = ORDER BY ;
foreach ($order as $key => $value) {
if (is_int($key)) {
$order_string .= $value . ,;
} else {
$order_string .= $key . . $value . ,;
}
}
$this->sql[order] = substr($order_string, 0, - 1);
} else {
$this->sql[order] = ORDER BY . $order;
}
return $this;
}

看到最后第4行的:

$this->sql[order] = ORDER BY . $order;

直接将$order拼接了进去。所以造成了注入。

注意:这是需要开启api介面,默认关闭,所以对实战来说鸡肋。

weixin.qq.com/r/tigTC_L (二维码自动识别)

推荐阅读:

相关文章