SQL Injection

Objective

There are 5 users in the database, with id's from 1 to 5. Your mission... to steal their passwords via SQLi.

Security Level: Low

The SQL query uses RAW input that is directly controlled by the attacker. All they need to-do is escape the query and then they are able to execute any SQL query they wish. Spoiler: ?id=a' UNION SELECT "text1","text2";-- -&Submit=Submit.

  • We can provide a user ID 1 to the application.

  • So the user input is inserted in the following query:

SELECT first_name, last_name FROM users WHERE user_id = '$id';
  • Let's check the source code to see how the application behaves.

  • As we can see, the user input is not sanitized in any way. This is what leaves an application vulnerable to SQLi.

  • Let's provide the following input:

1' OR '1'='1
  • Our input causes the application to create the following query:

SELECT first_name, last_name FROM users WHERE user_id = '1' OR '1'='1';
  • As 1 is always equal to 1, all the users first and last name will be output to the page regardless of whether their id is 1 or not.

  • Our job in not done though, we need to find the passwords for the users using a UNION attack.

  • For a UNION query to work, two key requirements must be met:

    1. The individual queries must return the same number of columns.

    2. The data types in each column must be compatible between the individual queries.

  • We can find the number of columns using the following queries provided by Portswigger one by one:

' ORDER BY 1#
' ORDER BY 2# 
' ORDER BY 3#
  • We will be able to notice that the first two queries do not return any result but the third query returns a blank screen.

  • This means that there are two columns in the current table.

  • Let's create our final payload:

' UNION SELECT user, password FROM users#

Security Level: Medium

The medium level uses a form of SQL injection protection, with the function of "mysql_real_escape_string()". However due to the SQL query not having quotes around the parameter, this will not fully protect the query from being altered. The text box has been replaced with a pre-defined dropdown list and uses POST to submit the form. Spoiler: ?id=a UNION SELECT 1,2;-- -&Submit=Submit.

  • Let's first check the source code.

  • In this level our input is not inserted into quotes.

  • We can inspect the code for more information.

  • Let's change the <option> tag to the following value:

<option value="1 OR 1=1">1 OR 1=1</option>
  • In order to retrieve the passwords, we can set the <option> tag to the following value:

<option value="1 UNION SELECT user, password FROM users#">1 UNION SELECT user, password FROM users#</option>

Security Level: High

This is very similar to the low level, however this time the attacker is inputting the value in a different manner. The input values are being transferred to the vulnerable query via session variables using another page, rather than a direct GET request. Spoiler: ID: a' UNION SELECT "text1","text2";-- -&Submit=Submit.

  • Let's check the source code.

  • The application treats our input the same way it did in the low security level.

  • That means the same payload as the low security level should work in this level.

' UNION SELECT user, password FROM users#

Last updated

Was this helpful?