vee1e

vee1e / cf0a56f6c8274b74b7d97c7c571b9967

Last active 2 hours ago

Like 0
solver.py Raw
1import pwn
2import re
3
4def get_rand(seed):
5 state = [0] * 31
6 v3 = seed if seed != 0 else 1
7 state[0] = v3
8 for i in range(1, 31):
9 v9 = 16807 * (v3 % 127773) - 2836 * (v3 // 127773)
10 v3 = v9 + (0x7FFFFFFF if v9 < 0 else 0)
11 state[i] = v3
12
13 fptr = 3
14 rptr = 0
15
16 def rand():
17 nonlocal fptr, rptr, state
18 val = (state[fptr] + state[rptr]) & 0xFFFFFFFF
19 state[fptr] = val
20 res = val >> 1
21 fptr += 1
22 if fptr >= 31: fptr = 0
23 rptr += 1
24 if rptr >= 31: rptr = 0
25 return res
26
27 for _ in range(310):
28 rand()
29
30 return rand
31
32def solve_challenge(dt):
33 # Connect
34 conn = pwn.remote('135.235.195.203', 3000, level='error')
35
36 # Wait for shell prompt
37 conn.recvuntil(b"/ $ ")
38 conn.sendline(b"/challenge/lock_app")
39
40 # Read until "The current time is:"
41 conn.recvuntil(b"The current time is: ")
42 server_time = int(conn.recvline().strip())
43 print(f"[+] Server Time: {server_time}, dt: {dt}")
44
45 # Compute SBOX with server_time
46 rand_init = get_rand(server_time)
47 rand_init() # Discard
48 rand_init() # Discard
49
50 SBOX = list(range(256))
51 for j in range(255, 0, -1):
52 v2 = rand_init()
53 swap_idx = v2 % (j + 1)
54 SBOX[j], SBOX[swap_idx] = SBOX[swap_idx], SBOX[j]
55
56 def time_math(val):
57 return (SBOX[(val >> 24) & 0xFF] << 24) | \
58 (SBOX[(val >> 16) & 0xFF] << 16) | \
59 (SBOX[(val >> 8) & 0xFF] << 8) | \
60 SBOX[val & 0xFF]
61
62 # Wait for menu
63 conn.recvuntil(b"Select option: ")
64
65 # 2. Reset password
66 conn.sendline(b"2")
67
68 # Read challenge code
69 # "Your challenge code is: XXXXXXX"
70 conn.recvuntil(b"Your challenge code is: ")
71 chal_code = int(conn.recvline().strip())
72 print(f"[+] Challenge Code: {chal_code}")
73
74 # Generate response based on guessed time
75 rand_gen = get_rand(server_time + dt)
76 v5 = rand_gen()
77 v6 = rand_gen()
78
79 v7 = time_math(v5)
80 v8 = time_math(v6)
81
82 v7 = time_math(v5)
83 v8 = time_math(v6)
84
85 # Both modulos are UNSIGNED 32-bit
86 val1 = (31337 * v7 + v8) & 0xFFFFFFFF
87 mod1 = val1 % 1000000
88 urandom = chal_code ^ mod1
89
90 val2 = (v7 ^ v8) & 0xFFFFFFFF
91 mod2 = val2 % 1000000
92
93 response = urandom ^ mod2
94
95 print(f"[+] Predicted Response (dt={dt}): {response}")
96
97 # Send response
98 conn.recvuntil(b"Response code: ")
99 conn.sendline(str(response).encode())
100
101 res = conn.recvall(timeout=3).decode()
102 conn.close()
103
104 if "Nope" in res:
105 print("[-] Failed.")
106 return False
107 elif "Here's a gift" in res or "SUCCESSFUL" in res:
108 print("[*] SUCCESS!!!")
109 print(res)
110 return True
111 return False
112
113if __name__ == "__main__":
114 for dt in range(0, 5):
115 for _ in range(3): # try each dt 3 times
116 try:
117 if solve_challenge(dt):
118 import sys
119 sys.exit(0)
120 except Exception as e:
121 pass
122