| 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 |
| 122 |
vee1e / cf0a56f6c8274b74b7d97c7c571b9967
Last active 2 hours ago