This week’s topic 22/2/15: Input()
Since this is the first article in this new series, I’ll begin by explaining what this experiment is all about. I decided to begin writing a collection of articles all about exploiting programming mishaps, which shall be known as Exploitation. The main purpose of these articles, is to prevent security issues by informing readers who might’ve not been aware of these vulnerabilities prior to reading the article. Another motive would be promoting CTF (Capture the Flag) cybersecurity competitions. For the time being, I’ll try releasing these on a weekly basis. With that said, lets get started!
Before we dive in, a quick notice.
For those of you who are using Python version 3.x, this does NOT apply to you. For those who don’t know, in Python 3, the raw_input() function was erased, and it’s functionality was transferred to a new built-in function known as input(). As oppose to Python 2.x, which both the input() and raw_input() function exist. Therefore this article only applies to programs written in Python 2.x.
The eval() function in Python receives a lot of criticism for it’s potentially dangerous misuse. As a reminder, the eval() function evaluates a string of text which is passed as its parameter, accepting a possible second argument for the global values to use during evaluation. Furthermore, the input() function in Python 2.x, would be the same as writing eval(raw_input()). For those who haven’t caught on yet. This makes the input() function very vulnerable.
There’s no better way to understand its vulnerability, then by seeing the function exploited. Therefore, I’ll demonstrate input()’s exploitation by writing up a small guessing game script.
The first two lines of the program can be ignored for our purposes, they’re comments. We begin by importing the random module, so that we can use random.randint(1, 10001) to generate a number in that range, and set it equal to variable lucky_num. In a potential infinite loop, we set variable res equivalent to the user’s input. And finally test if that input is equal to the random number which was randomly generated. If they’re equal, a message will be outputted, otherwise the loop will keep going. Now for the exploitation….
From reading the the text in the image above, you can see that after I ran the program in terminal I was prompted for a number. After trying unsuccessfully several times, I decided to just use the variable name which stores the value of the random integer. In our case, this was lucky_num. Since input() is the same as eval(raw_input()), it evaluates the variable as if a number was directly entered, by which means it returns a True Boolean value and ends the game. Had I used raw_input() instead, this wouldn’t have been an issue.
The example above is just for a small and insignificant game. But imagine you used input() to obtain a user’s credentials and stored them in a database. That user is potentially vulnerable to identity theft or robbery among other things, if the perpetrator has access to your script. Therefore, word of the wise. If you insist on sticking to Python 2.x, stick to raw_input() as well. Also try to avoid misusing eval().