PRNG Task
Solution
There are two ways to predict next numbers Mersenne Twister returns. The first is rebuilding its internal state using 624 integers. The second way is guessing the seed and guessing it shouldn’t be that hard, because source code we get tells us it’s rounded time.
Code:
import socket
import time
import random
import math
import datetime
= "challenges.ctfd.io"
HOST = 30264
PORT
def main():
= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = round(time.time() / 100, 5)
my_tm connect((HOST, PORT))
s.= []
srv_nums print("current time: %f" % my_tm)
= s.recv(4096).decode("UTF-8")
recvd while True:
if len(srv_nums) != 2:
"r\n")
s.sendall(b= s.recv(128).decode("UTF-8")
recvd = recvd[:recvd.find("\n")]
recvd int(recvd))
srv_nums.append(continue
break
print("bruteforcing seed")
print("searching for numbers:", srv_nums)
= False
flag_found print("displaying progress...\n")
= time.time()
work_begin
= round(my_tm - 30, 6)
my_tm while True:
random.seed(my_tm)= random.randint(1, 100000000)
my_rnd if my_rnd == srv_nums[0]:
print("found time seed: %f" % my_tm)
= random.randint(1, 100000000)
tmprng print(tmprng)
if tmprng != srv_nums[1]:
print("second number doesn't match, skipping")
= round(my_tm + 0.000001, 6)
my_tm continue
= True
flag_found break
= round(my_tm + 0.000001, 6)
my_tm if my_tm == float(math.floor(my_tm)):
print(int(my_tm))
= time.time()
work_end print("finished job in %s" % str(datetime.timedelta(seconds=work_end - work_begin)))
if not flag_found:
print("seed not found")
return
print("\nsubmitting the answer")
print("\nserver numbers")
for x in srv_nums:
print("| %i |" % x, end="")
print("")
"g\n");
s.sendall(b
= random.randint(1, 100000000)
first_rnd = s.recv(4096)
recvd print(recvd)
str(first_rnd).encode("utf-8") + b"\n")
s.sendall(print("sent first guess: %i" % first_rnd)
= random.randint(1, 100000000)
second_rnd = s.recv(4096)
recvd print(recvd)
str(second_rnd).encode("utf-8") + b"\n")
s.sendall(print("sent second guess: %i" % second_rnd)
while True:
= s.recv(4096).decode("utf-8")
recvd if not recvd:
break
print(recvd)
if __name__ == "__main__":
main()
We run it and get the flag:
16045235.553690
found time seed: 95870824
in 0:03:57.809325
finished job
submitting the answer
server numbers| 71504180 || 95870824 |
'Guess the next two random numbers for a flag!\nGood luck!\nEnter your first guess:\n> '
b94324429
sent first guess: "Wow, lucky guess... You won't be able to guess right a second time\nEnter your second guess:\n> "
b68431170
sent second guess: 's your flag:
What? You must have psychic powers... Well herenactf{ch000nky_turn1ps_1674973}
Flag
nactf{ch000nky_turn1ps_1674973}
Credits
License
CC BY 4.0 WaletSec + everl0stz