种子爆破&[GWCTF 2019]枯燥的抽奖

伪随机数的爆破,种子爆破

做到了一道题,就是有个伪随机数爆破的漏洞,当时尽管是看到了这两个敏感的函数,但是先去看其他的了,没有看到什么漏洞,所以我当时是准备直接强行爆破,之后看到使用伪随机数爆破的方式来做题。

mt_scrand():mt_srand播种 Mersenne Twister 随机数生成器。
mt_rand():mt_rand 使用 Mersenne Twister 算法返回随机整数。  

<?php
echo(mt_rand());    #3150906288
echo(mt_rand());    #513289678
echo(mt_rand(10,100));   #35
?>  

<?php
mt_srand(mktime());
echo(mt_rand());   #1132656473
?>

每一次调用mtrand()函数的时候,都会检查一下系统有没有播种。(播种是由mtsrand()函数完成的),当随机种子生成后,后面生成的随机数都会根据这个随机种子生成。

<?php
mt_srand(22332233);
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";
echo mt_rand()."<br/>";

output:

900961484<br/>
1627307390<br/>
1924937608<br/>
1013625438<br/>、
382930313<br/>

结果永远都是这么几个数,这样就有了破解的可行性。
对于计算机的运算能力应该也就几分钟吧。

昨天做到了一道题,可以当做例子,[GWCTF 2019]枯燥的抽奖:

<?php
#这不是抽奖程序的源代码!不许看!
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";

这里其实就是mt_rand的应用,表面上输出的是字母,但还是根据数字来截断的,即第几位。

if(!isset($_SESSION['seed'])){
    $_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);
echo '             ';
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    echo mt_rand(0, strlen($str_long1));
    echo '             ';

}  

在这里都看得到,output:

55 36 1 35 41 31 49 9 31 40 22 52 1 36 21 40 38 56 14 58 这里根据substr函数截取相应的位数字母。
生成我们最终的密码,这里是提供给了我们前十个字符。

我们需要用脚本将他转换一下变成数字,能够被我们工具所利用的:

str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='zOHF0Cxp49'
str3 = str1[::-1]
length = len(str2)
res=''
for i in range(len(str2)):
    for j in range(len(str1)):
        if str2[i] == str1[j]:
            res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' '
            break
print res

根据phpmtseed手册,我们将这段数字放入就能开始自动爆破了。
得到了种子一切就都好说了:

<?php
mt_srand(819101489);

$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
    $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);       
}
echo $str;

?>
原文地址:https://www.cnblogs.com/ophxc/p/13062028.html