在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 (二維碼自動識別)

推薦閱讀:

相關文章