PHPAPP是一款威客程序,前段时间看了一下,发现了一些问题。有一些已经提交到漏洞平台了,这里发一个没提交的。
漏洞文件:\phpapp\apps\pay\main_phpapp.php GoPayTool方法
function GoPayTool($payarr){
//检查支付工具
$paytoolid=$payarr['PayToolID']; //$paytoolid变量由$payarr获取,只要可控就存在宽字节SQL注入
if($this->IsSQL('pay_tool',"WHERE id_phpapp='$paytoolid'")){
if($payarr['Submit']){
include_once(APPS.'/pay/class/pay_class_phpapp.php');
$pay=new PayMoney($payarr,$paytoolid);
$pay->SetPayTools();
}
}else{
header('location:'.SURL);
}
\phpapp\apps\apppay\main_phpapp.php的OnLinePayAction方法调用了GoPayTool方法:
function OnLinePayAction(){
if($this->POST['PayMoney'] < PHPAPP::$config['pay_small_money']){
$this->Refresh(include $this->LanguageArray('apppay','Pay_is_too_low',1),'member.php?app=5&action=2');
}else{
include_once(APPS.'/pay/main_phpapp.php');
$pay=new PayMainControls();
$pay->GoPayTool($this->POST); //POST变量进入,可控</span>
}
}
我们再来看看$this->POST是怎么获取的:
$this->POST=$this->POSTArray();
跟进POSTArray()方法:
function POSTArray(){
$postarr=array();
if(is_array($_POST)){
foreach($_POST as $key=>$value){
$keyarr=explode('_',$key);
$count=count($keyarr);
if($count>1){
$keyname='';
for($i=0;$i<$count-1;$i++){
if($keyname){
$keyname.='_'.$keyarr[$i];
}else{
$keyname=$keyarr[$i];
}
}
if($keyarr[$count-1]=='s'){
$isajax=empty($_SERVER['HTTP_X_REQUESTED_WITH']) ? '' : $_SERVER['HTTP_X_REQUESTED_WITH'];
if($isajax=='XMLHttpRequest'){
$value=$this->ConvertStr($value);
}
$postarr[$keyname]=$this->str($value,0,1,0,0,0,1);
}elseif($keyarr[$count-1]=='d'){
$postarr[$keyname]=intval($value);
}elseif($keyarr[$count-1]=='f'){
$postarr[$keyname]=floatval($value);
}else{
$postarr[$key]=$value;
}
}else{
$postarr[$key]=$value;
}
}
}
return $postarr;
}
我们这里的POST变量分割成数组之后只有PayMoney_f变量经过了转换,PayToolID变量没有,这样就存在注入了(POSTArray()方法如果走到else的话就会有很多问题,这里的注入只是其中之一)。
利用方法:
注册用户登录前台,在线充值处注入:/phpapp/member.php?app=5&action=2