Walkthrough: SQL Injection with DVWA

The Setup 


The only tool we will use for the exploitation process, in addition to a normal browser, is Burp Suite. Start up Burp, and edit your browser's proxy settings to point to the port Burp is running on. Be sure to turn Burp proxy's intercept mode off until ready to use it.

We'll be attacking DVWA - "Damn Vulnerable Web App," which comes preinstalled in the Metasploitable 2 VM. You can download the VM here. Once the VM is set up in your hypervisor of choice, no further configuration is required. We simply navigate to the VM's IP address in our browser, click on "DVWA," and log in to the app with the credentials listed on the login page. Be sure to set the security level to "low" for this exercise.

Baseline Testing


After navigating to the vulnerable page, we see a box that takes user supplied input in the form of a user ID. Let's see what happens when we send a normal input. We'll capture the request using Burp Proxy's intercept mode, copy it to Burp's Repeater module for later manipulation, then forward it to assess the behavior of the application. First, we'll just send the number ‘1’:


After we submit, we can see the raw request in Burp's Proxy tab:


We can see that the user input is passed as a parameter in a GET request to the application server.  Next we send it to the Repeater. Right click, then hit “Send to Repeater,” or simply hit CTRL+R. Now we'll forward the request and view the page in the browser.


So it seems the application is taking our supplied id parameter, then querying the database to return a user's first and last name. It is probable that the SQL query is making a selection from a users table that most likely also contains usernames and passwords. We don't as yet know whether the request is vulnerable to injection. We'll test that next.

Testing for SQLi


On the DVWA SQL injection page, we've sent a normal request, intercepted it with Burp Proxy, then sent the request to Burp's Repeater module for us to play around with the vulnerable “id” parameter. We'll next send a basic SQL injection to confirm the vulnerability and see what happens. We navigate to the repeater tab, right-click and select “url-encode as you type” to make things easier on us, then type the following in the id parameter:

1' or 1=1#

It should look like so:


We then send the request, and view the response:


In response to our test query, the server has output the first and last names of everyone in the users table. This is a telltale sign the the request is vulnerable to injection. Our input was not properly sanitized by the application, which resulted in a  dangerous query being passed to the database that looks something like:

SELECT * FROM usertable WHERE id = '1' OR 1=1#

Now, because one of the conditions in the 'OR' clause is necessarily true, all rows in the table are selected and output in our browser. Our '#' comments out any additional code the application might add to our input, which could interfere with our injection. 

Database Enumeration and Data Exfiltration


Now that we know the application is vulnerable, next we'll try to enumerate the number of columns being selected, so that we can later craft a union statement. To do this, we'll use the ‘order by’ statement, eg. "1' order by <num>" incrementing the number until an error is reached. This error signals that we've exceeded the number of columns being selected in the query. The highest number that produces no error is the correct number of selected columns.

If we input 1' order by 1 # or 1' order by 2 #, we get no error:


  But if we input 1' order by 3# we get this:


From this we can infer that two columns are being selected in the original query. With this information, we can now begin to further enumerate the database. Next we will attempt to discover the current database name and user by injecting:

  1' union select database(),user() #

This returns:


We can see that we're running as the root user, and the current database is 'dvwa.' With this knowledge, we can now enumerate the tables and column names in our database. First we'll enumerate the tables in our database with the following injection:

1' union select table_name,2 from information_schema.tables where table_schema='dvwa' #

This gives us:


There are two tables in the database, 'guestbook' and 'users.' Of the two, 'users' probably contains the most useful information. We'll now discover what columns exist in the table, which we can then use to dump desired information from the database. To discover the columns in the user table, we'll inject the following statement:

  1' union select column_name,2 from information_schema.columns where table_name='users' #

This returns:


Now that we know the names of all the columns, we can dump whatever information we wish from the users table. If we want to dump usernames and passwords of all users, we can use the following statement:

1' union select user,password from users #

We can now see the usernames and password hashes for each user:


It is clear that this same technique can be used to dump any arbitrary data from the database, leading to a complete database breach. Next time, we'll increase the security level and try some filter evasion techniques.

Comments

Popular Posts