当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-064310

漏洞标题:PHPYUN最新版SQL注入二处(绕过防御)

相关厂商:php云人才系统

漏洞作者: xfkxfk

提交时间:2014-06-10 12:47

修复时间:2014-09-08 12:48

公开时间:2014-09-08 12:48

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-06-10: 细节已通知厂商并且等待厂商处理中
2014-06-10: 厂商已经确认,细节仅向厂商公开
2014-06-13: 细节向第三方安全合作伙伴开放
2014-08-04: 细节向核心白帽子及相关领域专家公开
2014-08-14: 细节向普通白帽子公开
2014-08-24: 细节向实习白帽子公开
2014-09-08: 细节向公众公开

简要描述:

PHPYUN最新版(phpyun_v3.1.0604_gbk)SQL注入二处,无视GPC(绕过防御)

详细说明:

PHPYUN最新版(phpyun_v3.1.0604_gbk)SQL注入二处
第一处SQL注入:
文件/member/model/com.class.php

function job(){
if($_GET['p_uid']){
$data['p_uid']=(int)$_GET['p_uid'];
$data['inputtime']=mktime();
$data['c_uid']=$this->uid;
$data['usertype']=$_COOKIE['usertype'];
$haves=$this->obj->DB_select_once("blacklist","`p_uid`=".$data['c_uid']." and `c_uid`=".$data['c_uid']." and `usertype`=".$data['usertype']."");
if(is_array($haves)){
$this->obj->layer_msg("该用户已在您黑名单中!",8,0,$_SERVER['HTTP_REFERER']);
}else{
$nid=$this->obj->insert_into("blacklist",$data);
$num=$this->obj->DB_select_num("userid_job","`uid`=".$data['p_uid']." and `com_id`=".$data['c_uid']."");
$this->obj->DB_delete_all("userid_job","`uid`=".$data['p_uid']." and `com_id`=".$data['c_uid'].""," ");
$this->obj->DB_update_all("member_statis","`sq_jobnum`=`sq_jobnum`-$num","`uid`='".$data['p_uid']."'");
$nid?$this->layer_msg('删除成功!',9,0,$_SERVER['HTTP_REFERER']):$this->layer_msg('删除失败!',8,0,$_SERVER['HTTP_REFERER']);
}
}


$data['usertype']=$_COOKIE['usertype'];
这里没有经过任何包含直接进入了DB_select_once
跟进DB_select_once函数:

function DB_select_once($tablename, $where = 1, $select = "*") {
$cachename=$tablename.$where;
if(!$return=$this->Memcache_set($cachename)){
$SQL = "SELECT $select FROM " . $this->def . $tablename . " WHERE $where limit 1";
$query = $this->db->query($SQL);
$return=$this->db->fetch_array($query);
$this->Memcache_set($cachename,$return);
}
return $return;
}


依然没有处理,所以,这里导致注入。
第二处SQL注入
文件/member/model/com.class.php

function job(){
......
if($_GET['r_uid']){
if($_GET['r_reason']=="")
{
$this->obj->ACT_layer_msg("举报内容不能为空!",8,"index.php?c=down");
}
$data['p_uid']=(int)$_GET['r_uid'];
$data['inputtime']=mktime();
$data['c_uid']=$this->uid;
$data['eid']=$_GET['eid'];
$data['r_name']=$_GET['r_name'];
$data['usertype']=$_COOKIE['usertype'];
$data['username']=$this->username;
$data['r_reason']=$_GET['r_reason'];
$haves=$this->obj->DB_select_once("report","`p_uid`=".$data['p_uid']." and `c_uid`=".$data['c_uid']." and `usertype`=".$data['usertype']."","id");
if(is_array($haves))
{
$this->obj->ACT_layer_msg("您已经举报过该用户!",8,"index.php?c=down");
}else{
$nid=$this->obj->insert_into("report",$data);
$nid?$this->obj->ACT_layer_msg("操作成功!",9,"index.php?c=down"):$this->obj->ACT_layer_msg("操作失败!",8,"index.php?c=down");
}
}


也是$data['usertype']=$_COOKIE['usertype'];
没有经过任何保护,直接进入了SQL语句
因为PHPYUN使用了360webscan的规则等一些防御措施
文件/data/db.safety.php:

function gpc2sql($str) {
if(preg_match("/select|insert|update|delete|union|into|load_file|outfile/is", $str))
{
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");
foreach($arr as $key=>$v){
$str = preg_replace('/'.$key.'/isU',$v,$str);
}
return $str;
}
function safesql($StrFiltKey,$StrFiltValue,$type){

$getfilter = "\\<.+javascript:window\\[.{1}\\\\x|<.*=(&#\\d+?;?)+?>|<.*(data|src)=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\\(\d+?|sleep\s*?\\([\d\.]+?\\)|load_file\s*?\\()|<[a-z]+?\\b[^>]*?\\bon([a-z]{4,})\s*?=|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
$postfilter = "<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\\(\d+?|sleep\s*?\\([\d\.]+?\\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover)\\b|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
$cookiefilter = "benchmark\s*?\\(\d+?|sleep\s*?\\([\d\.]+?\\)|load_file\s*?\\(|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT(\\(.+\\)|\\s+?.+?)|UPDATE(\\(.+\\)|\\s+?.+?)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?)FROM(\\(.+\\)|\\s+?.+?)|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";


像 and 1=1等这些会被过滤
那么使用/**/and 1+1=1和/**/and 1+1=2就能搞定了

漏洞证明:

我们以第二个SQL注入为例:
通过代码逻辑我们知道,当返回错误时,进入insert_into操作,会返回信息:“操作成功!”或者“操作成功!”

1.png


3.png


当返回为真时,会返回信息:“您已经举报过该用户!”

2.png


通过一直遍历char值得到user()的第一位字符为r
继续遍历得到user()=root

修复方案:

过滤,引号保护

版权声明:转载请注明来源 xfkxfk@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2014-06-10 12:49

厂商回复:

感谢您的支持,我们会尽快修复!

最新状态:

暂无