Walkthrough: SQL Injection with DVWA
The Setup
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 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#
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
Post a Comment