本文当中所有安全问题都将围绕parse_str()这个函数展开,parse_str函数在php 版本当中,在对变量进行解析过程中,有解码、以及变量后置等安全问题,这里不啰嗦,看问题。
任意密码重置:
在/phpcms/modules/member/index.php中account_manage_password方法
跟踪ps_member_edit 在phpcms/modules/member/classes/client.class.php中
继续跟踪_ps_send
直接发送到/index.php?m=phpsso&c=index&a=edit
继续跟踪_ps_post
继续上追踪到/phpsso_server/phpcms/modules/phpsso/index.php中
追踪到edit()方法
在追踪到该edit()函数之前,其中页面已经pc_base::load_app_class('phpsso', 'phpsso', 0);
调用了phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php对已加密的数据进行解密
其中该页面当中出现的漏洞即为。
关键点。。。
parse_str在php高版本当中在解析过程中会对编码进行一次解码,解析过程中会后续存在变量将会覆盖,如
username=111111&password=22222&username=33333,最终为username=33333,password=22222.
根据该特征:
1、通过引入%2527即可带入单引号,即产生注入,甚至getshell。
2、通过username=111111&password=22222&username=33333即可造成前面的变量覆盖,如达到任意用户密码重置
一、任意用户密码重置漏洞详细说明如下:
通过$_POST['info']['password']获取的变量设置为:
该值在经过parse_str解析前,应该是info[email]=test@qq.com&info[password]=test1234&info%5Bnewpassword%5D=test1234a%26username%3dtest12345
经过 if(isset($_POST['data'])) {
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
由于前面提到的username会覆盖。。。
在/phpsso_server/phpcms/modules/phpsso/index.php第15行中
$this->username = isset($this->data['username']) ? $this->data['username'] : '';
将会产生一个username的变量,即后面可控,即可控制任何人的用户名
在phpsso_server/phpcms/modules/phpsso/index.php中edit方法
这里即更改了不属于我们的用户test12345的密码了,这就是任意密码重置漏洞。
二、SQL注入漏洞详细说明如下(注入有多个,前台无需登录也有,会员中心也有):
注入主要是通过%2527经过2次解码进入数据库。。。
涉及SQL注入的方法有login \ public_checkname_ajax \ register \ account_manage_password …..等等,所以你会看到有好多好多的注入。。。哈哈,并且这些SQL注入还可以getshell,因为可以带入单引号进入写shell (前提你得有路径。不过phpcms也有报路径方法的,但是之前的爆路径的方法修复了。)
在这里只说明一处,其他的可以按照这个去发掘。。
我就说一下account_manage_password这个方法,其他的sql注入我就不一一爆了原理一样2次解码%2527带入单引号。。。
我们还是选取account_manage_password方法
我们设置newpassword (新密码)为test123456a%26username%3dtest12345%2527
如图:
其中username进入数据库
我们在mysql.class.php update方法将sql语句记录下来,无法直接回显,因为内部接口通信,所以你直接echo不出来的
UPDATE `phpcms`.`v9_sso_members` SET `appname`='phpcms v9',`email`='test12345d67@qq.com',`password`='8a58c2fcafc50bccb9b3b97c1871e31e',`random`='xcnhzq' WHERE `username` = 'test12345''
这个注入点也就是二次注入…..但是这个注入点不是回显的,知道为什么吗?
因为前面已经说了,看看client.class.php中的_ps_send方法(内部通信)
所以这个注入点不回显的,所以利用方式,你就是如何把他变回显,或者直接写shell,延时注入….
后面真正的poc就不再提供,杀人原理已经给出来,杀人工具不再造。。。如果你利用的好,直接sqlmap都可以跑数据,相信自己。。。。
总之围绕这个函数的安全问题就全部总结了,包括任意用户密码重置、SQL注入漏洞、xss、getshell等等