freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

CTF| web篇之伪随机数
2019-06-04 14:40:42

鉴于最近的CTF比赛中常出现关于mt_rand()伪随机函数的题目,本周斗哥就给大家讲解一下关于mt_rand()函数的问题。

mt_rand()工作原理:

这里引用一下php手册

mt_rand( void) : int

mt_rand( int $min, int $max) : int

很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。该函数用了 » Mersenne Twister 中已知的特性作为随机数发生器,它可以产生随机数值的平均速度比 libc 提供的 rand() 快四倍。

如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 mt_getrandmax() 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用 mt_rand(5, 15)。

提到了mt_rand()就要说一下mt_srand()函数:

mt_srand([ int $seed] ) : void

用 seed 来给随机数发生器播种。 没有设定 seed 参数时,会被设为随时数。使用者在进行一次mt_srand()操作后,seed数值将被固定下来,给接下来的mt_rand()函数使用。


mt_rand()存在的问题:

由于mt_rand()的生成的随机数只跟seed和调用该函数的次数有关。举一个简单的例子来说明一下这个问题,假设使用mt_srand(1111111)进行了一次播种操作,接下来调用mt_rand()函数,第一次生成的数值为a,第二次生成的为b,第三次生成的为c。任何一个人拿到这样的一串代码,所执行的结果都是跟刚刚描述的一样。所以当你的seed数值被他人知道后,就可以预测出你接下来的数值是多少,这就是该函数的一个问题,他并不能起到一个真随机数的作用。


seed的获取:

seed获取需要利用一个爆破工具。

https://github.com/lepiaf/php_mt_seed

下载后有这三个文件:

文件.webp.jpg

在linux中直接命令make就可以生成可执行文件。

执行.webp.jpg

php_mt_seed是一个可以根据一串int 或者一串由许多4个一组的数字组成(等下在说明)。

这里直接用这个工具页面里面的例子来说明。

直接.webp.jpg

上图就是直接由一串int数值来爆破的seed值,当然这样爆破出来的seed可能有多个,那么就需要你去验证一下。这种直接根据int数值来爆破是第一种方法。

第二种重点介绍一下:

重点.webp.jpg


这后面的一整串数值每四个为一组,中间以一个空格为间隔,前面两个数是随机数的结果区间,后两位是随机数的随机范围区间。具体如何获取这一串数值,等等将在例题中为大家解答。

以上2种都是直接获取seed的用法。


CTF原题:

就前段时间西湖论剑线上赛的web第一题题目就有利用到这个seed这个点,他的最后一步需要通过php_mt_seed这个工具来获取seed,然后flag存放于这个爆破出来的seed.txt文件夹中,对这题有兴趣的可以找找这个题目。

NJCTF也是一道很好的题目。

接下来讲一下SWPUCTF的其中一道web题目。

这些都是当初做的时候的截图了。

截图.webp.jpg

具体解法不赘述了,就来说一下整个题目的流程以及关于mt_rand函数的点。

首先注册登录会有一个15位的优惠码,但是优惠码全长为24位,也就是你需要预测出这个值,通过扫描发现了源码,下图就是跟本知识点有关的代码。

代码.webp.jpg

先分析一下代码,首先在开头通过一个rand随机获取了一个seed数值,然后采用优惠码的方法,该方法先将seed用作mt_srand()的参数,seed就是mt_srand()播种的种子,接下来每次调用的mt_rand()函数都会根据这个seed来生成数值,解题思路其实很明确,就是爆破到seed然后生成优惠码来完成。

优惠.webp.jpg

这个脚本是根据源码所写成的脚本,根据原来的生成规律来写的,源码中逻辑是前半段从左往右数X,拿1个字符,取完一半,从后半段从右往左数X,拿一个字符完成优惠码的生成。每次取字符的时候都会使用到mt_rand()来获取位置,也就是每次读取到的位置其实就是mt_rand()函数产生的数值,所以在脚本中用了strpos()函数来获取数值位置,返回的结果实际上就是mt_rand()生成的结果,根据php_mt_seed的格式生成了字符串,爆破得到seed。

seed.webp.jpg

得到seed后就可以将seed放入源码中的mt_srand(seed),得到24位优惠码,最后绕过正则得到flag。

flag.webp.jpg


小总结:

关于伪随基数的介绍就到这里啦!欢迎各位小伙伴们给斗哥留言探讨哇~

qrcode_for_gh_223e082fe8a7_430.jpg

# CTF # mt_rand()函数
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者