Comprehensive DVWA Walkthrough: Low Security Level Explained Step-by-Step

I came across the DVWA lab and noticed that many people have shared walkthroughs online. However, I decided to create my own WordPress post to document and build my knowledge. Although I completed this some time ago, I never recorded the process on my blog, so I’m doing it now. While most online guides organize DVWA walkthroughs by vulnerability type, I’ll structure mine based on difficulty level. This post will focus on the Low difficulty level.

DVWA walkthrough

Introduction to DVWA

DVWA (Damn Vulnerable Web Application) is a PHP/MySQL web application designed to provide a legal environment for security professionals to test their skills and tools. It also helps web developers better understand the process of securing web applications.

DVWA consists of ten modules: Brute Force, Command Injection, CSRF (Cross-Site Request Forgery), File Inclusion, File Upload, Insecure CAPTCHA, SQL Injection, SQL Blind Injection, XSS (Reflected), and XSS (Stored).

It’s important to note that DVWA 1.9’s codebase is divided into four security levels: Low, Medium, High, and Impossible. We’ll start with the Low security level.

  • Brute Force


DVWA walkthrough

Since the DVWA login username is “admin,” we’ll start by brute-forcing the password. Entering random passwords shows an error message and reveals parameters in the URL, indicating that the request uses the GET method.

Capture the request using Burp Suite and send it to the Intruder module by pressing Ctrl+I.

Load a dictionary to prepare for brute-forcing. Weak password dictionaries are widely available online, so download a few.

Adjust the thread settings to speed up the brute-forcing process.

Start the brute force attack.

Determine success by analyzing the length of the response packets. A useful trick is to sort by the “length” field to identify discrepancies.

The password is “password.” Log in again to confirm.


  • Command Injection


The task asks us to ping an IP address. Testing with 8.8.8.8 shows that the system directly calls the “ping” command. This suggests that the parameters are concatenated without proper filtering.

By replacing the IP address with a string and appending “&” to chain additional commands, we can execute “pwd” and “whoami,” which are reflected in the output.


  • CSRF (Cross-Site Request Forgery)


The task involves changing the password. After entering the new password twice, capture the request.

Copy the CSRF HTML code generated by Burp Suite.

Save the CSRF code as an HTML file locally and open it in a browser.

Clicking the file triggers the request, and the password is successfully changed.

Causes of the CSRF vulnerability:
– Developer oversight leading to insecure web applications
– Browser handling of cookies and HTTP authentication lacks safeguards

Exploitation prerequisites:
– The user must be authenticated
– The new request does not require re-authentication or confirmation
– The attacker knows the structure of the web app’s parameters
– The user is tricked into clicking a malicious link


  • File Inclusion


The task provides three files. Clicking one reveals that the URL parameter “page” corresponds to the file name. This suggests that we can replace the file name with critical system files like “/etc/passwd.”


  • File Upload


Uploading an image reveals the upload path, suggesting that file extensions are not filtered. Uploading a simple web shell confirms this.

Access the uploaded web shell.

Many users have a misconception that because a one-liner web shell does not provide feedback, the page appears blank when accessed. In reality, it has been successfully uploaded; otherwise, it would return a 404 error. Next, we will directly use a web shell to connect.

  • Insecure CAPTCHA


Insecure CAPTCHA means an insecure verification process. CAPTCHA stands for Completely Automated Public Turing Test to Tell Computers and Humans Apart. However, I personally think that this module should be called insecure verification processes because the main issue lies in the logical flaws in the verification process, not in Google’s CAPTCHA itself.

Since applying for Google’s CAPTCHA API is too cumbersome, we will skip it. Understanding the vulnerability principle is sufficient, so let’s directly look at the source code.

Change the step to 2 when submitting.

  • SQL Injection


Manual injection approach

1. Determine if there is an injection, and whether it is character-based or numeric-based.

2. Guess the number of fields in the SQL query.

3. Identify the order of the displayed fields.

4. Retrieve the current database.

5. Retrieve the tables in the database.

6. Retrieve the column names in the tables.

7. Download the data.

Let’s use our hackbar. Since it’s an injection, start with a single quote to trigger an error and get feedback.

Continue testing to determine the type.

No return indicates it is character-based.

Next, use the order by query to find out the number of fields. When 3 causes an error, it indicates there are only 2 fields, then determine the position.

Replace with the content we want to query, such as the current database user and path.

Next, retrieve the table names in the current database using the group_concat() function.

The current database is dvwa, with two tables: guestbook and users. Extract column names.

The users table has 8 columns: user_id, first_name, last_name, user, password, avatar, last_login, failed_login. Query all users’ passwords.

  • SQL Blind Injection


This is a typical boolean-based blind injection. The approach is similar. We will use sqlmap for injection. First, capture the packet with Burp Suite, copy the content to a text file, and use sqlmap’s -r parameter to read the data packet. Save the right-side data packet as blind.txt. Adding the threads parameter helps speed up the injection.

Payload: ./sqlmap.py -r blind.txt –batch

Injection successful, next, retrieve all database names.

Payload: ./sqlmap.py -r blind.txt -dbs -threads 10

List the table names under the dvwa database.

Payload: ./sqlmap.py -r blind.txt -tables -D dvwa -threads 10

The table names match our manual injection results, proceed to extract columns.

Payload: ./sqlmap.py -r blind.txt -tables -D dvwa -T users –columns -threads 10

Extract columns and retrieve the user’s password.

Payload: ./sqlmap.py -r blind.txt -tables -D dvwa -T users -C “first_name,password” –dump -threads 10

Using sqlmap significantly improves injection efficiency.


  • XSS (Reflected)


It seems the parameter is directly printed without filtering, so we test with the simplest XSS script tag.

Payload:

The alert box appears successfully.


  • XSS (Stored)


Stored XSS is similar to functions like message boards. Use the same payload as before.

Summary:

Since the low-level difficulty is very simple, the main focus is on mastering the tools, so there’s no need to analyze it from the code level. Just practice more.