doyensec/csharp_rand_py
GitHub: doyensec/csharp_rand_py
这是一个用于安全测试的 Python 库,通过将 C# Random 类的输出建模为符号方程,实现随机数预测和种子反推。
Stars: 3 | Forks: 0
# C# Random 利用库
这是一个替代性的、绝大部分等效的 C# `Random::Next` 重新实现。
其工作原理是将所有内容保留在形式为 `a * Seed + b mod p` 的方程中。
你可以对这些方程针对任意 `Seed` 进行 `resolve`(求解),以获得某些 `(new Random(Seed).Next...)` 的输出。
你可以对这些方程进行代数运算,以发现其他更复杂的情况。
这些方程可以轻松移植到其他语言。只需确保使用 64 位数学运算。使用 32 位整数很可能会溢出,并且与模 `2**31 - 1` 不同余。
# 示例
获取能表示任意 `Seed` 的 `Random::Next` 第一次输出的方程。
```
>>> from csharp_rand import csharp_rand
>>> cs = csharp_rand()
>>> first = cs.sample_equation(0)
>>> print(first)
rand = seed * 1121899819 + 1559595546 mod 2147483647
```
然后运行 `.resolve(42)` 将对应于 `(new Random(42)).Next()` 的输出。
```
>>> first.resolve(42)
1434747710
```
或者你可以使用 `.invert()` 进行逆向运算,从而得到 `Seed`。
```
>>> first.invert().resolve(1434747710)
42
```
更复杂的例子,从第 725 次 `Random` 输出获取第 726 次输出。
```
>>> late = 724 # 725th rand, zero indexed
>>> late_rand = cs.sample_equation(late)
>>> late_rand_plus = cs.sample_equation(late + 1)
>>> late_to_late_plus = late_rand_plus(late_rand.invert())
>>> # check for seed 42
>>> late_to_late_plus.resolve(late_rand.resolve(42)) == late_rand_plus.resolve((42))
True
>>> print(late_to_late_plus)
rand = seed * 1971396503 + 1990619591 mod 2147483647
```
所以 `late_rand` 表示调用 `.Next` 725 次后的输出。然后 `late_rand_plus` 是第 726 次。由于这两者共享相同的 `Seed`,我们可以对 `late_rand` 求逆并与 `late_rand_plus` 组合,从而得到从第 725 次 `.Next` 到第 726 次 `.Next` 的方程。
我们可以通过将 `late_to_late_plus` 和 `late_rand.invert()` 方程复制到 .NET [演练场](https://dotnetfiddle.net/PLLcyC) 来进行检查。
```
using System;
public class Program
{
// next two equations take from python csharp library
private static int check(long seed) {
long ret = (seed * 1971396503 + 1990619591) % 2147483647;
return (int)ret;
}
private static int invert(long rand) {
long ret = (rand * 1433598513 + 1157387419) % 2147483647;
return (int)ret;
}
private static bool test(int Seed) {
Console.WriteLine("Testing Seed {0}: ", Seed);
var late = 724;
var prng = new Random(Seed);
for (int i = 0; i < late; i++) {
prng.Next();
}
var first = prng.Next();
var second = prng.Next();
var c = check(first);
Console.WriteLine(" Random[{0}]: {1}", late, first);
Console.WriteLine(" Random[{0}]: {1}", late + 1, second);
Console.WriteLine(" Computed: {0}", c);
Console.WriteLine(" Computed seed: {0}", invert(first));
if (c == second) {
Console.WriteLine(" Success");
return true;
}
Console.WriteLine(" Failed");
return false;
}
public static void Main() {
for (int i = 278; i < 291; i++) {
test(i);
}
}
}
```
输出:
```
Testing Seed 278:
Random[724]: 1558502570
Random[725]: 827201365
Computed: 827201365
Computed seed: 278
Success
Testing Seed 279:
Random[724]: 1583339083
Random[725]: 1435417286
Computed: 1435417286
Computed seed: 279
Success
...
```
标签:LCG, PRNG, 云资产清单, 伪随机数, 域名收集, 多人体追踪, 安全测试, 密码学分析, 情报收集, 攻击性安全, 服务器监控, 漏洞研究, 种子破解, 符号执行, 算法还原, 线性同余生成器, 误配置预防, 逆向工具, 逆向工程, 随机数预测