# TJCTF 2025 Đề bài: ```python= #!/usr/local/bin/python import random import base64 import sys import select class User: def __init__(self, username): self.username = username self.key = self.get_key() self.message = None def get_key(self): username = self.username num_bits = 8 * len(username) rand = random.getrandbits(num_bits) rand_bits = bin(rand)[2:].zfill(num_bits) username_bits = ''.join([bin(ord(char))[2:].zfill(8) for char in username]) xor_bits = ''.join([str(int(rand_bits[i]) ^ int(username_bits[i])) for i in range(num_bits)]) xor_result = int(xor_bits, 2) shifted = ((xor_result << 3) & (1 << (num_bits + 3)) - 1) ^ 0x5A byte_data = shifted.to_bytes((shifted.bit_length() + 7) // 8, 'big') key = base64.b64encode(byte_data).decode('utf-8') return key def set_message(self, message): self.message = message def input_with_timeout(prompt="", timeout=10): sys.stdout.write(prompt) sys.stdout.flush() ready, _, _ = select.select([sys.stdin], [], [], timeout) if ready: return sys.stdin.buffer.readline().rstrip(b'\n') raise Exception input = input_with_timeout flag = 'a'*30 assert len(flag)%3 == 0 flag_part1 = flag[:len(flag)//3] flag_part2 = flag[len(flag)//3:2*len(flag)//3] flag_part3= flag[2*len(flag)//3:] admin1 = User("Admin001") admin2 = User("Admin002") admin3 = User("Admin003") admin1.set_message(flag_part1) admin2.set_message(flag_part2) admin3.set_message(flag_part3) user_dict = { "Admin001": admin1, "Admin002": admin2, "Admin003": admin3 } print("Welcome!") logged_in = None user_count = 3 MAX_USERS = 200 while True: if logged_in is None: print("\n\n[1] Sign-In\n[2] Create Account\n[Q] Quit") inp = input().decode('utf-8').strip().lower() match inp: case "1": username = input("Enter your username: ").decode('utf-8') if username in user_dict: user = user_dict[username] key = input("Enter your sign-in key: ").decode('utf-8') if key == user.key: logged_in = user print(f"Logged in as {username}") else: print("Incorrect key. Please try again!") else: print("Username not found. Please try again or create an account.") case "2": if user_count >= MAX_USERS: print("Max number of users reached. Cannot create new account.") else: username = input("Select username: ").decode('utf-8') if username in user_dict: print(f"Username '{username}' is already taken!") else: user_dict[username] = User(username) user_count += 1 print(f"Account successfully created!\nYour sign-in key is: {user_dict[username].key}") case "q": sys.exit() case _: print("Invalid option. Please try again.") else: print(f"Welcome, {logged_in.username}!") print("\n\n[1] View Message\n[2] Set Message\n[L] Logout") inp = input().decode('utf-8').strip().lower() match inp: case "1": print(f"Your message: {logged_in.message}") case "2": new_message = input("Enter your new message: ").decode('utf-8') logged_in.set_message(new_message) print("Message updated successfully.") case "l": print(f"Logged out from {logged_in.username}.") logged_in = None case _: print("Invalid option. Please try again.") ``` library: https://pypi.org/project/extend-mt19937-predictor/ Script solve: ```python= from extend_mt19937_predictor import ExtendMT19937Predictor import random from pwn import* from Crypto.Util.number import* import itertools import base64 flag=b'' predictor = ExtendMT19937Predictor() p=remote('tjc.tf', 31400) alphabet = 'abcdef' length = 128//8 # 32*4 count=0 known_numbers=[] for i, combo in enumerate(itertools.product(alphabet, repeat=length)): print(count,624//4-1) string = (''.join(combo)).encode() print(string) print(p.recvuntil(b'Quit\n').decode()) p.sendline(b'2') p.sendline(string) a=bytes_to_long(string) print(p.recvline()) print(p.recvuntil(b': ')) b=p.recvline() print(b) b=base64.b64decode(b) b=bytes_to_long(b) c=((b^0x5a)>>3)^a predictor.setrandbits(c, 32*4) known_numbers.append(c) count=count+1 if count==(624//4): break #print(c) #break for i in range(624//4-1, -1, -1): recovered = predictor.backtrack_getrandbits(32*4) assert recovered == known_numbers[i] user=[b'Admin001',b'Admin002',b'Admin003'] for i in range(2, -1, -1): p.sendline(b'1') print(p.recvuntil(b': ')) p.sendline(user[i]) print(user[i]) print(p.recvuntil(b': ')) recovered = predictor.backtrack_getrandbits(32*2) print(recovered) d=bytes_to_long(user[i]) d=d^recovered d=d<<3 d=d^0x5a d=long_to_bytes(d) d=base64.b64encode(d) print(d) p.sendline(d) f=(p.recvline()) print(f) print(p.recvuntil(b'Logout\n')) p.sendline(b'1') print(p.recvuntil(b': ')) f=(p.recvline()) print(f) flag=f[:-1]+flag p.sendline('L') print(p.recvuntil(b'Quit\n')) print('flag = ',flag.decode()) ''' predictor = ExtendMT19937Predictor() random.seed(1234) outputs = [random.getrandbits(32*4) for _ in range(624//4)] for val in outputs: predictor.setrandbits(val, 32*4) print("Predicted:", predictor.predict_getrandbits(8)) print("Actual :", random.getrandbits(8)) ''' #tjctf{1_gu3ss_h1nds1ght_15_20/20} ```