gpt4 book ai didi

RNG Challenge Python(RNG挑战巨蟒)

转载 作者:bug小助手 更新时间:2023-10-25 13:55:01 26 4
gpt4 key购买 nike



I am trying to solve a CTF challenge in which the goal is to guess the generated number. Since the number is huge and you only have 10 attempts per number, I don't think you can apply binary search or any kind of algorithm to solve it, and that it has something to do with somehow getting the seed of the random function and being able to generate the next number, but I have no idea on where to start to get the correct seed. Do you have any idea?
Here's the code of the challenge:

我正在尝试解决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()


更多回答

The number 625 in the loop is interesting. Python's default PRNG is Mersenne Twister which maintains 624 words of state.

循环中的数字625很有趣。Python的默认PRNG是Mersenne Twister,它维护624个状态字。

Another issue is finding the exact algorithm details used by python's mersenne twister implementation. I'd hate to have to pour through hundreds of lines of C code trying to figure out what exactly is happening internally to get random.getrandbits(32) output. Also, if there is even a minor change to this implementation it could throw everything off.

另一个问题是找到python的mersenne twister实现所使用的确切算法细节。我不想要倾注成百上千行的C代码来弄清楚内部到底发生了什么,才能得到随机的.getRANDITS(32)输出。此外,如果对该实现进行哪怕是很小的更改,都可能会颠覆一切。

@KellyBundy: Given that it's a CTF and the FLAG is in plaintext in the code the answer has to be that it's run on some server out of the player's control. Similar to his previous question, standard input and standard output of the above program are connected to the two halves of a socket after you connect to the server with your CTF-solver program.

@KellyBundy:鉴于它是一个CTF,并且代码中的标志是纯文本的,答案肯定是它运行在玩家控制之外的某个服务器上。与他前面的问题类似,在使用CTF-solver程序连接到服务器后,上面程序的标准输入和标准输出连接到套接字的两个部分。

Yes, it comes from os.environ["FLAG"]. That's the from the environment of python program, which if it were somehow on your own PC would thus be available in plaintext.

是的,它来自os.environ[“FLAG”]。这是来自环境的Python程序,如果它以某种方式在您自己的PC上,那么它就会以明文形式提供。

优秀答案推荐

Don't try guessing the first 624 numbers, just give up on them. You're told what they were, feed them into randcrack as shown in its example. Ask it to predict the next 32-bit number and guess that.

不要试图猜测前624个数字,放弃它们。您将被告知它们是什么,将它们输入到Randcrack中,如其示例所示。让它预测下一个32位数字,然后猜出来。


For a bigger challenge, you could try it without that tool. Here's some insight, "predicting" the next number, i.e., showing how it's computed from the state:

对于更大的挑战,您可以在没有该工具的情况下尝试。下面是一些洞察力,“预测”下一个数字,即显示它是如何根据状态计算出来的:


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()

Sample output:

示例输出:


predict: 150999088
actual: 3825261045

predict: 457032747
actual: 457032747

predict: 667801614
actual: 667801614

predict: 3817694986
actual: 3817694986

predict: 816636218
actual: 816636218

First I get the state, which is 624 words of 32 bits and an index. The calculation of y is from here. The first number is wrong because in reality, the first time the more complicated code above it runs.

首先我得到状态,它是624个字的32位和一个索引。Y的计算是从这里开始的。第一个数字是错误的,因为在现实中,第一次运行上面的代码越复杂。


If you can figure out how to inverse those calculations, you could reconstruct the original state from the given first 624 numbers, then set that state with random.setstate, and generate the next number. The tool does seem to do that inversal, but it doesn't look trivial.

如果您知道如何反转这些计算,您就可以根据给定的前624个数字重建原始状态,然后使用随机设置.setState设置该状态,并生成下一个数字。该工具似乎确实做到了这一点,但它看起来并不微不足道。


更多回答

May I ask you if there is a paper or something I can check? I would like to try to understand what's the math behind it. Anyway, thank you for your answer :)

我可以问你有没有纸或什么我可以检查的东西?我想试着理解它背后的数学原理。无论如何,感谢您的回答:)

@Shark44 I don't know. I guess it would be reasonable to create a GitHub issue for randcrack, asking them to add documentation of how it works.

@Shark44我不知道。我想为Randcrack创建一个GitHub问题是合理的,要求他们添加如何工作的文档。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com