Web Application Security (part 2)


Supporting files

We will use the same vulnerable virtual machine as the previous lab. If not already downloaded in /mnt/sda5/cns/, download it from elf (the file has about 250MB) and import it into VirtualBox by selecting FileImport Appliance and selecting cnsweb.ova. Add a new network adapter (Adapter 2) of the type Host-only Adapter). This will be adapter you will use for connecting uring Burp. After booting up the virtual machine, you can find its IP by logging in directly from VirtualBox as student (password student); you will be shown a window with the IP address to use; you can not do anything more than that; you are just going to use the IP address to connect to the virtual machine using Burp.

You can get out of the VirtualBox virtual machine console by using the right Ctrl key.

You can then test that the web server is working by issuing

$ sudo apt-get update && sudo apt-get install curl
$ curl $SERVER_IP

where $SERVER_IP is the Virtual Machine's IP address.

As mentioned in the previous lab, do not attempt to attack the machine during the lab by any means other than exploiting the web applications on it. We encourage you to try this at home, though (possibly after you've successfully managed to complete some of the web exploits).

Also download the the free version of Burp in your home directory and run it using:

$ java -jar ~/burpsuite_free_v1.6.jar

and configure Firefox to use the Burp proxy as mentioned in the Burp tutorial. Remember that the Proxy is very useful for us in order to intercept both HTTP requests and responses and modify them to our liking. We assume that you are using it, but you may also use other tools (e.g. the Firefox Web Console) to obtain a particular behaviour.


In the previous lab we went through a brief overview of the basics of web application security. We saw that web applications receive inputs from a variety of sources (URLs, message body, cookies, etc.) and that, like all applications, they must handle inputs carefully in order to avoid providing an attack vector for potentially malicious entities. Ultimately, bugs and/or misconfigurations in web applications cause damage not only to company owners or employees, but also to the users, either by revealing personal data, as seen for example in the Sony PSN hack, or by directly damaging the users' systems.

In this lab we will deal mostly with injection attacks. Injecting malicious payloads into web applications is conceptually identical to injecting shellcodes or ROP chains into binaries, as seen in earlier labs. However, modern web applications consist of complex software stacks, comprising general-purpose programmable runtimes (i.e. shells/scripting languages), database management systems and system administration utilities, which could possibly be used in undesirable ways by an attacker. Additionally, users/clients also normally run modern browsers capable of modifying web content dynamically through JavaScript; thus any popular site has the potential to impact thousands to millions of users by being buggy or just downright malicious.

All the DVWA tasks allow you to view the page's PHP source to get additional info about the back-end script. However, unless the lab text explicitly states otherwise, we assume that you can't access the sources, so please use this functionality only after you have finished the task. Make sure to ask the lab assistant for hints when you're stuck.

1. [1p] Warm-up task: cookie hijacking

First prepare the setup from the Burp tutorial, firing up Burp and setting up the proxy settings in Firefox. In Burp, go to Proxy / Intercept and make sure that “Intercept” is off for the moment. Next, login to Damn Vulnerable Web App (DVWA) at $SERVER_IP/~dvwa using the following credentials:

  • User: admin
  • Password: password

By looking into the lower-left corner of the DVWA interface, we notice that the application's Security Level setting is set to “high”. In principle, the “high” security setting of DVWA was made so that it's not exploitable, so we'll have to turn down the knob a bit in order to perform the following tasks.

Fortunately for us, this setting is held in a cookie that we got from the application and that – that's right, you guessed – is stored in the browser.

[1p] Inspect the requests generated by the browser to access DVWA and find the cookie that sets the security setting for the app. After finding the (obvious) cuplrit, turn on “Intercept” in Proxy, refresh the page in Firefox and alter the request in Burp so that the browser will respond with the security set to “low”. Check the DVWA web page to make sure that the app has modified the setting.

Note that altering the cookie in Burp will not make the setting permanent, as the browser still stores the cookie with the “high” setting.

To make the setting permanent (for the current session at least), find the DVWA Security option in the DVWA menu at the left of the page. There you can set the security to the level required by the particular task you'll be solving.

2. [3p] Command injection

Simply put, command injection refers to vulnerabilities that allow attackers to inject shell commands into the application's input and execute them on the remote host. We will see that improperly sanitized input fields allow us to execute virtually any command and that we are limited by how well the web server is hardened against such attacks.

In DVWA, go to the Command Execution screen. Notice that the vulnerable web application is a Ping service. Try it out on a valid IP address (e.g. and examine the output. First, try answering the following questions:

  • Can you figure out what happens behind the scenes?
  • Can you use this information to execute commands on the virtual machine?

Discuss with your lab assistant.

a. Low security

[1p] Print the contents of /etc/passwd and /proc/meminfo using the low security setting on DVWA. As what user are the commands being executed? Can you also print the contents of /etc/shadow?

b. Medium security

[2p] Same as previous, only now change DVWA's security to the medium setting.

You may have noticed that (unless you're really lucky or crafty) the previous exploit doesn't work here and the vulnerable application doesn't offer any hints as to why that happens. Still, remember that the main attack surface comes from the fact that the application executes a shell command, and your average shell implements various tricks that result in command execution. What operators (other than the semicolon) can you use to chain commands?

3. [3p] SQL injection

Before solving the SQL injection task, let's use our newfound command execution feature to attempt getting more information about the victim. We know that the application's base URL is $SERVER_IP/~dvwa, which means that there's a high chance that the server is an Apache running mod_userdir and that the application is stored in ~dvwa (dvwa's home directory). We can run ls on that:

$ ls ~dvwa
$ ls -F ~dvwa/public_html

We can try to leak the config information off the server:

$ ls ~dvwa/public_html/config
$ cat ~dvwa/public_html/config/config.inc.php

That didn't work, unfortunately! This means we might not have the rights to access config.inc.php. But that's not it! (use ls -l for that). It has to with the content of the script (PHP content being interpreted).

In order to get the content of the config.inc.php you have to ditch the first line (with the <?php content) or you can use a command to encode the output differently resulting in the PHP script not being interpreted.

Make sure to have DVWA's security setting set to low when attempting to solve this task.

To attempt the actual SQL injection, let's go to the SQL Injection page in the menu to the left. We notice that the vulnerable application asks for an user ID, which we assume represents the vulnerable unsanitized field. Let's give it some input to see if that's the case. If we give it id=3, we get the following output:

ID: 3
First name: Hack
Surname: Me

Now let's try the classical or 1=1, i.e. set the ID to 3 or 1=1:

ID: 3 or 1=1
First name: Hack
Surname: Me

Nothing happens; the application acts just like before, meaning that SQL (presumably MySQL) doesn't interpret the injected code. Now there's a big chance that the ID variable is quoted (using either single or double-quotes), so we'll add a single quote to obtain 3' or 1=1. We get the following MySQL error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1.

This means we got lucky and the ID variable is indeed quoted. However, there's a single-quote that's now unterminated, which is why we're getting this notice.

This is actually another information leak on the vulnerable application's part. If you're feeling adventurous, you can try the SQL Injection (Blind) application, which acts like this one, only it hides the extra MySQL errors.

A smart way to finish this quote would be using the 'a'='a trick; or we can just add a comment marker (-- or #) to the end of the line. This way we can make sure that we avoid executing any extra SQL code that comes after the injected code. By entering 3' or 1=1 # into the input field, we obtain:

ID: 3' or 1=1 #
First name: admin
Surname: admin

ID: 3' or 1=1 #
First name: Gordon
Surname: Brown

ID: 3' or 1=1 #
First name: Hack
Surname: Me

ID: 3' or 1=1 #
First name: Pablo
Surname: Picasso

ID: 3' or 1=1 #
First name: Bob
Surname: Smith

We managed to get a list of all the users in the database queried by the application! Here's some additional info we can gather from this output:

  • One of the users is admin, i.e. the user we're using to log in to DVWA. This means the other users also have stored passwords.
  • The MySQL query most probably selects two columns (might be three, but that's improbable since the script displays the ID we entered as input) from a table in the database – the first name and the surname – and displays all the matching rows.

A third hint that's very important is that MySQL (or rather the application's API) doesn't allow us to issue more than one select query per call. For example, let's try inputting 3' or 1=1; show databases #. We get the following MySQL error:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'show databases #'' at line 1

This aspect is very limiting, because it doesn't allow us performing arbitrary queries on the MySQL database. However, we can use the UNION operator to add additional SELECT queries to our data, e.g. 3' or 1=1 union all select col1,col2 from some_table #.

Given that the application most probably does a SELECT on exactly two columns, we can't include more than two columns in our SELECT statements, otherwise the UNION would fail.

[3p] Do the following:

  1. Use the UNION trick to list all the tables stored in the database. Query the information_schema.tables table; see the INFORMATION_SCHEMA documentation for more details.
  2. Inspect the output and find the name of the table that stores the users queried above. Use the same UNION trick to dump all the table's columns by querying information_schema.columns; see the INFORMATION_SCHEMA documentation for more details.
  3. Finally, use this info to dump all the user names and their passwords stored in the databases.

[0.5p bonus] Feed the obtained hashes to a rainbow table service such as CrackStation or HashKiller to reverse them.

4. [3p] Cross-site scripting (XSS)

Cross-site scripting (XSS) is basically an attack which allows malicious entities to inject JavaScript code into a web application. Its most dangerous aspect is the attacker's ability to include and execute remote scripts, hence the cross-site scripting nomenclature, although directly injecting code is possible. Currently there are two main types of XSS known:

  • Reflected XSS: Reflected XSS attacks are achieved by crafting malicious GET or POST requests, either directly encoded in an URL or in a malicious web page, and the vulnerable application sending the a malicious response back to the user. A typical example is the scenario in which an user clicks on a crafted URL, resulting in code being executed in the victim's browser, e.g. which sends its cookie to a third-party.
  • Stored XSS: The difference between reflected and stored XSS is that the latter is persistent, i.e. the web application stores malicious input from the attacker so that the payload will be executed at a later time, when the data is reloaded, possibly by a large number of victims. For example, imagine that a famous Twitter user could inject a malicious script into their name; then millions of people could end up executing that script!

More details on reflected versus stored XSS can be found on the OWASP wiki.

Although XSS vulnerabilities may be present in a given web application, they are very often exploited by a second (malicious) application, e.g. a site trying to steal your credentials for a social networking web application. This is ultimately what makes XSS attacks very dangerous.

Assuming that our DVWA security is set to the “low” setting for the time being, let's attempt doing a reflected XSS attack. First, select XSS reflected from the menu on the left. Now, enter the following input in the text box:

<script>alert("I pwn j00!")</script>

Notice how this generates a dialog window with the text entered in the input. Of course, a real attacker would do more than that by modifying the page's DOM tree or performing a HTTP request which sends personal data stored in your browser to a third party. Basically anyone capable to do XSS has the full power of JavaScript at their fingertips.

Make sure to have DVWA's security setting set to medium when attempting to solve the following tasks. For these particular tasks you may assume that the vulnerable application's page source is known (see the View Source button in the bottom right of the DVWA interface).

a. Reflected XSS

[1p] Go to the XSS reflected screen in DVWA. Craft a script that displays a dialog box containing your session cookie. Remember that the security level must be set to “medium”, so you can't repeat the exact pattern explained above. If you're having any trouble, look at the page source and discuss with the lab assistant.

b. Stored XSS

[2p] Go to the XSS stored screen in DVWA. Craft a script that displays the session cookie's value in the page.

Use the document.write() method.

On the medium security setting of DVWA only the “Name” field can be exploited. Notice that you can only type a limited number of characters in the field; however, that's an artificial (client-side) limitation which you can easily overcome by removing the input field's maxlength attribute in Burp or in the Firefox Web Developer toolbar (F12). If things go south with the guestbook, you can always reset the application by accessing $SERVER_IP/~dvwa/setup.php and clicking Create/Reset Database.

You can easily find the hard character number limit on the database fields where the payload is stored. Any ideas how you can do that? Hint: you can't do a buffer overflow in MySQL.

For the bonus task set DVWA's security setting to low in order to be able to store the payload in the “Message” field. Note that this is a rather difficult task and we recommend doing it at home

[4p bonus] Go to the XSS stored screen in DVWA. Craft a script that posts the session cookie's value in the guestbook by sending a HTTP POST request to the guestbook page. Note that the form submission will result in two POST requests being done: one which submits the malicious script and one which stores the cookie into the guestbook.

See the AJAX - Send a Request To a Server tutorial on w3schools to get an example of how to make POST requests in JavaScript. Also, make sure:

  • To initialize the XMLHttpRequest object.
  • That your script fits into the “Message” value posted in the database.
  • To also set the Cookie field of the HTTP header.

cns/extra/web-app-security-02.txt · Last modified: 2022/03/14 12:42 by razvan.deaconescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0