vee1e

vee1e / cf0a56f6c8274b74b7d97c7c571b9967

Last active 4 days ago

Like 0

Osanai Yuki revised this gist 6 months ago · b1fa20a

1 file changed, 121 insertions

solver.py (file created)
@@ -0,0 +1,121 @@
1 + import pwn
2 + import re
3 +
4 + def 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 +
32 + def 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 +
113 + if __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