Introduction
This series will cover my exploitation of DVWA (Damn Vulnerable Web App). The main topic I want to focus on in this blog series is using tools installed in Kali Linux, particularly Hydra, wfuzz and SQLMAP. I will be running the application via a Docker container (vulnerables/web-dvwa image) running on my Windows host machine, and the container will have port 3000 exposed. I will then run all exploits through a Kali Linux virtual machine I have running via VirtualBox. The address to reach the Docker container inside Kali will be 192.168.56.1:3000. This blog series assumes that the reader has prior knowledge in web application security and pentesting techniques/tools.
Brute Force Login (low security)
During my research of DVWA (and also through some earlier experiments with bWAPP), I have determined that wfuzz is the best password brute forcing tool to use for these scenarios. Hydra seems to be notorious for returning false positives when it encounters any sort of URL redirect, and this generally cannot be solved even with complete inclusion of every HTTP request header or cookie that the web app could provide. However wfuzz seems to work better in these situations, so wfuzz will be the tool I'll use for these challenges. Firstly, we know that the default login and password for DVWA are admin and password respectively. Therefore we will know whether the brute force attack results are correct or not. When an unsuccessful login occurs, the page renders a message stating "Username and/or password incorrect".
When a successful login occurs, the page renders a message stating "Welcome to the password protected area admin".
So let's begin.
My first step is to use Burpsuite to intercept whatever request is made when the login form is submitted. The screenshot below shows that a GET request is made to the /vulnerabilities/brute/
endpoint with parameter names username and password. This is the endpoint that I will need to feed into the password cracking tool for the upcoming attacks. I can also confirm via Burpsuite that DVWA responds with an HTTP 200 response even if the login is unsuccessful.
My first attempt of brute forcing the login page with wfuzz used the following command:
wfuzz -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -d "username=admin&password=FUZZ&Login=Login" --sc 200 -u http://192.168.56.1:3000/vulnerabilities/brute/ -v
A short description of each argument:
-c : Makes terminal output colourful
-w : Specifies that I am supplying a wordlist to attempt for the brute forcing attack. In this case, I am using dirbuster's directory-list-2.3-small.txt password list.
-d : Specifies the postdata for the request being sent to the page
--sc : Only show responses that return with a 200 code
-u : Specifies the url to launch the attack against
-v : Verbose mode, which provides more information when outputting to the terminal
I also know in advance that the correct value password is in the dictionary file at line 464.
However upon execution, wfuzz would always get redirected back to the /login.php
endpoint with an HTTP 302 redirection. Therefore I need to start including cookies and other header information to make this attack successful.
I will add in the following arguments to the command. The -b flag denotes a cookie to include in the wfuzz request, and the cookie contents can be pasted from an intercepted Burpsuite request:
-b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low"
So the terminal command now looks like this:
wfuzz -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low" -d "username=admin&password=FUZZ&Login=Login" --sc 200 -u http://192.168.56.1:3000/vulnerabilities/brute/ -v
The attack seems to operate properly, however it does not seem to successfully login. The 245 W and 4323 Ch elements denote the amount of words and characters in DVWA's response. So for the highlighted line, these values should be different than the rest given that we know the correct password should have been applied here.
Specifying that the request method should be GET (-X flag) also does not resolve the issue:
wfuzz -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low" -X GET -d "username=admin&password=FUZZ&Login=Login" --sc 200 -u http://192.168.56.1:3000/vulnerabilities/brute/ -v
Instead of specifying the "payload" using the -d flag, I'll instead try to include it directly in the URL since this is how DVWA sends the request. I actually should have noticed this earlier.
Trying this command:
wfuzz -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low" -X GET --sc 200 -u 'http://192.168.56.1:3000/vulnerabilities/brute/?username=admin&password=FUZZ&Login=Login' -v
Finally, success! Analyzing the terminal output shows that there is a different word and character count when password is used. In practice, I would either use grep or pipe the wfuzz terminal command into a file so that it would be more easily searchable. An even more convenient method would be to use Burpsuite to launch a sniper attack, because it includes data filters for easy analysis of all HTTP response contents and sizes.
Brute Force Login (medium security)
Let's try to accomplish the same brute forcing results with DVWA set to medium security now.
The intercepted request seem to be the same, with the only difference being that now the cookie must specify security=medium. The web app also seems to have a noticeable delay after submitting the login form before it re-renders with the failure message.
I'll try to use wfuzz with this command:
wfuzz -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=medium" -X GET --sc 200 -u 'http://192.168.56.1:3000/vulnerabilities/brute/?username=admin&password=FUZZ&Login=Login' -v
Wfuzz works the same as before but it is extremely slow - therefore it seems that the medium-level security feature is a timed delay before responding with the failed login message.txt
My first idea to address this issue is to improve wfuzz's speed by specifying a higher thread (concurrent attacks) count with -t 50 :
wfuzz -t 50 -c -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -b "PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=medium" -X GET --sc 200 -u 'http://192.168.56.1:3000/vulnerabilities/brute/?username=admin&password=FUZZ&Login=Login' -v
However this seems to actually make the response times from DVWA increase. Note how the connection time column continually increases now that a higher thread count has been specified:
So multithreading the attack is a possible solution for the medium security setting but not a very good one.
Doing some more research on how to get around this simply showed that most people were using Hydra and also executing the command with a high thread count. This is the only Hydra command I could get to work - I could not at all get Hydra to work when I was also trying to specify the cookie to include in the request. It is puzzling how directly copying other people's Hydra commands that clearly worked for them would not work for me.
hydra 192.168.56.1 -s 3000 -V -l admin -P /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt http-get-form "/dvwa/vulnerabilities/brute/:username=^USER^&password=^PASS^&Login=Login:Username and/or password incorrect." -f -t 64 -I
And as you can see Hydra was not successful even though we know in advance that the correct password is in the supplied wordlist. I am not confident that Hydra was even attacking the correct DVWA page since I could not get it to accept the cookies that seem to be necessary in order to navigate to the correct login form. I am confident that I prefer to use wfuzz over Hydra for web app brute forcing though.
Brute Force Login (high security)
On the high security setting, DVWA now appears to include some sort of CSRF token in the URL called user_token. Upon every submittal of the login form, the token changes value.
Trying to take the easy route and send this intercepted request to Burpsuite repeater fails, as any subsequent requests with the same token information just results in a redirection to the DVWA home page. Therefore in order to make any sort of viable brute force attack, we would need a method of dynamically retrieving this token (which can be found by inspecting the DVWA login page source).
For this blog post I am only going to link to this article (DVWA Brute Force Tutorial (High Security) | by Danny Beton | Medium) that shows how a Python script can be made to retrieve the token and brute force the login page. In the future I plan to attempt to write a C# script that completes the same task.
SQL Injection (low security)
For the SQL Injection topics I only plan to try and use SQLMAP to see what type of vulnerabilities it can detect. For hand-crafted SQL Injection attacks, see my blog series on bWAPP.
First encounter with the SQL Injection page shows that submitting the form results in a GET request with the form values assigned to the id query parameter.
Entering a value such as abc' breaks the application and reveals that MariaDB is the particular database in use. All responses still return a 200 success code. Let's see if SQLMAP can detect this.
The first command I will run is as follows:
sqlmap -v -o --level=5 --risk=3 --method=GET --cookie="PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/"
A description of what each flag is doing:
-v : Verbose (more information)
-o : Turns on all optimization switches
--level=5 : SQLMAP will use the most extensive list of tests when set to level 5
--risk=3 : SQLMAP will include detectable attacks during testing when set to level 3 (ie. secrecy of the attack is not a concern)
--method=GET : SQLMAP will perform all tests via GET requests
--cookie : Required in order to prevent URL redirects away from the page
-u : Specify the URL to attack
This command does not result in any findings, so I need to update it.
I'll specify the entire URL now and also improve the speed of testing by increasing the number of threads from 1 to 8:
sqlmap -v -o --threads=8 --level=5 --risk=3 --method=GET --cookie="PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/?id=&Submit=Submit#"
Great sign, SQLMAP detects the vulnerabilities now. It actually even corrects me by declaring that the back-end DBMS is MySQL >= 5.0 (MariaDB fork).
Submitting the form with the suggested payload string gives an immediate (though complex) starting point to begin performing some more sophisticated hand-crafted SQL injection attacks:
' UNION ALL SELECT CONCAT(0x7171716b71,0x646542725a71576877474d7954756678546e524a54577a6c66764473686f4d6e666d5257774e7648,0x71717a7871),NULL-- -
The following command dumps all tables in the database. The complete output is too large to show in this screenshot so I will instead modify the command to only dump the tables of interest.
sqlmap -v --method=GET --cookie="PHPSESSID=jf9b7iej46ar96agbb5lqjd3f5; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/?id=&Submit=Submit#" --dump-all
The following command lists all tables in the database:
sqlmap -v --method=GET --cookie="PHPSESSID=jf9b7iej46ar96agbb5lqjd3f5; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/?id=&Submit=Submit#" --tables
The following command lists all columns in the users table:
sqlmap -v --method=GET --cookie="PHPSESSID=jf9b7iej46ar96agbb5lqjd3f5; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/?id=&Submit=Submit#" users --columns
The following command dumps the user and password columns of the users table. SQLMAP also has a feature that will automatically perform dictionary-based password hash cracking:
sqlmap -v --method=GET --cookie="PHPSESSID=jf9b7iej46ar96agbb5lqjd3f5; security=low" -u "http://192.168.56.1:3000/vulnerabilities/sqli/?id=&Submit=Submit#" users -C user,password --dump
Note for future use: instead of including all cookie and URL information in the command, I can instead save the request body and headers to a file (ex. intercept the request in Burpsuite then save to a file called request) then refer to the file while executing a sqlmap command. For example, dumping all table information could be completed with the following command:
sqlmap -r request --dump-all
SQL Injection (medium security)
With the medium security setting, the web page now instead has a dropdown list with a submit button. That means I am going to need to again rely on Burpsuite to intercept some requests and identify how to craft the request for SQLMAP to test against.
Intercepting the request in Burpsuite upon pressing the Submit button looks like the screenshot below. Adding a ' character after the 1 character results in the page breaking due to SQL injection.
So I'll need to get SQLMAP to launch a POST request that includes a request body similar to id=1&Submit=Submit.
Here is the new command. Note that there is a new flag --data that includes the request body. Also note that the / character at the end of the URL path is required; I left it out at first and SQLMAP did not find any SQL injection attacks until I simply added the backslash at the very end.
sqlmap -v -o --threads=8 --level=5 --risk=3 --method=POST --cookie="PHPSESSID=eq12vf4fdgchbui9kf7k5gu922; security=medium" -u "http://192.168.56.1:3000/vulnerabilities/sqli/" --data="id=1&Submit=Submit"
Success. Thanks SQLMAP.
SQL Injection (high security)
Upon changing the security settings to high, we are greeted with some text that tells us to click on the link to change our ID.
Intercepting the request upon pressing the link shows that a GET request is being made to /vulnerabilities/sqli/session-input.php, and the cookie is PHPSESSID=5dlsl3ti5evbdo2juvml2hvte4; security=high.
A new page opens. It contains a text input field and a submit button.
Entering a value such as 3 causes the user details to render on the original DVWA webpage.
Intecepting the HTTP traffic upon pressing the Submit button looks like this:
So a POST request with a request body is being made to endpoint /vulnerabilities/sqli/session-input.php
, then a GET request is being made to endpoint /vulnerabilities/sqli/
so the page rerenders with the user details.
Adding a ' character to the end of the input form and submitting completely kills the webpage on DVWA. The only way to get rid of this error message is to logout, clear cookies and log back in. So it seems the defense here is to just make it extremely tedious to perform SQL attacks, rather than outright fix the injection issue.
Nevertheless, I'll first try to run the following command without resetting any cookies or the entire DVWA:
sqlmap -v -o --threads=8 --level=5 --risk=3 --method=POST --cookie="PHPSESSID=5dlsl3ti5evbdo2juvml2hvte4; security=high" -u "http://192.168.56.1:3000/vulnerabilities/sqli/session-input.php" --data="id=1&Submit=Submit"
However SQLMAP fails to find any exploits. Running the command again after resetting DVWA and all cookies also does not find any exploits. Therefore this method of making the SQL query a two-step process seems to be initially effective at preventing tools like SQLMAP from detecting any exploits, though I am sure we all know that this is not sufficient security against these types of attacks in the real world.