网站地图    收藏   

主页 > 入门引导 > 黑客攻防 >

php云两处SQL二次注入 - 网站安全 - 自学php网

来源:未知    时间:2015-04-15 13:42 作者:xxadmin 阅读:

[导读] php云两处二次注入 最新版。两个注入点。顺带一个绕过waf的小技巧。 第一处:/member/model/index.class.php 39行 function index_action(){$this-public_action();$this-member_satic(); $this-com_cache();$resume = $this-...

php云两处二次注入

最新版。两个注入点。顺带一个绕过waf的小技巧。



第一处:/member/model/index.class.php



39行
 

function index_action()
{
$this->public_action();
$this->member_satic();
        $this->com_cache();
$resume = $this->obj->DB_select_once("resume","`uid`='".$this->uid."'");
$expect=$this->obj->DB_select_once("resume_expect","`id`='".$resume['def_job']."'");
if($_GET['type']=="job")
{
$where="`job_post` in (".$expect['job_classid'].") and `status`<>'1' and `state`='1' and `sdate`<'".mktime()."' and `r_status`<>'2' and `edate`>'".mktime()."'";
}elseif($_GET['type']=="city"){
$where="`cityid`='".$expect['cityid']."' and `status`<>'1' and `state`='1' and `sdate`<'".mktime()."' and `r_status`<>'2' and `edate`>'".mktime()."'";
}else{
$where="`state`='1' and status<>'1' and `sdate`<'".mktime()."' and `r_status`<>'2' and `edate`>'".mktime()."'";
}
$rows=$this->obj->DB_select_all("company_job",$where." order by id desc limit 12","`name`,`id`,`salary`,`edu`,`edate`");





where 语句拼接了$expect['job_classid'].变量。而这个变量来自于$expect=$this->obj->DB_select_once("resume_expect","`id`='".$resume['def_job']."'"); resume_expect 表。

member/model/index.class.php 587行

function saveexpect_action()

{
if($_POST['submit'])
{
$eid=(int)$_POST['eid'];
unset($_POST['submit']);
unset($_POST['eid']);
unset($_POST['urlid']);
$_POST['name'] = iconv("utf-8", "gbk", $_POST['name']);
$where['id']=$eid;
$where['uid']=$this->uid;
$_POST['lastupdate']=time();
if($eid=="")
{
$num=$this->obj->DB_select_num("resume_expect","`uid`='".$this->uid."'");
var_dump($num);
if($num>=$this->config['user_number'])
{
echo 1;die;
}
$_POST['uid']=$this->uid;
$nid=$this->obj->insert_into("resume_expect",$_POST);
if ($nid)
{




可以看到整个$_POST插入到了expect表中。完全是可控的。



测试过程。因为phpyun有两个waf,360就不说了。phpyun自带的依然可以白名单绕过。这里说一下自带的waf。



 

function gpc2sql($str,$str2) {


if(preg_match("/select|insert|update|delete|union|into|load_file|outfile/is", $str))
{
exit(safe_pape());
}
if(preg_match("/select|insert|update|delete|union|into|load_file|outfile/is", $str2))
{
exit(safe_pape());
}

$arr=array(" and "=>" an d "," or "=>" Or ","%20"=>" ","select"=>"Select","update"=>"Update","count"=>"Count","chr"=>"Chr","truncate"=>"Truncate","union"=>"Union","delete"=>"Delete","insert"=>"Insert","<"=>"&lt;",">"=>"&gt;","\""=>"&quot;","'"=>"&acute;","--"=>"- -");

foreach($arr as $key=>$v){
    $str = preg_replace('/'.$key.'/isU',$v,$str);
}
return $str;
}





这个函数直接过滤了select|insert|update|delete|union|into|load_file|outfile 关键字,$arr=array(" and "=>" an d "," or "=>" Or ","%20"=>" ","select"=>"Select","update"=>"Update","count"=>"Count","chr"=>"Chr","truncate"=>"Truncate","union"=>"Union","delete"=>"Delete","insert"=>"Insert","<"=>"&lt;",">"=>"&gt;","\""=>"&quot;","'"=>"&acute;","--"=>"- -"); 这里之前把%20替换为空。之前有人提的利用这里引入or关键字的方式就不可以了。这个过滤还是很变态的。所以这里尝试进行延时注入。



其中过滤sleep的正则是这样的:


sleep\s*?\\([\d\.]+?\\)




看了以前原来已经前辈发过了。 WooYun: 360webscan正则不当可被绕过进行SQL注入



sleep里面进行算数运算就可以了。这里说一下别的方法:



比如sleep((11)),多加一层括号,sleep((select 2)),等等。所以 WooYun: 360webscan正则不当可被绕过进行SQL注入 这里分析的改成benchmark这样也是不安全的。

benchmark\s*?\\(\d+?|sleep\s*?\\([\d\.]+?\\)





最彻底的就是sleep\s*?\(.*\)进行过滤。



最后说一下这里的利用过程。



首先登陆,post数据到数据库



 

选区_113.jpg




 

选区_114.jpg





访问一下url触发。
 

选区_116.jpg





所以这里实现的绕过也就是前辈说过的
如果我们想让服务器挂掉或者查询当前的数据库环境,很容易,我们可以很轻松的sleep或者获取当前运行的数据库信息了,这些不依赖select字符的事情我们都可以做了。





第二个点存在招聘会的地方,也是二次注入,写数据的时候需要后台审核。



企业预订的时候,抓包。

选区_118.jpg





修改GET /phpyun3.1/index.php?m=ajax&c=zphcom&uid=5&pid=1&jobid=2 HTTP/1.1

jobid为注入payload。

然后查看参会企业触发。只是默认情况下,企业申请需要管理员审核。

 

选区_119.jpg





相关代码:model/zph.class.php



23行:

function com_action()

{
$this->job_cache();
$row=$this->obj->DB_select_once("zhaopinhui","`id`='".(int)$_GET['id']."'");
$this->yunset("row",$row);
$where="`zid`='".(int)$_GET['id']."' and status='1'";
var_dump($where);
$urlarr["c"]=$_GET['c'];
$urlarr["id"]=$_GET['id'];
$urlarr["page"]="{{page}}";
$pageurl=$this->url("index",$_GET['m'],$urlarr,"1");
$rows=$this->get_page("zhaopinhui_com",$where."  order by id desc",$pageurl,"13");
if(is_array($rows)){
foreach($rows as $key=>$v){
$rows[$key]['comname']=$this->obj->get_comname($v['uid']);
$rows[$key]['job']=$this->obj->DB_select_all("company_job","id in (".$v['jobid'].") and `status`<>'1' and `r_status`<>'2'","name,id");
}
}




写数据的代码位于model/ajax.class.php894 line

 

function zphcom_action()
{
if(!$this->uid || !$this->username || $_COOKIE['usertype']!=2 || $this->uid!=$_GET['uid'])
{
$arr['status']=0;
$arr['content']=iconv("gbk","utf-8","您不是企业用户或者还没有登录,<a href='index.php?m=login&usertype=2'>请先登录</a>");
}elseif(!$_GET['pid']){
$arr['status']=0;
$arr['content']=iconv("gbk","utf-8","你没有选择招聘会");
}elseif(!$_GET['jobid']){
$arr['status']=0;
$arr['content']=iconv("gbk","utf-8","你还没有选择职位");
}elseif(is_array($this->obj->DB_select_once("zhaopinhui_com","uid='".(int)$_GET['uid']."' and zid='".(int)$_GET['pid']."'"))){
$arr['status']=0;
$arr['content']=iconv("gbk","utf-8","您已经参与该招聘会");
}else{
$jobidarr=@explode(",",$_GET['jobid']);
$array=array();
foreach($jobidarr as $v){
if(!in_array($v,$array)){
$array[]=$v;
}
}
$sql['uid']=$_GET['uid'];
$sql['zid']=$_GET['pid'];
$sql['jobid']=@implode(",",$array);
$sql['ctime']=mktime();
$sql['status']=0;
$id=$this->obj->insert_into("zhaopinhui_com",$sql);



 

选区_116.jpg

 

解决方案:

加强过滤

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论