Bypassing Basic Protections

In this post I’ll be looking at ways of bypassing simple vulnerability protections. I will highlight common mistakes made by developers when trying to prevent some of the most common web application attacks, and how these mistakes can be exploited/bypassed to achieve an attack.

This post was inspired partly by a recently disclosed vulnerability I read about, and partly by the ‘Damn Vulnerable Web Application’ (DVWA). I thought it would be something interesting to practice, and would provide some good content for this blog.

I recently downloaded the ‘Damn Vulnerable Web Application’, which is a web application that has been purposely built to be vulnerable to common web application attacks. I was hoping it would be a set of realistic challenges, much like the HackThisSite challenges but better. However, it turns out that DVWA is very similar to OWASP’s Webgoat, in that it lists each vulnerability and provides hints and access to the source code should you need it.

This is great for learning more, and practicing my skills; I’m sure that I will find some value in it. However, it isn’t particularly interesting to write about, and doesn’t really help develop skills in testing applications (i.e. not knowing what an application is vulnerable to, or even if it is vulnerable at all, and figuring out what is wrong; also known as Blackbox Testing). Then I noticed that the DVWA has varying ‘difficulty levels’. It allows you to select what level of protections are in place for each vulnerability; so for example, the low difficulty SQL Injection attack has absolutely no protections in place, but the impossible level is totally secure and not possible to attack.

So, because I have never really looked at bypassing protections in great detail I thought it would be a great opportunity to learn more and write about it for my blog.

The Disclosed Vulnerability

As I mentioned, this topic is also of interest to me because of a vulnerability disclosure I read this week which highlights this exact problem. I won’t name the software, because as far as I am aware it has not been patched (and judging by the developer’s hostile response, it may not be for some time, if at all!) and it isn’t really relevant.

Most developers are not security experts. In fact, there are many developers out there who pay no attention to security issues at all; security is often a very low priority when compared to functionality, ease of use, and client requests. And that is one of the many reasons applications are made with vulnerabilities built-in.

There are some developers who attempt to prevent malicious users, but the techniques they use are sometimes flawed and will only prevent low skilled attackers. To be quite honest, I don’t really understand how such solutions find their way into code, given that secure methods of achieving goals are usually well documented if you perform a little research. Maybe it is a case of one person getting it wrong, posting their solution on the internet, and then it being copied and spread into other applications.

In any case, this particular example was a Local File Inclusion vulnerability, which allowed attackers to use directory traversal to print the contents of files stored on the server. Local File Inclusion is when an application dynamically reads the contents of files to the page.

So, for example, if you had a page which displayed a series of poems which are all stored in text files, you may have a user request one using a GET parameter: example.com/poems/?poem=poem1.txt. The application would then pass this GET parameter directly into a function which prints the contents of a file to the page. If a malicious user were to use directory traversal, they could use ‘../’ to travel through other directories on the server, and make the function print files it was not intended to.

So for example, if the application did not have strong protections in place, sending a request to example.com/poems/?poem=../../../../etc/passwd would print out the /etc/passwd file (if the file was contained in something like /var/www/html/[application] ). They may also be able to use the direct path, /etc/passwd depending on how the application handles the file path.

This is obviously an issue; attackers could do several things including reading confidential files, accessing source code to find further vulnerabilities, or in some cases even perform code execution.

So, to stop this, the developer of the application decided to use str_replace() to replace any occurrences of “../” in the request parameter to “”, effectively removing them. This kind of works, but in practice it is only a minor speedbump for a determined attacker. And, in fact, when faced with a possible local file inclusion vulnerability this is one of the
first techniques I might attempt if I suspected the application was filtering my attempts.

I’ve made a quick example application to show how an attack would work.

My application accepts a filename as an input and uses the following code to get the contents of the file:

$fileContent = file_get_contents("./" . $file, FILE_USE_INCLUDE_PATH);

This will insert the file parameter into the file_get_contents() function, which will then open the file from the current directory. With no protection in place, I can simply use ../ to go up a directory and print out the contents of a file in another directory. (I have also added a string which shows the file path that was requested)

lfi_bypass1

As you can see here, the file path requested was one directory above the current directory, and I was able to retrieve the default index.html page created by apache.

Now, I will add in the broken protection like so:

$fileOpen = str_replace("../", "", $file);
$fileContent = file_get_contents("./" . $fileOpen, FILE_USE_INCLUDE_PATH);

Now, when I try to request the same ../index.html I get no file contents because that file does not exist in the current directory; the “../” has been removed. Below is the print out, which shows the requested file path and the actual executed file path:

lfi_bypass2

So, how can this filter be bypassed?
The answer is extremely simple. The str_replace() will only remove exact instances of “../”. Nothing else. It will not remove a “.” or a “./”. So all you need to do is use “…/./”, and once the str_replace() is run you will be left with a “../”. Below is a screenshot of retrieving the same index.html file, bypassing the filter using the above method. You can see the …/./ used to contruct the ../ in the requested file path.

lfi_bypass3

There are several other (ineffective) methods of preventing local file inclusion but I won’t be going through all of them. The correct method to use, and prevent the vulnerability, will depend on the application you need to build, what kind of files are being retrieved, and how many files there are. In my poem example, I might suggest using a pre-built list of filenames and rejecting any deviations, or a carefully crafted regular expression suited to the filenames and extensions.

XSS Filters

XSS, Cross Site Scripting, is a group of attacks where malicious code can be inserted into a webpage and executed by the client. It comes in two main forms: reflected, where the code is immediately inserted onto the page and executed by the browser (e.g. via a GET/POST variable), and stored XSS, where the malicious script is actually saved to the database and served to everyone who happens to visit a page where that data is retrieved. There is also another form, known as DOM XSS, which works slightly differently. In reflected and stored attacks, the malicious scripts are returned in the response from the server. In a DOM based XSS attack, the malicious code is not returned by the server; instead, the script is inserted and used by the client and does not involve the server.

Filter bypasses for these attacks will vary based on which type of attack is possible, how the application handles the malicious input, and in some cases what kind of protections are in place on the client browser. I will look at a few of these variations.

I will start with a quick example on the Damn Vulnerable Web Application.

The reflected XSS example is a simple form with one input value. You enter your name (or text, or script) and the application prints it out with “Hello, ” prepended. With absolutely no protections in place (the security setting set to ‘low’), the application allows you to simply insert script tags and have the code execute on the client browser. Below is a simple alert() that has been triggered using the name GET parameter.

xss_bypass1

In this case, the application seems to simply take the GET parameter and insert it directly into the response with no input validation or output filtering. This causes a security issue, as an attacker could send a victim a link to the webpage with malicious script inserted into the url. Any user who visits the crafted url will execute the malicious script.

If I now set the DVWA security setting to ‘Medium’, some form of filtering/protection will be implemented. You can use the ‘view source’ button to show the source code that is rendering the page, but this would be cheating, and would be very unlikely to happen on a real web application. We will need to figure out how the script is being filtered manually.

If I attempt to enter the same script again, the alert is no longer executed. Instead, the application prints “Hello, alert(‘1’)”.

xss_bypass5

But what happened to the script tags I placed in? It looks like the application has simply stripped away the script tags and left whatever was contained inside them. It might be possible to circumvent this by ‘obfuscating’ the script tags; by which I mean, changing the appearance of the script tags so that when the application looks for the ‘<script>’ it does not find it. I tried to submit the following:

<ScRiPT>alert('1')</sCRipT>

And as you can see this still successfully executed:

xss_bypass6

Now if we view the source code we can see how the developer tried to prevent this. The vulnerable line is shown below:

// Get input
$name = str_replace('<script>', '', $_GET['name']);

They have simply used str_replace() to change every occurence of ‘<script>’ to an empty value. This is extremely ineffective as there are so many different ways to execute XSS attacks that simply removing occurences of script tags is not sufficient.

One such example are the HTML event attributes, which can be used to run functions when an event related to an HTML element occurs. For example, the img tag has an ‘onerror’ event which will execute when there is an issue loading an external resource (such as an image). All an attacker would need to do is include an img tag as shown below:

<img src="/" onerror="<script>alert('1')</script> />

The image will not be found and the event will be triggered, executing the alert.

I have now set the DVWA difficulty level to ‘high’, which is the final level below ‘impossible’. In this case, it should be difficult to perform the specified attack. In the ‘impossible’ level, the source code and application should be secure from all attacks.

I attempted the plain “<script>alert(‘1’)</script>” again and was this time given the response “Hello, >”. Obviously some stronger input validation has taken place here.

After some experimentation, I found that the event handlers were the way to get XSS to run. I used the one I printed above to get the alert to execute: “<img src=/ onerror=”alert(‘1’)”>”. I also found that many of the other event handlers would work in this situation, and I expect that the vast majority of them would. The onerror event is particularly useful though because, so long as you set it correctly, it runs the script without any user interaction, as opposed to an event handler such as onmouseover.

Viewing the source code shows the vulnerable line, printed below:

// Get input
$name = preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET['name']);

The regular expression is effective but, as I have already mentioned, it only focuses on the script tags. It does nothing to prevent other methods of XSS, such as the event handlers.

It seems that DVWA is a little limited in the XSS protections that it demonstrates. Many other XSS filters have been implemented in real-world applications, and they will all have different weaknesses with different bypasses. I will now look at a few more advanced ways of hiding the executable script tags and event handlers in order to get past poor protections. This is all a time consuming process of experimenting with different input values and seeing what the application does with the output. Typically, you would try to obfuscate script inputs when you no longer have any script execution methods to attempt.

Mangling the Input

Web browsers are quite forgiving in the code that they execute (i.e. they will try to correct incorrect syntax), and this can be used to an attacker’s advantage; by sending inputs which are technically incorrect (e.g. missing quotation marks or inserting unusual characters) may be enough to get past the application’s filter, or an application firewall, and still be executed by the browser.

One example which applies to the DVWA’s medium difficulty is the addition of extra content after the tag name, for example:

<script/aaa>alert('1')</script aaa>

In this case, the application’s search for a ” does not work, because it is not exactly contained within the value. But the extra content is still ‘intact’ enough to actually be executed by the browser.

Another method that can work in certain situations is encoding characters. The tricky part, however, is getting the application and browser to interpret the input in the way that you need it to.

One quick example of this is inserting an object with a data type and then inserting the encoded data. For example:

<object date="data:text/html;base64,PHNjcmlwdD5hbGVydCgnMScpPC9zY3JpcHQ+">

“PHNjcmlwdD5hbGVydCgnMScpPC9zY3JpcHQ+” is the base64 representation of “alert(‘1’)” and inserting this
into the DVWA page executes the alert.

The impossible level shows the correct way of preventing XSS (at least, within php). They have used the htmlspecialchars
() function to convert all special characters to html entities. It is important to use this function whenever you are outputting untrusted data to a page. It will ensure that no special characters are executed or read as part of the document. Instead, it will simply print the escaped string to the page.

DOM Based XSS and Client Side Filtering

If you have ever created an application that is deliberately vulnerable to XSS, and then tried to exploit it from within Google Chrome, you may have found that the script failed to execute. Examining the browser’s console will tell you that Google Chrome’s ‘XSS Auditor’ blocked the script because it was found in both the request and the response from the
server, as shown below.

xss_bypass7

Some browsers have built-in protections for XSS; they work on the client-side, and attempt to block the effects of XSS by looking for possible script injections. To explain it simply, Google Chrome’s XSS Auditor only checks to see if scripts that are being executed were contained within the HTTP request. If they were, then they are filtered out.

This means that the Auditor is completely ineffective against DOM based XSS attacks. As I have never written about these before, I should briefly explain how they work.

DOM based XSS attacks work by utilizing a vulnerable function contained within the client side code, rather than a server side vulnerability. It is much easier to understand when you see it working in action. Below is a snippet of vulnerable code from one of the OWASP WebGoat lessons:

function displayGreeting(name){
if(name != ''){
document.getElementById("greeting").innerHTML="Hello, " + name+ "!";
}
}

This is called using an event handler ‘onkeyup’, which occurs when a user releases a key. In the application, you are given an input box to type your name in and as you type the displayGreeting() function displays whatever you typed with the concatenated “Hello, !”.

innerHTML is vulnerable to DOM XSS if appropriate filters are not in place. As there is no protection on the name variable, an attacker can enter javascript or insert html elements. By inserting the text below:

" <img src=/ onerror="alert('1') >

I was able to cause an alert to pop up. There are several other methods you could use to insert malicious script in this case.

xss_bypass8

What is interesting about this vulnerability is that it occurs entirely client-side and therefore Google Chrome’s XSS Auditor can do nothing to prevent this attack. The inserted script does not get sent in the request and is not returned in the response. There are a few different attack vectors where, with the right vulnerability and application, an attacker can trick a user into executing a DOM based XSS script in the same way they might a ‘regular’ XSS attack, such as by sending an email with a link to the code inserted into the URL.

One such example is given by OWASP; if an application were to use document.location (which returns the url), for example, in a vulnerable function such as innerHTML, and attacker could direct a victim to something like some.site/page.html#default=alert(document.cookie). Everything after the ‘#’ would be inserted into the document as valid javascript, and would execute. However, it would not be sent to the server and would therefore also avoid server side prevention and Google Chrome’s XSS Auditor.

An important side-note to make here is that Chrome’s XSS Auditor is not designed to catch every single possible XSS attack, and the idea that any client side filter could do so is a little far fetched. Rather, it is intended to help prevent the easiest and most basic XSS attacks. The responsibility for preventing XSS attacks (ALL XSS attacks, including DOM based) still remains with application developers.

SQL Injection

The final protections bypass I will look at is for SQL Injection. I will again be using the Damn Vulnerable Web Application to demonstrate.

If you know anything about SQL Injections, you will know that the best way to prevent them is through parameterised queries which are, in the vast majority of cases, completely safe against injections.

Some developers however, decide to use character escaping or filtering rather than parameterising queries. This is risky because if your filter doesn’t work, your application is left wide open to a devastating attack.

The DVWA SQL Injection page, with absolutely no protections in place, has a text input where you can enter a user ID. This will return the information for that user. However, because the input is placed directly into the SQL query it is possible to use a simple SQL Injection such as “a’ OR ‘1’=’1” to make the query return true, and make the application
print out all of the user’s information. I covered situations like this quite well in my last post on SQL Injection, which you can read here.

With the security set to medium, the application changes to a text box and seems to have some protections in place. If I try to intercept the input and add my “‘OR ‘1’=’1” I am given an SQL error which reads: “You have an error in your SQL syntax… the right syntax to use near ‘\’ OR \’1\’=\’1′ It looks like the application has prepended ‘\’ to the quotation marks, which is a sign of mysql_real_escape_string() or some form of escaping, rather than parameterised queries.

As this particular input is a number, it is still possible to use the OR and a true value to get all of the user’s information. Simply using “OR 1=1” with no quotes will still make the OR clause return true, and as you can see below it still grabs all of the user’s data.

sqli_bypass

The final DVWA level which is exploitable, hard, does not use any filtering. It instead uses a SESSION variable to store the data and you simply have to use a comment to remove a ‘LIMIT 1’ appended to the query by the developer. Again, I covered this in my last article on SQL Injection in great depth.

Conclusion

I think I have written enough for now on evading filters. This was mostly focused on XSS attacks but I thought the Local File Inclusion and SQL Injection examples were interesting enough to include. This isn’t supposed to be a complete collection of every possible kind of bypass or exploitation method but just a few examples of creative ways to get around protections which don’t fully work.

I’m now going to be looking at a few challenges to work on so hopefully I’ll get to show off one of these techniques very soon!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s