print("Thanks for using our encryption service! To get the start guessing, type 1. To encrypt a message, type 2.") print("You will need to guess the key (you get 250 guesses for one key). You will do this 3 times!")
for i inrange(3): seed = random.randint(0, 10 ** 6) print("Find the key " + str(i + 1) + " of 3!") key = encrypt(b"random text to initalize key")[0] whileTrue: print("What would you like to do (1 - guess the key, 2 - encrypt a message)?") user_input = int(input()) if(user_input == 1): break
print("What is your message?") message = input() key, ciphertext = encrypt(message.encode()) print("Here is your encrypted message:", ciphertext) print("You have 250 guesses to find the key!") found = False for j inrange(250): print("What is your guess (in hex)?") guess = str(input()).lower() if guess == key: print("You found the key!") found = True break else: print("That is not the key!")
ifnot found: print("You did not find the key!") exit(0)
flag = open('/src/flag.txt', 'r').read(); print("Here is the flag:", flag)
Seems similar to the first Numbers go brr challenge. However, in this one, we are not decrypting a flag, but instead finding a key 3 times in a row.
However, we can exploit the same nature of the encryption scheme in both challenges, i.e. the seed space is of size 10**6, which is small enough to brute force.
Essentially, for each seed we’re testing, we can first initialize the state of the key, given that one encryption is done immediately before we are allowed to do anything (for each iteration of the program’s for loop). Then, we can ask for an encryption of any plaintext. We can then use the same exact encrypt() function on our local machine to test if the ciphertext returned by the program matches up with our locally produced ciphertext. If it does, that means we have the right seed. At this point, after calling the encrypt() function on our local machine, it should have already updated the key to the right value, so all we need to do is submit that to get the flag!