伪随机数总结
windows与linux下的随机数生成机制不一样,如果给的是elf文件要求随机序列,需要在linux下编译
C
一般先设置种子srand(seed),之后调用rand函数;如果没有调用srand函数则默认seed为1
需要注意rand是有内部状态的伪随机数生成器,每调用一次rand,内部状态就会更新一次, 下一次rand会基于更新后的状态继续生成下一个数
动调获取随机序列
2024geek-flower
去除花指令后得到如下结果
尝试提取出前几个随机数0x1b,0x13,0x13,0x41
用c跑随机数发现和调试的不太一样
往后调试发现伪随机数相关的值和明文异或
且加密过程只有一步异或
1 | |
2024CISCN初赛-gdb_debug
伪随机数只取高位
加密逻辑:xor rand->交换下标->xor rand->xor string
按理seed生成的伪随机数会很大,与调试结果不符,这也就是题目要求我们调试的原因
一种思路是输入一个flag,得到密文之后xor得到rand1,rand3和ptr,当然可以一位位提取数据
看汇编去找把rax作为地址的内存,记住开始位置后直接跳出循环,全部提取,这题神奇的点在双击数组进去看不到密文
而需要在调试时看看寄存器的值找内存
1 | |
最后一位爆破即可:flag{78bace5989660ee38f1fd980a4b4fbcd}
还有一种方法是直接用时间戳,注意要在linux下运行
1 | |
个人比赛的时候就用了这种,但是rand2的生成循环写反了,以及rand1和rand3的位置没考虑
1 | |
爆破seed
2023春秋杯冬季赛-upx
原来upx小写改大写然后脱壳
双击v7按几次d就发现只是顺序变了
找到修改时间往前爆
1 | |
再通过python索引把位置换回来
1 | |
2024山东省省赛决赛rand
参考链接:https://mp.weixin.qq.com/s/3PZK2O2PftCqr2mS7vn5wA
Python
python中random库使用的是MT19937算法(梅森旋转算法),利用算法可以求出后随机数,前未知随机数,种子等,详见博客:https://lazzzaro.github.io/2020/11/07/crypto-%E6%B5%81%E5%AF%86%E7%A0%81/
1.利用seed初始化624个状态
2.对状态进行旋转
3.根据状态提取伪随机数
1 | |
有默认种子,由当前时间和操作系统提供的熵源例如urandom综合生成
1 | |
2021GKCTF-Random
如果能获取前624个32位的随机数,就能预测出后面全部32位的随机数
1 | |
random的随机数以32位为一个单位,所以如果要产生一个64位的随机数,则等价于一次产生两个32位随机数
本题中已知的随机数有104*(1+2+3)=624个,刚好满足能够预测的条件,需要预测出下一个
randcrack
1 | |
列举全部state的状态
1 | |
2023HITCTF邀请赛-random
数据:📎output.zip
1 | |
题目已知产生了2500个byte,一个byte是8位,也就是说4个byte组成一个32位随机数,2500/4=625>624,满足预测条件
1 | |