SQL Injection targets AWS S3 Buckets and Azure Data blob
According to a vulnerability report made by Edgescan, SQL Injection accounts for 42% of the critical vulnerabilities found in the internet-facing infrastructure of companies.
SQLI also ranked first in 2017 and third in 2021 on OWASP Top 10, a list made by the OWASP Foundation that introduces the most critical vulnerabilities in web applications.
In 2020, a data breach caused by a successful SQL Injection attack caused a leakage of 8.3 million addresses and hashed passwords from Freepik Company. The passwords were easily crackable because of a weak hashing algorithm that was used.
Even today SQL Injections are posing the main threat to breach of users data.
SQL injection -- I think that's what's going to rapidly approach and replace that as [a top] data protection issue is going to be people who store my data in an open bucket, say an S3 bucket or an Azure Data Blob somewhere and it's not protected,
Karen Lopez said in her interview about a week ago.
Table of Contents
Disclaimer: The attack replicated in this article was performed on a machine in a safe environment, made especially for this. Please do not attack anyone without their written consent.
Real-life examples of SQL Injection
The OWASP Foundation released the top 10 web application vulnerabilities. For the year 2021, SQLI is the third most common vulnerability, while in 2017 it ranked first.
In this chapter, we will see two real-life examples using their platform The Juice Shop. The Juice Shop is a website that has many vulnerabilities and was created especially for professionals in cybersecurity to take on challenges and learn how to protect their products.
Here is the website:
These vulnerabilities may appear trivial, but unfortunately, they exist out there.
Log in as administrator
Now, before diving into this web application, we must first understand what a statement is and what’s the simplest way it can be exploited.
Let’s take for example the SELECT statement and see how easily it can be bypassed.
SELECT username, password, name, address FROM users WHERE username = ‘$username’ AND password = ‘$password’;
This simple SELECT statement retrieves the username, password, name, and home address of the users that try to log in by identifying them with a username and a password introduced in the input fields of the application.
Of course, a normal user would just provide their credentials. Unfortunately, a malicious user can easily bypass it. Let’s see how we can log in.
Let’s suppose we don’t even know a valid username of another user’s. We will use the username “admin” (or “administrator”, they are both quite common). We alter the statement by typing the following thing in the username input field:
admin’ or 1=1 --
This may seem weird, but let me show you what the final statement looks like:
SELECT username, password, name, address FROM users WHERE username = ‘admin’ or 1=1
For the username parameter, we’re saying: match the user with the username ‘admin’ OR where 1=1. However, 1=1 will always be true. Therefore, the SELECT statement will always work and we can log in as the administrator without knowing their password.
You can therefore see how dangerous SQLI can be.
Let’s see this in practice in The Juice Shop!
Of course, the statement behind this web application may be different. We don’t know what the first half of the statement is, but we do know that it probably has a WHERE part, which we can exploit.
It worked! And even though we didn’t even know the username of a valid user, we managed to log in, as you can see below.
Dump the entire database schema
There are other ways in which SQL injection can be used; for example, for retrieving data from the database or examining its schema.
This time, we’re going to exploit the ‘search’ feature of the website and we’re going to try to dump the entire database, with all of its tables and columns.
We’ll do this by adding a UNION along with a SELECT statement.
This time, as it is a slightly more complicated injection, I will use Burp Suite, an application security testing software, to demonstrate this attack. This application intercepts the traffic before sending it to the server and allows me to edit my web requests.
In the following image you can see, on the left, the request, and on the right, the result. I searched for ‘apple’ in the search bar and I got back two products. Now, let’s exploit this request.
Here is what I’m adding to the request:
‘)) UNION SELECT * FROM sqlite_master –
What I’m doing is: I’m concatenating my own SELECT, which does whatever I want, to the initial statement. I’m choosing to retrieve everything from the table sqlite_master. Sqlite_master contains all of the information of the database and its objects.
One thing to note: after adding my payload, I URL-encoded it. That is because URLs only accept certain characters.
This is not really what we want. I’m getting the following error:
SQLITE_ERROR: SELECTs to the left and right of UNION do not have the same number of result columns
This means that the SELECT the web server is performing fetches more rows than we’re fetching with our own SELECT. Therefore, we will just add columns, one by one, to match the results. After adding columns from 1 to 9, I do not get an error anymore.
Now, the only thing to do is retrieve the tables. After doing a quick google search, I find that the column “sql” describes the objects in the table sqlite_master. This is all we need to do a complete database schema reveal.
apple')) UNION SELECT sql, 2, 3, 4, 5, 6, 7, 8, 9 FROM sqlite_master –
What is SQL Injection?
SQLI is a procedure that exploits input requests by writing malicious SQL code to force users to unknowingly run SQL statements on a database. Such efforts to inject code can:
- modify or delete database data,
- enable reading sensitive information,
- or even shut down a DBMS.
SQL Injection usually involves changing the purpose of the queries, but a hacker can also gather information and reach their objective by causing an error or delaying a command.
In a later chapter, you will see examples of SQL Injection performed on a website.
How to protect your application against SQL Injection
A way of dealing with these types of vulnerabilities is by placing validation policies on the input received from users.
This can mean:
- not accepting meta characters (i.e., single or double quotes),
- limiting the amount of data accepted,
- restricting the user to a set of allowed values (for example, don’t let them type the name of their country, but rather provide a list of countries).
However, it is very difficult to think of all of the possible vulnerabilities a piece of code may have. There are many ways in which SQL queries can be exploited, as seen in the previous chapter. At some point, intruders may find a way around validation policies.
Therefore, it is very important to take extra measures, besides sanitizing the input accepted from users.
Use prepared statements
A more versatile and efficient way of protecting your application from SQL Injection is the use of Prepared Statements (or parameterized statements).
A prepared statement is a stored procedure that does not concatenate the query string and compiles it, but rather keeps the command compiled and executes the statement every time. This is efficient because the statement is only compiled once, so the overhead decreases.
It prevents SQL injection because it uses placeholders in the query string. Every parameter is checked if it is correct and if its data type corresponds to the database column type first.
Use scanning tools to search for vulnerabilities
Sqlmap is an automated tool that performs SQL injection in your place. You do not have to create payloads, encode them and test them on each parameter; it does it for you.
Sqlmap supports MySQL, SQL Server, Oracle, SQLite, and others.
Let’s see the example above, which required quite a few steps. I issued the following command and got the detailed database schema along with its contents, without having to manually type the payload.
sqlmap -u 'http://localhost:3000/rest/products/search?q=test' -p 'q' --dbms="sqlite" --technique U --prefix "')) " --level 5 --risk 3 --dump-all --no-cast --no-escape --flush
In the given command I used:
- -u for the URL, -p for the parameter tested
- --technique with the U argument to use UNION
- --prefix to match the server’s statement
- --level 5 and –risk 3 to indicate that we do not intend to be stealthy (in the case of a penetration test we would have to be more careful)
- --dump-all to dump all DBMS databases tables entries
- --no-cast to turn off payload casting mechanisms
- --no-escape to turn off string escaping mechanism
Here are some of the results:
Considering how easy it is to completely compromise a database, make sure you take the recommended measures to protect your application from SQL Injection.
You should test for vulnerabilities (you can do it manually, just like I showed you, and using sqlmap), use parameterized statements in your queries, and sanitize the input you’re receiving from users.
It is important to note that there are many ways in which SQL Injection can be performed. With the right statements, you can even drop tables or delete information stored in them.
Your email address will not be published. Required fields are marked