对JavaScript中的Math.random随机函数破解
创始人
2024-01-31 07:28:52
0

什么是随机

在这里插入图片描述

在通常的说法中,随机性是指事件中明显实际缺乏可预测性,事件、符号或步骤的随机序列通常没有顺序

举个例子,比如我们在抛硬币,硬币的结果取决于很多因素,比如说我们施加的力,空气阻力,引力等,但是如果我们知道影响硬币的所有因素,并且知道这些因素准确的值,我们就能预测硬币落下时,是正面还是反面

伪随机

假如我们有一个算法,我们给他设置一个初始值,然后用这个算法生成下一个数字,然后再用生成的这个数字继续生成下一个……

12 --------> 30 --------> 57 --------> 33

这个初始值被称之为seed(种子),过段时间后我们可以得到一组相同的数字,这个过程叫做周期,周期越大,说明我们的算法越好,这种随机数生成的算法被称之为伪随机,它不是真正的随机生成

伪随机生成器通常用于游戏中,比如角色一开始生成的地方,但是不会用于密码学中,因为在一定条件下,伪随机生成器是可以被破解的

Math.random

在JavaScript中,有一个叫Math.random随机生成的函数,他是一个原生的函数,几乎所有的JavaScript框架都包含这个函数

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

在这里插入图片描述

Math.random函数会返回一个大于0且小于1的浮点伪随机数,chrome浏览器也用的是JavaScript,并且包含了这个函数,他们使用的算法是v8

而v8是开源的,并且是由google进行维护的

ht#tps://github.com/v8/v8/tree/7a4a6cc6a85650ee91344d0dbd2c53a8fa8dce04
htt#ps://v8.dev/blog/math-random

在这里插入图片描述

在这里插入图片描述

可以发现有一个xorshift128+的算法,现在我们去看看math.random函数的源代码

在这里插入图片描述

static inline void XorShift128(uint64_t* state0, uint64_t* state1) {uint64_t s1 = *state0;uint64_t s0 = *state1;*state0 = s0;s1 ^= s1 << 23;s1 ^= s1 >> 17;s1 ^= s0;s1 ^= s0 >> 26;*state1 = s1;}

看起来并不复杂,只是一些异或操作和移位的操作,这个函数将state0和state1变成s0和s1,然后s1进行了异或和移位

我们不用对整个算法进行理解然后再去破解它,因为我们可以用z3这个smt求解器

z3

在这里插入图片描述

z3是由微软公司开发的smt求解器,我们可以将问题作为方程式列出,然后指定约束,z3就可以自动的解决这个问题

比如下面这个方程式

x + 2y = 7

我们可以使用z3来帮助我们计算x和y的值

from z3 import *x = Int('x')
y = Int('y')
solve(x + 2*y == 7) 

在这里插入图片描述

我们还可以用z3进行逻辑推理,弱哈希破解,数独……

对Math.random函数破解

在这里插入图片描述

首先,我们用z3创建64位的占位符值,因为xorshift128有两个状态,所以我们将这两个状态设置为占位符变量

solver = z3.Solver()
se_state0, se_state1 = z3.BitVecs("se_state0 se_state1", 64)

然后我们还需要从v8生成的随机值进行运算,我们按下f12,进入控制台,输入以下代码,随机生成五个数

Array.from(Array(5), Math.random)

在这里插入图片描述

把这五个数放到我们的脚本里,遍历这五个随机数

sequence = [0.6199046082820001, 0.6623637813965961, 0.7190181683749095, 0.06169296721449724, 0.915799780594273]
sequence = sequence[::-1]

然后我们将v8 xorshift128算法的源代码复制过来,做一些改动

在这里插入图片描述

for i in range(len(sequence)):se_s1 = se_state0   #用占位符值替换状态se_s0 = se_state1   #用占位符值替换状态se_state0 = se_s0   se_s1 ^= se_s1 << 23se_s1 ^= z3.LShR(se_s1, 17)  #设置逻辑移位而不是算数移位se_s1 ^= se_s0se_s1 ^= z3.LShR(se_s0, 26)se_state1 = se_s1

然后还需要写一些代码来进行运算

	float_64 = struct.pack("d", sequence[i] + 1) #然后获取 se_state0的值并用struct模块把它变成双精度的值u_long_long_64 = struct.unpack("

在v8里,还有一个函数叫做todouble,它的作用是转换,我们将这个源代码也放入我们的脚本

在这里插入图片描述

	state0 = states["se_state0"].as_long()u_long_long_64 = (state0 >> 12) | 0x3FF0000000000000float_64 = struct.pack("

现在我们就有一个可以破解Math.random函数的脚本了

脚本完全代码

#!/usr/bin/python3
import z3,struct,syssequence = [0.6199046082820001, 0.6623637813965961, 0.7190181683749095, 0.06169296721449724, 0.915799780594273]sequence = sequence[::-1]
solver = z3.Solver()
se_state0, se_state1 = z3.BitVecs("se_state0 se_state1", 64)for i in range(len(sequence)):se_s1 = se_state0se_s0 = se_state1se_state0 = se_s0se_s1 ^= se_s1 << 23se_s1 ^= z3.LShR(se_s1, 17)se_s1 ^= se_s0se_s1 ^= z3.LShR(se_s0, 26)se_state1 = se_s1float_64 = struct.pack("d", sequence[i] + 1)u_long_long_64 = struct.unpack("> 12) | 0x3FF0000000000000float_64 = struct.pack("

运行这个脚本,获得下一个随机数

在这里插入图片描述

在这里插入图片描述

成功正确预测了下一个随机数

相关内容

热门资讯

“剪辑拼接没影响他当选”,BB... 【文/观察者网 陈思佳】上个月,美国总统特朗普正式就英国广播公司(BBC)剪辑拼接其讲话一事提起诉讼...
“京西法律智谷”打造全生命周期... 央广网北京1月13日消息(记者 庞婷)某生物医药公司突遭合作方提起专利侵权诉讼,面临千万元索赔与研发...
把制度优势转化成治理效能 最高法举行座谈会征求有关单位意见 张军强调 在党中央坚强领导下合力推进法治建设 “审判工作高质量发展...
日照建设全国首个“四入”数智监... 齐鲁晚报·齐鲁壹点记者 杨璐 如何更好推动地方性法规从“纸面”落到“地面”? 1月13日,山东省人大...
认罪认罚后,为何获不起诉?检察... 极目新闻通讯员 曾娟 夏秋怡 “谢谢检察官,多亏了你们细致审查,我才没有稀里糊涂地背负罪名!”近日,...
司法局副局长受贿844万获刑,... 去年11月,山东曲阜市人民法院作出刑事判决,济宁市司法局原副局长国庆启因犯贪污罪、受贿罪,被判处有期...
【福贡大队】酒后滋事接连上演 ... 接连两日,匹河边境派出所先后调解了两起因饮酒引发的冲突事件,涉事双方虽最终在民警的调解下达成和解,但...
私!贪!狂!洪礼和三个字总结自... 由中央纪委国家监委宣传部与中央广播电视总台央视联合摄制的电视专题片《一步不停歇 半步不退让》,1月1...
李亚鹏发声!拖欠房租遭起诉,嫣... 1月13日下午,@北京嫣然天使儿童医院 发布“北京市朝阳区嫣然天使儿童医院关于房租债务的回应”。 回...