Skip to main content
  1. Research & Techical Notes/

Blind SQL Injection - Error SQL Injection

·1164 words·6 mins
Nguyen Hoang Thanh Phong
Author
Nguyen Hoang Thanh Phong
Senior Information Assurance student at FPT University. Focused on Web vulnerability exploitation, AWS Security Architecture, and building automated penetration tooling
Web Security IAW301 - This article is part of a series.
Part 11: This Article

Question & Answer
#

1. What is an Error-Based SQL Injection attack, and how does it differ from other types of SQL injection?

An Error-Based SQL Injection attack is a type of SQL injection where an attacker intentionally triggers database error messages to learn information about the database structure, such as table names, column names, or query logic. Unlike blind SQL injection, which requires inference from application behavior, error-based SQL injection directly reveals useful information through visible database error messages.

2. Explain the concept of using database errors to extract information, and describe the typical signs that a web application might be vulnerable to this type of attack.

Attackers use specially crafted input to cause the database to return detailed error messages. These errors may expose database type, SQL syntax, table names, or other internal details. Typical signs include visible SQL error messages, database stack traces, unexpected error pages after special characters like ' or ", and messages mentioning SQL syntax, database drivers, or query failures.

Blind SQL injection with conditional errors
#

1. Lab Objective
#

The objective of this lab was to exploit a blind SQL injection vulnerability in the TrackingId cookie. The goal was to extract the password of the administrator user and then log in as that user to solve the lab.

2. Identifying the Injection Point
#

First, I captured the request in Burp Suite and observed that the application used a TrackingId cookie.

1
Cookie: TrackingId=<tracking-value>; session=<session-value>
Capture request

I tested the TrackingId cookie because tracking cookies are commonly processed by backend SQL queries. By modifying this cookie value in Burp Repeater, I was able to observe different server responses depending on the SQL payload.

Error quote

3. Confirming Conditional Error-Based SQL Injection
#

To confirm the vulnerability, I used conditional SQL payloads that intentionally triggered a database error only when a condition was true.

The following payload caused an internal server error:

1
' UNION SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM dual-- -
CASE WHEN 1=1

Because 1=1 is true, the database evaluated TO_CHAR(1/0), which caused a divide-by-zero error. As a result, the application returned:

1
500 Internal Server Error

Then, I tested a false condition:

1
' UNION SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM dual-- -
CASE WHEN 1=2

Because 1=2 is false, the error expression was not executed and the application returned a normal page.

This confirmed that the application was vulnerable to blind SQL injection with conditional errors.

4. Confirming Oracle Database Syntax
#

The payload used Oracle-specific syntax such as dual and TO_CHAR(1/0). I also tested a simple Oracle UNION SELECT payload:

1
' UNION SELECT '1' FROM dual-- -
Compatible

The application returned a normal response, confirming that the SQL injection was compatible with Oracle syntax and that the query expected one returned column.

5. Enumerating Table Names
#

5. Enumerating Table Names
#

After confirming the conditional error-based SQL injection vulnerability, I enumerated the database tables to identify where user credentials were stored. Since the backend database used Oracle syntax, I queried the user_tables data dictionary view.

The following payload was used to check whether a table named USERS existed:

1
' AND 1=(SELECT CASE WHEN EXISTS(SELECT 1 FROM user_tables WHERE table_name LIKE 'USERS') THEN 1/0 ELSE 1 END FROM dual)-- -
Enumerate Table

The application returned a 500 Internal Server Error. This indicated that the condition was true, because the database executed 1/0 and triggered an error.

Therefore, I confirmed that the USERS table existed in the current Oracle schema.

This table was then selected as the target for further enumeration because it likely contained user account information such as usernames and passwords.

6. Enumerating Column Names in the USERS Table
#

After confirming that the application was vulnerable to conditional error-based SQL injection, I began enumerating the column names in the USERS table. Since the database was Oracle, I used the user_tab_columns data dictionary view to check whether specific column names existed.

The following payload was used to test whether a column named USER existed:

1
' AND 1=(SELECT CASE WHEN EXISTS(SELECT 1 FROM user_tab_columns WHERE column_name='USER') THEN 1/0 ELSE 1 END FROM dual)-- -
Enumerate Fail Username

The application returned a normal page instead of a 500 Internal Server Error. This means the condition was false, so the USER column did not exist.

I then continued testing other possible column names, such as USERNAME and PASSWORD, until the server returned a 500 Internal Server Error. A 500 response indicated that the tested column name existed because the true condition triggered the Oracle divide-by-zero error.

Enumerate Username Column
Enumerate Password Column

7. Determining the Password Length
#

Before extracting the password, I determined its length using the LENGTH() function.

The following payload was used:

1
' UNION SELECT CASE WHEN LENGTH(password)=20 THEN TO_CHAR(1/0) ELSE '' END FROM USERS WHERE username='administrator'-- -
Password length
Password length
Password length

The application returned a 500 Internal Server Error, meaning the condition was true. Therefore, the password length was confirmed to be 20 characters.

8. Extracting the Password Character by Character
#

After confirming the password length, I extracted the password one character at a time using the SUBSTR() function.

For example, the first character was tested using:

1
' UNION SELECT CASE WHEN SUBSTR(password,1,1)='s' THEN TO_CHAR(1/0) ELSE '' END FROM USERS WHERE username='administrator'-- -
Password enumerate

If the guessed character was correct, the server returned 500 Internal Server Error. If the guessed character was incorrect, the server returned a normal page.

The same method was repeated for each character position from 1 to 20.

9. Automating the Extraction with Turbo Intruder
#

To speed up the extraction process, I used Turbo Intruder to brute-force each character of the administrator password. The script sent requests with different character guesses and identified the correct characters by checking for HTTP 500 responses.

Turbo Intruder

The Turbo Intruder results showed the following extracted characters:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
1  s
2  p
3  1
4  g
5  b
6  k
7  w
8  u
9  l
10 y
11 1
12 h
13 8
14 h
15 p
16 y
17 u
18 a
19 j
20 g

Therefore, the recovered administrator password was:

1
sp1gbkwuly1h8hpyuajg

10. Verifying the Full Password
#

To verify the extracted password, I tested the full 20-character value using the following payload:

1
' UNION SELECT CASE WHEN SUBSTR(password,1,20)='sp1gbkwuly1h8hpyuajg' THEN TO_CHAR(1/0) ELSE '' END FROM USERS WHERE username='administrator'-- -
Test password

The application returned 500 Internal Server Error, confirming that the extracted password was correct.

11. Logging in as Administrator
#

Finally, I logged in using the recovered credentials:

1
2
Username: administrator
Password: sp1gbkwuly1h8hpyuajg

After logging in successfully, the lab displayed the “Solved” status.

Success

12. Conclusion
#

This lab demonstrated how blind SQL injection with conditional errors can be exploited even when database query results are not directly displayed in the response. By using Oracle-specific error-based payloads with CASE WHEN, TO_CHAR(1/0), LENGTH(), and SUBSTR(), I was able to extract the administrator password character by character and complete the lab successfully.

Web Security IAW301 - This article is part of a series.
Part 11: This Article