80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
from pwn import remote, log
|
|
import ctypes
|
|
import sys
|
|
import re
|
|
|
|
# Set up the connection
|
|
host = 'challs.glacierctf.com'
|
|
port = 13386
|
|
|
|
p = remote(host, port)
|
|
|
|
# Load the C library (Liquids/glibc)
|
|
# This is required to match the server's random number generation.
|
|
# Note: This usually requires running on Linux to match a Linux server.
|
|
try:
|
|
libc = ctypes.CDLL('libc.so.6')
|
|
except OSError:
|
|
# Fallback for Mac/others, though values might differ from the Linux server
|
|
libc = ctypes.CDLL(None)
|
|
log.warning("Could not explicitly load libc.so.6. Using default system libc. If on Windows/Mac, numbers might not match server.")
|
|
|
|
def solve():
|
|
# 1. Wait for the initial prompt '>'
|
|
p.recvuntil(b'>')
|
|
|
|
# 2. "Write time" -> Send the command to get the seed info
|
|
log.info("Sending 'time' command...")
|
|
p.sendline(b'time')
|
|
|
|
# 3. Wait for ':' (The prompt for timezone)
|
|
p.recvuntil(b':')
|
|
|
|
# 4. Write "Europe/Berlin"
|
|
log.info("Sending timezone 'Europe/Berlin'...")
|
|
p.sendline(b'Europe/Berlin')
|
|
|
|
# 5. Receive the output containing the seed
|
|
# We expect:
|
|
# THIS IS THE STRING: 20251122201640
|
|
# THIS IS THE SEED: 351401000
|
|
response = p.recvuntil(b'>', drop=True).decode() # Read until next prompt/menu
|
|
print(f"\nServer Response:\n{response}\n")
|
|
|
|
# 6. Parse the seed using Regex
|
|
# Looking for: "THIS IS THE SEED: <number>"
|
|
match = re.search(r'THIS IS THE SEED:\s*(\d+)', response)
|
|
|
|
if match:
|
|
seed = int(match.group(1))
|
|
log.success(f"Extracted Seed: {seed}")
|
|
else:
|
|
log.error("Could not find seed in server response!")
|
|
return
|
|
|
|
# 7. Initialize srand with the extracted seed
|
|
libc.srand(seed)
|
|
log.info("Initialized local C library with seed.")
|
|
|
|
# 8. Generate the number
|
|
# This should match the server's next rand() call
|
|
generated_number = libc.rand()
|
|
log.success(f"Predicted Random Number: {generated_number}")
|
|
|
|
# 9. "Write solve" -> Send the solve command
|
|
log.info("Sending 'solve' command...")
|
|
p.sendline(b'solve')
|
|
|
|
# 10. Wait for ':' (The prompt for the random number)
|
|
p.recvuntil(b':')
|
|
|
|
# 11. Send the generated number
|
|
log.info(f"Sending predicted number: {generated_number}")
|
|
p.sendline(str(generated_number).encode())
|
|
|
|
# 12. Switch to interactive mode to see the flag/result
|
|
p.interactive()
|
|
|
|
if __name__ == "__main__":
|
|
solve()
|