There are hundreds of ways to exploit a web application. Users can upload invalid file types to an app that doesn't check the file type, they can inject code into the pages, as well as retrieve data from a database that should not be retrieved. The focus of this series is mainly on using a web application firewall to prevent against attacks, so I will not be explaining every attack type with examples. However, I will be focusing on two injection attacks here that will demonstrate that the web application is vulnerable before I use a web application firewall to block those attacks. I will be giving basic examples of cross site scripting and mySQL injection.
Cross Site Scripting (XSS)
The first attack type I am going to attempt on our web application is cross site scripting. However, we must first understand what cross site scripting is and how it can be used against a web app. Remember in part one of this series, I mentioned that most web vulnerabilities come from users entering input that is not valid and that could contain malicious code. Cross site scripting takes advantage of the fact that a fair amount of web pages and applications fail to "sanitize" user input. Take a look at the following PHP code:
echo <pre>Hello $_GET['name']</pre>;
This code gets a variable called "name" and prints it out directly within the page as HTML code. The echo statement prints whatever follows it into the HTML code of the page. If we pass in the name "Robert," the following is reflected onto the page to the user:
Now, the code we just typed is reflected into the actual code of the page as it is displayed.
echo <pre>Hello <script>alert('Hello')</script></pre>
This will cause an alert box to pop up for the user.
This form of XSS is known as reflected or non-persistent XSS because it only occurs if the additional code parameters are passed in at run time. The web page itself is not changed permanently. However, this vulnerability can be exploited by sending someone a URL with the parameters as seen in the screenshot above. A lot of XSS can be done directly through the URL bar. The example given above is very basic. However, imagine the security issues that could occur if instead of displaying an alert, an attacker loaded code from an externally hosted script (the "cross-site" in cross site scripting).
The second form of XSS (persistent or stored) allows users to inject code directly into the page that will be repeatedly reflected to users who load it. The code is usually stored in a database and then continually reflected. The attack is carried out the same way, except instead of simply being reflected back to the user, the script is saved an executed every time the page is loaded. Think of an visitor log that web page visitors can sign and leave comments. The information they submit is saved in a database and loaded each time the visitor log is displayed. If someone were to inject malicious code, it would be shown each time to the user. This form of XSS is much more dangerous.
mySQL injection is well documented around the web with thousands of tutorials on YouTube covering it. mySQL injection can range from a very simple, short line of code to an extremely complex and carefully crafted string to destroy a database. What it all comes down to, however, is creating a string that will "confuse" the PHP code into executing more commands than should be executed. Let's look at the following PHP code:
$name = $_GET['name'];
$result = mysql_query("SELECT * FROM people WHERE first_name='$name'");
while($row = mysql_fetch_array($result))
echo $row['first_name'] . " " . $row['last_name'];
echo "<br />";
It's fairly straightforward as to what this code does (prints out names from the database given a first name). But look at the way in which the code is outputting the user-entered input: it's treating it like a single piece of text that is just inserted into the mySQL command. Suppose that the user doesn't enter a name, but instead enters mySQL commands? Let's look at the following code:
' or '1' = '1
This code is extremely common for testing mySQL injection vulnerabilities. When the PHP code prints out this string as the "name" in the code above, a very important tick-mark (') causes the code to read as:
WHERE first_name=' ' OR '1' = '1'
Essentially, we are crafting a string of code that fits nicely within the given mySQL code. The tick-marks line up and a complete statement is made. The statement "OR '1' = '1'" is used because it will always evaluate to true. What we are telling the database to do is "return all the rows where 1=1." In other words, return all of the rows. This is a great way to view data in the database that should not be viewed.
Progressing beyond a simple OR '1' = '1' statement, pretty much any SQL code can by inserted into the statement. This can be used to view other tables, return all the lists of users, grab additional columns, etc. Here is a great link to some SQL statements that may be helpful in exploitation.
Next in the Series
Now that we've discussed injection techniques and very common vulnerabilities, we are going to be using a web application firewall to prevent those attacks. There are many ways to protect against injection attacks (most notably the filtering and sanitation of user input) but we will be leaving the application vulnerable for the purpose of learning about the firewall.