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, 云资产清单, 伪随机数, 域名收集, 多人体追踪, 安全测试, 密码学分析, 情报收集, 攻击性安全, 服务器监控, 漏洞研究, 种子破解, 符号执行, 算法还原, 线性同余生成器, 误配置预防, 逆向工具, 逆向工程, 随机数预测