Home SQL Injection LAB
Post
Cancel

SQL Injection LAB

It’s a write-up about the room : Try Hack Me - Room : SQL Injection LAB

Task 1 : Introduction

This room is meant as an introduction to SQL injection and demonstrates various SQL injection attacks.

Questions

Deploy the machine

Task 2 : Introduction to SQL Injection: Part 1

SQL injection is a technique through which attackers can execute their own malicious SQL statements generally referred to as a malicious payload. Through the malicious SQL statements, attackers can steal information from the victim’s database; even worse, they may be able to make changes to the database. Our employee management web application has SQL injection vulnerabilities, which mimic the mistakes frequently made by developers.

Applications will often need dynamic SQL queries to be able to display content based on different conditions set by the user. To allow for dynamic SQL queries, developers often concatenate user input directly into the SQL statement. Without checks on the received input, string concatenation becomes the most common mistake that leads to SQL injection vulnerability. Without input sanitization, the user can make the database interpret the user input as a SQL statement instead of as data. In other words, the attacker must have access to a parameter that they can control, which goes into the SQL statement. With control of a parameter, the attacker can inject a malicious query, which will be executed by the database. If the application does not sanitize the given input from the attacker-controlled parameter, the query will be vulnerable to SQL injection attack.

The following PHP code demonstrates a dynamic SQL query in a login from. The user and password variables from the POST request is concatenated directly into the SQL statement.

1
$query = "SELECT * FROM users WHERE username='" + $_POST["user"] + "' AND password= '" + $_POST["password"]$ + '";"

If the attacker supplies the value

1
' OR 1=1-- - 

inside the name parameter, the query might return more than one user. Most applications will process the first user returned, meaning that the attacker can exploit this and log in as the first user the query returned. The double-dash (--) sequence is a comment indicator in SQL and causes the rest of the query to be commented out. In SQL, a string is enclosed within either a single quote (') or a double quote ("). The single quote (') in the input is used to close the string literal. If the attacker enters

1
' OR 1=1-- - 

in the name parameter and leaves the password blank, the query above will result in the following SQL statement.

' OR 1=1-- -, the OR 1=1 part is attempting to inject a condition that is always true, effectively bypassing any password check in the query. Then, -- - is used to comment out the rest of the query, including any subsequent parts that might be added to prevent the injection.

1
SELECT * FROM users WHERE username = '' OR 1=1-- -' AND password = ''

If the database executes the SQL statement above, all the users in the users table are returned. Consequently, the attacker bypasses the application’s authentication mechanism and is logged in as the first user returned by the query.

The reason for using -- - instead of -- is primarily because of how MySQL handles the double-dash comment style.

From a -- sequence to the end of the line. In MySQL, the -- (double-dash) comment style requires the second dash to be followed by at least one whitespace or control character (such as a space, tab, newline, and so on). This syntax differs slightly from standard SQL comment syntax, as discussed in Section 1.7.2.4, “'--' as the Start of a Comment”.(dev.mysql.com)

The safest solution for inline SQL comment is to use --<space><any character> such as -- - because if it is URL-encoded into --%20- it will still be decoded as -- -. For more information, see: https://blog.raw.pm/en/sql-injection-mysql-comment/

SQL Injection 1: Input Box Non-String

When a user logs in, the application performs the following query:

1
SELECT uid, name, profileID, salary, passportNr, email, nickName, password FROM usertable WHERE profileID=10 AND password = 'ce5ca67...'

When logging in, the user supplies input to the profileID parameter. For this challenge, the parameter accepts an integer, as can be seen here:

profileID=10

Since there is no input sanitization, it is possible to bypass the login by using any True condition such as the one below as the ProfileID

1
1 or 1=1-- -

Bypass the login and retrieve the flag.

SQL Injection 2: Input Box String

This challenge uses the same query as in the previous challenge. However, the parameter expects a string instead of an integer, as can be seen here:

profileID='10'

Since it expects a string, we need to modify our payload to bypass the login slightly. The following line will let us in:

1
1' or '1'='1'-- -

Bypass the login and retrieve the flag.

SQL Injection 3 and 4: URL and POST Injection

Here, the SQL query is the same as the previous one:

1
SELECT uid, name, profileID, salary, passportNr, email, nickName, password FROM usertable WHERE profileID='10' AND password='ce5ca67...'

But in this case, the malicious user input cannot be injected directly into the application via the login form because some client-side controls have been implemented:

1
2
3
4
5
6
7
8
9
10
11
12
13
function validateform() {
    var profileID = document.inputForm.profileID.value;
    var password = document.inputForm.password.value;

    if (/^[a-zA-Z0-9]*$/.test(profileID) == false || /^[a-zA-Z0-9]*$/.test(password) == false) {
        alert("The input fields cannot contain special characters");
        return false;
    }
    if (profileID == null || password == null) {
        alert("The input fields cannot be empty.");
        return false;
    }
}

The JavaScript code above requires that both the profileID and the password only contains characters between a-z, A-Z, and 0-9. Client-side controls are only there to improve the user experience and is in no way a security feature as the user has full control over the client and the data it submits. For example, a proxy tool such as Burp Suite can be used to bypass the client side JavaScript validation (https://portswigger.net/support/using-burp-to-bypass-client-side-javascript-validation).

SQL Injection 3: URL Injection

This challenge uses a GET request when submitting the login form, as seen here:

1
http://MACHINE_IP:5000/sesqli3/login?profileID=a&password=a

The login and the client-side validation can then easily be bypassed by going directly to this URL:

1
http://MACHINE_IP:5000/sesqli3/login?profileID=-1' or 1=1-- -&password=a

The browser will automatically urlencode this for us. Urlencoding is needed since the HTTP protocol does not support all characters in the request. When urlencoded, the URL looks as follows:

1
http://MACHINE_IP:5000/sesqli3/login?profileID=-1%27%20or%201=1--%20-&password=a

The %27 becomes the single quote (') character and %20 becomes a blank space.

SQL Injection 4: POST Injection

When submitting the login form for this challenge, it uses the HTTP POST method. It is possible to either remove/disable the JavaScript validating the login form or submit a valid request and intercept it with a proxy tool such as Burp Suite and modify it:

SQL Injection 4: POST Injection burp

Questions:

What is the flag for SQL Injection 1: Input Box Non-String?

Answer: THM{dccea429d73d4a6b4f117ac64724f460}

What is the flag for SQL Injection 2: Input Box String?

Answer: THM{356e9de6016b9ac34e02df99a5f755ba}

What is the flag for SQL Injection 3: URL Injection?

Answer: THM{645eab5d34f81981f5705de54e8a9c36}

What is the flag for SQL Injection 4: POST Injection?

Answer: THM{727334fd0f0ea1b836a8d443f09dc8eb}

Task 3 : Introduction to SQL Injection: Part 2

SQL Injection Attack on an UPDATE Statement

If a SQL injection occurs on an UPDATE statement, the damage can be much more severe as it allows one to change records within the database. In the employee management application, there is an edit profile page as depicted in the following figure.

SQL Injection Update sqli

This edit page allows the employees to update their information, but they do not have access to all the available fields, and the user can only change their information. If the form is vulnerable to SQL injection, an attacker can bypass the implemented logic and update fields they are not supposed to, or for other users.

SQL Injection Update sqli

We will now enumerate the database via the UPDATE statement on the profile page. We will assume we have no prior knowledge of the database. By looking at the web page’s source code, we can identify potential column names by looking at the name attribute. The columns don’t necessarily need to be named this, but there is a good chance of it, and column names such as “email” and “password” are not uncommon and can easily be guessed.

To confirm that the form is vulnerable and that we have working column names, we can try to inject something similar to the code below into the nickName and email field:

1
asd',nickName='test',email='hacked

When injecting the malicious payload into the nickName field, only the nickName is updated. When injected into the email field, both fields are updated:

This post is licensed under CC BY 4.0 by the author.