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 File
→ Import 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.
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.
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.
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:
admin
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.
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.
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. 8.8.8.8
) and examine the output. First, try answering the following questions:
Discuss with your lab assistant.
[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
?
[2p] Same as previous, only now change DVWA's security to the medium setting.
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 public_html $ ls -F ~dvwa/public_html CHANGELOG.md COPYING.txt README.md about.php config/ docs/ dvwa/ [..] vulnerabilities/
We can try to leak the config information off the server:
$ ls ~dvwa/public_html/config config.inc.php $ 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.
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.
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:
admin
, i.e. the user we're using to log in to DVWA. This means the other users also have stored passwords.
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 #
.
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:
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.UNION
trick to dump all the table's columns by querying information_schema.columns
; see the INFORMATION_SCHEMA documentation for more details.[0.5p bonus] Feed the obtained hashes to a rainbow table service such as CrackStation or HashKiller to reverse them.
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:
More details on reflected versus stored XSS can be found on the OWASP wiki.
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.
[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.
[2p] Go to the XSS stored screen in DVWA. Craft a script that displays the session cookie's value in the page.
document.write()
method.
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.
[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.
XMLHttpRequest
object.Cookie
field of the HTTP header.