Finding security vulnerabilities in PHP using Grep
Description: Using grep to find common web application vulnerabilities within your applications.
It is a common misconception that companies need to purchase complicated and expensive software to find security vulnerabilities (bugs) within their applications. These specialized software applications, whether they be black-box or white-box, open-source or commercial, do make the process of finding security vulnerabilities easier and in some cases quicker.
11 courses, 8+ hours of training
The truth is, all of these specialized vulnerability scanning tools have their particular strengths and weaknesses. Some may be ASP centric whereas others more geared towards PHP. The development team may have taken the decision to limit requests in order to improve speed, they may not check for vulnerabilities which they deem unworthy to be reported. If you want to find as many security vulnerabilities as possible within a certain timeframe you need to use all of the tools at your disposal.
No one vulnerability scanner or technique is going to find 100% of the vulnerabilities which may affect your web application. Even if you use every tool and technique at your disposal, and buy it cupcakes, software is never perfect.
Within this article I will introduce you to one more way you can hunt down those bugs by just using the command line tool, grep.
Black box / white box
Let's take a step back and clarify the white/grey/black box concept. A black-box assessment is where you have no prior knowledge of the application/network/company you are assessing. A white-box assessment is completely the opposite. You may have any information that you require to make your job easier. This may include network ranges, source-code, phone numbers, etc. A grey-box assessment is somewhere in between. In reality, most assessments are grey-box assessments. It is rare you either have no prior knowledge or all the knowledge you need.
Grepping for bugs would be classed as a white-box assessment or 'source code review'. A web application vulnerability scanner such as Netsparker, Nikto, Acunetix or w3af (the list goes on) would be classed as black-box tools as they (in most cases) will not have access to any server side source-code.
If you want to find as many security vulnerabilities as possible, a mixture of black-box web application assessment tools/techniques and a white-box source code review should be employed.
Grep
If you are reading this article I would imagine you are familiar with the basic concepts of the grep tool. However if you are not, here is a brief introduction to such a powerful utility.
Grep was created by Ken Thompson and released in 1973 to be used as a UNIX search utility that uses regular expressions to match lines in files. Most, if not all *nix based operating systems today will come with grep pre-installed.
On a *nix operating system we can use the command 'man grep' to view the tools' extensive functionality. Or alternatively we can use the command 'grep --help' for a list of switches and their usage.
For this article I have used GNU grep version 2.5.4. If you are running an older version of GNU grep some of the commands in this article may not work. To check your version of GNU grep use the command 'grep –V'.
Damn Vulnerable Web Application (DVWA)
DVWA is a purposely vulnerable open-source web application I originally developed while at university to teach myself web application security. Since then it has grown with the help of many talented individuals which range from web developers to security professionals from around the world.
The DVWA LiveCD will be perfect for practicing grepping for bugs as it is developed in PHP, it is open-source, easy to set-up and, if I do say so myself, pretty awesome.
The LiveCD or the stand alone files can be downloaded from the official DVWA homepage located at: http://www.dvwa.co.uk
If you have opted for the LiveCD version, either burn it to CD and boot it in a spare machine on your local network, or, the easier method is to boot the LiveCD ISO within virtualization software such as the open-source Virtualbox available from: http://www.virtualbox.org
Once you have set-up DVWA within Virtualbox and booted from it, you should be able to connect to it via your preferred browser.
As we are grepping, the server side PHP source code we will need to ssh to the DVWA LiveCD. To do this the command is 'sudo ssh dvwa@192.168.1.107' followed by the password 'password'. (NOTE: The IP address in the SSH command depends on what IP your DHCP server has assigned to the DVWA LiveCD.)
From here we 'cd' to the DVWA LiveCD web server root directory located at '/opt/lampp/htdocs'.
Grepping for Cross-Site Scripting (XSS)
For a brief description of XSS I will use the one from the Open Web Application Security Project ( OWASP ), "XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation and escaping. XSS allows attackers to execute scripts in the victim's browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites." (Top 10 2010-Main, http://www.owasp.org/index.php/Top_10_2010-Main)
To identify XSS within PHP we need to identify lines within the codebase where user supplied input is output back to the user without first being validated or properly encoded.
In PHP user supplied input is mostly handled by either $_GET, $_POST, $_COOKIE, or $_REQUEST. However user supplied input can also be handled with $_FILES, $_SERVER and others.
Let's start by looking for user supplied input via HTTP GET requests. To do this we will use grep combined with a couple of flags and a regular expression.
The command we will use to search for user supplied input is: grep -i -r "$_GET" *
We have used the following options; '-i' to ignore case sensitivity and '-r' to be recursive by searching for files within sub directories. Our regular expression which will attempt to match the PHP $_GET superglobal variable is "$_GET". We first enclose the regular expression in double quotes, we escape the dollar symbol with a forward slash as the dollar symbol has special significance in regular expressions. Then we give it the keyword to search for, '$_GET'. We finish off with a wildcard symbol (*) to tell grep to search within all files it comes across.
As you can see we have many results from our simple grep command, let us try and be more specific to narrow down the potential possibilities. In PHP, output is normally handled by the 'echo' construct. Let's see what happens if we search for user supplied input which is then directly output within the page without first being sanitised. To do this we will try the following command: grep -i -r "$_GET" * | grep "echo"
Our new command will search through our original results looking for the "echo" keyword.
In this instance no results were found. Let's take another look at our original results more closely to try to identify why this is the case.
The following line within our results looks as though it may be outputting data.
It looks as though the GET HTTP request with the name of 'name' is being appended to a variable called '$html'. Let's try and find out where the variable was originally set or where it ends up. To do this we will take a look at the server side source code of the '/opt/lampp/htdocs/vulnerabilities/xss_r/source/low.php' file with the following command: cat vulnerabilities/xss_r/source/low.php
By reading the low.php file we get a better understanding of what it does. We can see that the only check in place is whether or not the $_GET['name'] variable is empty or null before it gets put into another variable called $html. All user supplied input should be sanitized or encoded to help prevent XSS vulnerabilities We can now safely assume that the $html variable is output to the browser at some point due to its name and contents. However if the $html variable is properly sanitized or encoded where it is output we may not have found a valid XSS vulnerability.
To find where the $html variable is output to the user let's do some further investigation. As we can see, the low.php file is in the 'vulnerabilities/xss_r/source' directory. Let's see what else is in the same directory with the following command: ls vulnerabilities/xss_r/source
As you can see from the output of our command, we have three files, high.php, medium.php and low.php. Let's take a look at the contents of a file within the same directory, maybe they yield some clues as to where the $html variable is output. We will issue the following command: cat vulnerabilities/xss_r/source/medium.php
The medium.php file looks almost exactly the same as the low.php file. However the medium.php file does some basic input sanitization by replacing the '<script>' string with nothing in the$_GET['name'] input variable. There could be some possible XSS here too, however this is still using the $html variable to output the data to the user. We still need to find where the $html variable is output in order to verify the XSS vulnerability. Let's look in the parent directory for some clues by issuing the following command: ls vulnerabilities/xss_r/
The index.php file looks interesting, let's take a look at its server side source code by issuing the following command: cat vulnerabilities/xss_r/index.php
Bingo! By reading through the file we notice the $html variable is present! Issue the following command to view the index.php files contents with line numbers: cat -b vulnerabilities/xss_r/index.php
And there we have it, at line 47!
The user supplied input which comes from $_GET['name'] in the low.php file is output via the $html variable within the index.php file. Both input and output is left unsanitized or unencoded. There is only one way to be 100% certain that we have an XSS vulnerability, and that is to exploit it.
Let's open up the web application in a browser and login with the username, 'admin' and password 'password'.
Once logged in, navigate to the 'DVWA Security' tab on the left hand menu. From here change the 'vulnerability level of DVWA' to 'low' and hit the submit button. NOTE: From our grepping we noted that our input was in the 'low.php' file. For each vulnerability in DVWA there are three different levels of security which determines the vulnerabilities exploitability. By changing the vulnerability level of DVWA to low we are making the application as vulnerable as possible.
Now the security level has been changed to low let's navigate to the XSS reflected page by clicking on the 'XSS reflected' button on the left hand menu.
To quickly verify that user supplied input or output is not sanitized or encoded we can use the <blink> html tag. Let's input the following as our name: <blink>I am vulnerable!</blink>
As you can see our <blink> HTML tag has been output to the user without being sanitized or encoded. We can now confirm that we have HTML injection, but what about XSS?
Let's try inputting the following as our name: <script>document.write(document.cookie);</script>
As you can see from the above screenshot we have successfully executed JavaScript by inputting it into the web application and having it output back to us without first being sanitized or encoded. Ladies and gents, we have XSS!
For further reading on the subject of Cross-Site Scripting (XSS) please see the provided links within DVWA under the 'More info' title.
Grepping for Command Injection
For a brief description of Command Injection I will use the one from the Open Web Application Security Project (OWASP), "The purpose of the command injection attack is to inject and execute commands specified by the attacker in the vulnerable application." (Command Injection, http://www.owasp.org/index.php/Command_Injection)
Within PHP there are a few different functions which will facilitate the execution of commands on the underlying operating system. If unsanitized user supplied input is used within one of these functions it may be possible to inject our own commands on the operating system. We will try our luck and search for the exec() PHP function with the following command: grep -i -r "exec(" *
Our grep command seems to have given us a lot of results. Let's refine our grep command a little to be more specific. It looks as though the developers of DVWA have left the '.svn' hidden directory within the application. There also seems to be an Intrusion Detection System (IDS) within the 'external' directory. Both of these folders are giving us a lot of output which look like false positives. We will use grep to exclude both the '.svn' directory and 'external' directory to refine our search with the following command: grep -i -r --exclude-dir={.svn,external} "exec(" *
That's better. We now have fewer, more refined results by using the '--exclude-dir' grep flag to exclude both the '.svn' and 'external' directories. By looking at the results, the following line looks promising based on the directory structure (similar to the XSS one) and the fact that there is no sanitization on the '$target' variable:
Let's take a look at the 'vulnerabilities/exec/source/low.php' file by issuing the following command: cat -b vulnerabilities/exec/source/low.php
We can see from the file contents that the '$target' variable accepts user supplied input on line 5. It is then placed straight into the 'shell_exec()' PHP function on lines 10 and 15 depending on the operating system the script is run on. Here we have user supplied input being put straight into a function that executes operating system commands. Bad idea.
To verify whether or not the above is actually exploitable, fire up DVWA and take a look at the 'Command Execution' page. Can you successfully execute commands on the operating system to determine the version of MySQL in use? Give it a try!
Conclusion
By reading through this article and following along with the help of DVWA, I hope I have shown you other techniques and tools you can use when securing your web applications.
We have barely scratched the surface of the power of grep. There are many more flags within grep that can help you in searching for vulnerabilities. Read the help and manual to see how powerful the tool really is.
For further grep vulnerability finding commands please see my original post on the subject located on my personal blog: http://www.ethicalhack3r.co.uk/security/greping-for-bugs-in-php/
For a great open source Windows tool to help with manual source code review please see Agnitio by David Rook which can be downloaded from: http://sourceforge.net/projects/agnitiotool/
And for an automated open source PHP source code review tool I recommend RIPS which can be downloaded from: http://sourceforge.net/projects/rips-scanner/

Application security
DevSecOps: Continuous Integration Continuous Delivery (CI-CD) tools