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