ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
Posted Learning is fun.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi相关的知识,希望对你有一定的参考价值。
1 // where子单元分析 2 protected function parseWhereItem($key,$val) { 3 $whereStr = ‘‘; 4 if(is_array($val)) { 5 if(is_string($val[0])) { 6 if(preg_match(‘/^(EQ|NEQ|GT|EGT|LT|ELT)$/i‘,$val[0])) { // 比较运算 7 $whereStr .= $key.‘ ‘.$this->comparison[strtolower($val[0])].‘ ‘.$this->parseValue($val[1]); 8 }elseif(preg_match(‘/^(NOTLIKE|LIKE)$/i‘,$val[0])){// 模糊查找 9 if(is_array($val[1])) { 10 $likeLogic = isset($val[2])?strtoupper($val[2]):‘OR‘; 11 if(in_array($likeLogic,array(‘AND‘,‘OR‘,‘XOR‘))){ 12 $likeStr = $this->comparison[strtolower($val[0])]; 13 $like = array(); 14 foreach ($val[1] as $item){ 15 $like[] = $key.‘ ‘.$likeStr.‘ ‘.$this->parseValue($item); 16 } 17 $whereStr .= ‘(‘.implode(‘ ‘.$likeLogic.‘ ‘,$like).‘)‘; 18 } 19 }else{ 20 $whereStr .= $key.‘ ‘.$this->comparison[strtolower($val[0])].‘ ‘.$this->parseValue($val[1]); 21 } 22 }elseif(‘exp‘==strtolower($val[0])){ // 使用表达式 23 $whereStr .= ‘ (‘.$key.‘ ‘.$val[1].‘) ‘; 24 }elseif(preg_match(‘/IN/i‘,$val[0])){ // IN 运算 25 if(isset($val[2]) && ‘exp‘==$val[2]) { 26 $whereStr .= $key.‘ ‘.strtoupper($val[0]).‘ ‘.$val[1]; 27 }else{ 28 if(is_string($val[1])) { 29 $val[1] = explode(‘,‘,$val[1]); 30 } 31 $zone = implode(‘,‘,$this->parseValue($val[1])); 32 $whereStr .= $key.‘ ‘.strtoupper($val[0]).‘ (‘.$zone.‘)‘; 33 } 34 }elseif(preg_match(‘/BETWEEN/i‘,$val[0])){ // BETWEEN运算 35 $data = is_string($val[1])? explode(‘,‘,$val[1]):$val[1]; 36 $whereStr .= ‘ (‘.$key.‘ ‘.strtoupper($val[0]).‘ ‘.$this->parseValue($data[0]).‘ AND ‘.$this->parseValue($data[1]).‘ )‘; 37 }else{ 38 throw_exception(L(‘_EXPRESS_ERROR_‘).‘:‘.$val[0]); 39 } 40 }else { 41 $count = count($val); 42 $rule = isset($val[$count-1])?strtoupper($val[$count-1]):‘‘; 43 if(in_array($rule,array(‘AND‘,‘OR‘,‘XOR‘))) { 44 $count = $count -1; 45 }else{ 46 $rule = ‘AND‘; 47 } 48 for($i=0;$i<$count;$i++) { 49 $data = is_array($val[$i])?$val[$i][1]:$val[$i]; 50 if(‘exp‘==strtolower($val[$i][0])) { 51 $whereStr .= ‘(‘.$key.‘ ‘.$data.‘) ‘.$rule.‘ ‘; 52 }else{ 53 $op = is_array($val[$i])?$this->comparison[strtolower($val[$i][0])]:‘=‘; 54 $whereStr .= ‘(‘.$key.‘ ‘.$op.‘ ‘.$this->parseValue($data).‘) ‘.$rule.‘ ‘; 55 } 56 } 57 $whereStr = substr($whereStr,0,-4); 58 } 59 }else { 60 //对字符串类型字段采用模糊匹配 61 if(C(‘DB_LIKE_FIELDS‘) && preg_match(‘/(‘.C(‘DB_LIKE_FIELDS‘).‘)/i‘,$key)) { 62 $val = ‘%‘.$val.‘%‘; 63 $whereStr .= $key.‘ LIKE ‘.$this->parseValue($val); 64 }else { 65 $whereStr .= $key.‘ = ‘.$this->parseValue($val); 66 } 67 } 68 return $whereStr; 69 }
第24行的preg_match(‘/IN/i‘,$val[0])
第34行的preg_match(‘/BETWEEN/i‘,$val[0])
两个正则表达式没有设置起始,因此xxxinxxxx,xxxbetweenxxx的字符串都可以匹配成功,因而构成了注入。
以上是关于ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi的主要内容,如果未能解决你的问题,请参考以下文章