09-01-2019 / From 0 to pentesting hero

Why you shouldn’t use input function in Python 2?

Today's example consists of 2 lines of python code, because usually it's enough to introduce a vulnerability to our application.

The code is extremely simple - first I ask for the user's name and then I display them in the console with the note "Hello".

Let's see how it works in practice.

name = input("My name:")
print ("Hello ", name)

I'm entering my name. For now, everything looks fine.

My name

During the pentest, we try to provide an input that the programmer did not expect when creating a given piece of code.

Here, the programmer asks us for a name - a string of characters, so let's try to give a number and see what happens.

I will type 2+4.

Number

As you can see I got the result of addition, not a string of characters.

Why did this happen?

If we don't understand something, it's worth looking into the documentation1.

Eval

I am browsing the documentation of Python's built-in functions. Now let's go to the input function.

As we can see, it says it's the equivalent of two functions: eval and raw_input.

What is eval? It is a function that executes the code given by the user as a parameter.

We can therefore treat this as a console equivalent, only in the form of a function.

And that's all about today's vulnerability - input is another name of the eval function - which allows you to execute arbitrary code by the user.

So let's try to do something more complicated than just addition.

We will try to display a list of all files in a given directory. We are going to use the system function from the os module to achieve this.

By default, we would use the import keyword to load the module and then the system function to call the function we want.

Here, however, we can't do this, because everything must fit in 1 line.

We will use an alternative syntax that looks like this.

__import__('os').system('dir')

As you can see, we made it to display the contents of the current directory.

So how do you fix this error?

Directory content

Just use the raw_input function, which always returns text and no longer uses the eval function.

name = raw_input("My name:")
print ("Hello ", name)

Interestingly, this bug only exists in Python version 2. If you're using version 3 - you're safe, because input function by default works like raw_input function.

raw_input Function

And that's all for today. If you like this episode - subscribe my channel for more.