C#随机数生成器漏洞分析与利用
漏洞概述
在C#中,使用new Random().Next(min, max)
生成密码重置令牌存在严重安全风险。由于Random
类默认使用系统时钟(Environment.TickCount
)作为种子,在1毫秒时间窗口内创建的多个Random
实例将产生相同的随机数序列。
漏洞代码示例
|
|
C# PRNG工作原理
Random
类的参考实现显示,当无参构造函数被调用时:
|
|
内部状态(SeedArray[55]
)基于32位种子构建。所有PRNG输出都由其种子决定,在这种情况下,种子本质上是时间。
漏洞利用方法
单包攻击
利用Burp Suite的Repeater组功能,在1毫秒时间窗口内同时发送两个密码重置请求:
- 监控往返时间差异(显示在Burp右下角)
- 当时间差≤1毫秒时,两个账户将收到相同的重置令牌
- 通过测试账户验证漏洞存在后,针对管理员账户实施攻击
黑盒测试方法
- 创建两个测试账户
- 使用Burp Repeater同时发送重置请求
- 检查邮件中的令牌是否重复
- 确定有效的时间差窗口
- 在实际攻击中,仅当时间差在测试范围内时才尝试登录
修复方案
使用加密安全的随机数生成器:
|
|
数学逆向分析(进阶)
种子算法数学原理
SeedArray
中的操作都是在模MBIG
(Int32.MaxValue
,即2^31-1)下进行的,形成一个伽罗华域。
通过代数运算,可以将任何SeedArray
元素表示为:
|
|
csharp_rand.py库功能
该库能够:
- 预测
Random::Next
的输出 - 从输出反推原始种子
- 在不同输出间建立数学关系
示例:
|
|
整数下流问题
在特定种子值下,原始实现存在整数下流问题,导致某些输出存在"碰撞" - 两个不同的种子产生相同的第13个输出。
结论
这种攻击虽然简单,但危害严重。安全开发中应始终:
- 查阅文档了解API的安全使用方式
- 对安全关键操作使用加密安全的RNG
- 在实际环境中测试"安全"代码
- 对安全令牌进行模糊测试
该漏洞利用方法不仅适用于C#,也可能影响其他使用类似PRNG实现的编程语言和框架。