freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

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

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()函数
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者