提问人:Shark44 提问时间:9/10/2023 更新时间:9/11/2023 访问量:235
RNG 挑战赛 Python
RNG Challenge Python
问:
我正在尝试解决一个 CTF 挑战,其中的目标是猜测生成的数字。由于这个数字很大,每个数字只有 10 次尝试,我认为你不能应用二叉搜索或任何类型的算法来解决它,它与以某种方式获得随机函数的种子并能够生成下一个数字有关,但我不知道从哪里开始获得正确的种子。你有什么想法吗? 以下是挑战的代码:
#!/usr/bin/env python3
import signal
import os
import random
TIMEOUT = 300
assert("FLAG" in os.environ)
FLAG = os.environ["FLAG"]
assert(FLAG.startswith("CCIT{"))
assert(FLAG.endswith("}"))
def handle():
for i in range(625):
print(f"Round {i+1}")
guess_count = 10
to_guess = random.getrandbits(32)
while True:
print("What do you want to do?")
print("1. Guess my number")
print("2. Give up on this round")
print("0. Exit")
choice = int(input("> "))
if choice == 0:
exit()
elif choice == 1:
guess = int(input("> "))
if guess == to_guess:
print(FLAG)
exit()
elif guess < to_guess:
print("My number is higher!")
guess_count -= 1
else:
print("My number is lower!")
guess_count -= 1
elif choice == 2:
print(f"You lost! My number was {to_guess}")
break
if guess_count == 0:
print(f"You lost! My number was {to_guess}")
break
if __name__ == "__main__":
signal.alarm(TIMEOUT)
handle()
答:
4赞
Kelly Bundy
9/11/2023
#1
不要试图猜测前 624 个数字,放弃它们。你被告知它们是什么,将它们输入到 randcrack 中,如其示例所示。让它预测下一个 32 位数字并猜测。
对于更大的挑战,您可以在没有该工具的情况下尝试。这里有一些见解,“预测”下一个数字,即显示它是如何从状态计算出来的:
import random
for _ in range(5):
s = random.getstate()[1]
y = s[s[-1]]
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);
print('predict:', y)
print('actual: ', random.getrandbits(32))
print()
示例输出:
predict: 150999088
actual: 3825261045
predict: 457032747
actual: 457032747
predict: 667801614
actual: 667801614
predict: 3817694986
actual: 3817694986
predict: 816636218
actual: 816636218
首先,我得到状态,它是 624 个 32 位的字和一个索引。的计算是从这里开始的。第一个数字是错误的,因为在现实中,它上面更复杂的代码第一次运行。y
如果你能弄清楚如何反转这些计算,你可以从给定的前 624 个数字重建原始状态,然后用 设置该状态并生成下一个数字。该工具似乎确实可以反转,但它看起来并不微不足道。random.setstate
评论
0赞
Shark44
9/11/2023
请问你有没有可以检查的论文或东西?我想试着理解它背后的数学原理。无论如何,感谢您的回答:)
0赞
Kelly Bundy
9/11/2023
@Shark44我不知道。我想为 randcrack 创建一个 GitHub 问题是合理的,要求他们添加有关其工作原理的文档。
上一个:CTF 挑战中的堆栈布局
评论
random.getrandbits(32)
os.environ["FLAG"]