PHPCMS MT_RAND SEED CRACK致authkey泄露
雨。 漏洞分析 13256浏览 · 2017-10-10 01:35

正文

看到phpcms更新了, 看了下补丁, 分析了下他修复的漏洞。

这种漏洞在CTF中还是比较常见的, 实例我还是第一次遇到。

在INSTALL.PHP中

$cookie_pre = random(5, 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ').'_';
$auth_key = random(20, '1294567890abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');

在安装的时候, 用random来生成了cookie_pre 和 authkey,

function random($length, $chars = '0123456789') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

这里使用了mt_rand来生成chars的索引来生成authkey之类的。
mt_rand 在一个脚本中, 产生多个随机数的时候, 只播了一次种。
那么也就是mt_rand生成cookie_pre和authkey的种子是一样的。
cookie_pre从名字就能看出这个是cookie名称的前缀, 所以是可以拿到的, 那么只要用cookie_pre爆破到了种子的话, 那么也就是拿到了生成authkey的种子。
因为种子确定了的话, 产生的随机数序列就可以确定了, 也就是每次的索引可以确定了, 就可以拿到auth_key了。

首先看到 COOKIE_PRE 为 AZZBP

这里直接用下wonderkun大佬的脚本, 来获取一下cookie_pre的各个字符串在序列中的位置。

<?php 

$str = "AZZBP";
$randStr = "abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ";

for($i=0;$i<strlen($str);$i++){
   $pos = strpos($randStr,$str[$i]);
   echo $pos." ".$pos." "."0 ".(strlen($randStr)-1)." ";
   //整理成方便 php_mt_seed 测试的格式
  //php_mt_seed VALUE_OR_MATCH_MIN [MATCH_MAX [RANGE_MIN RANGE_MAX]]
}
echo "\n";

26 26 0 51 51 51 0 51 51 51 0 51 27 27 0 51 41 41 0 51

然后用MT_RAND SEED CRACKER来爆破一下种子。

然后把爆破到的种子, 用mt_srand设置一下种子, 再来获得随机数列, 就能拿到authkey了。
因为爆破到的种子会有多个。 就一个一个慢慢试了。

在试第三个种子的时候就拿到了正确的auth_key了。

拿到auth_key后 可以做的事情很多, 就不多说了。

修复方法

官方的已经修复了。

多次播种了, 那么根据cookie_pre拿到的种子和生成auth_key的种子是不一样的, 所以authkey生成的序列就不知道咯。

10 条评论
某人
表情
可输入 255
vulg****
2019-04-29 14:16 0 回复

@0r3ak 求雨牛大神的博客链接 表哥 可否告知下 谢谢了


hades
2017-10-10 17:29 0 回复

有些小地方还是有的玩~   


zxc
2017-10-10 17:21 0 回复

雨屌


0r3ak
2017-10-10 02:27 0 回复

不错,很早在雨牛的博客里面学习了这篇文章,是一个新思路,不仅仅是phpcms,包括很多类似的cms,开发在错误的将mt_rand()用来当作安全的随机数造成的悲剧。


cover
2017-10-15 19:32 0 回复

原理跟discuz 那个一模一样啊,只不过cooKie 前缀先生成


imp
2017-10-15 19:23 0 回复

我的好像是新版,他random函数也改了。。


imp
2017-10-15 19:16 0 回复

random函数里不是也有个mt_srand()吗

function random($length, $chars = '0123456789') {

    $hash = '';

    $max = strlen($chars) - 1;

    mt_srand();  //重点

    for($i = 0; $i < $length; $i++) {

        $hash .= $chars[mt_rand(0, $max)];

    }

    return $hash;

}


xiao_c
2017-10-15 17:36 0 回复

求告知雨牛的博客url


hades
2017-10-15 17:13 0 回复

已经修复咯~~


茜さす
2017-10-15 06:35 0 回复

雨牛,你的两张图片打错了,你博客就没问题的


目录