当前位置:Gxlcms > 
数据库问题 > 
ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
                     
                    
                        ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
                        
                            时间:2021-07-01 10:21:17
                            帮助过:35人阅读
							                        
                     
                    
                    
                         // 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
标签:xor   rest   thinkphp   sse   throw   xxx   成功   pre   logic