Skip to content

SQL Syntax Material

Detection

It is possible to identify SQL injection small expressions. However, the exploitation will require the help of utility functions such as substring() and ascii(). It will also include SQL keywords such as UNION and SELECT. Finally, some table names and column names will be used to extract the database schema structure (if the table name is not brute forced or known). All those keywords are likely to be searched by WAF.

How to detect SQL injection
MySQL SQLite MSSQL Oracle PostgreSQL DB2
ad'+'min 0 0 admin
ad'||'min 0 0 admin admin admin
ad'||chr(109)||'in admin admin admin
ad'||char(109)||'in 0 admin ad109in

⛔: The query will throw an error.

White space

Whitespace alternatives by DBMS

DBMS ASCII Characters in hexadecimal
MySQL 5 09, 0A, 0B, 0C, 0D, A0, 20
MySQL 3 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 7F, 80, 81, 88, 8D, 8F, 90, 98, 9D, A0
SQLite 0A, 0D, 0C, 09, 20
MSSQL 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 20
PostgreSQL 0A, 0D, 0C, 09, 20
Oracle 11g 00, 0A, 0D, 0C, 09, 20

Query Obfuscation

Here are a few additional tricks taken from Roberto Salgado paper.

Comments

An alternative to the single characters is using empty comments.

SELECT/**/name/**/FROM/**/users/**/WHERE/**/1=1

MSSQL [Square brackets]

Microsoft DBMS allow table name to be surrounded by square brackets. Column names can be surrounded by double-quotes.

SELECT"name"FROM[sys.databases]WHERE 1=1

Oracle Hex Encode

Oracle column names can be hex-encoded.

SELECT 0x7461626c655f6e616d65 FROM all_tab_tables

Scientific expression in MySQL

When MySQL sees 1.e(abc), it will ignore the 1.e( portion because the following characters do not form a valid numeric value.

This behavior can be abused to fool libinjection tokenizer. Libinjection internally tokenizes the parameter and identifies contextual section types such as comments and strings. Libinjection sees the string 1.e as an unknown SQL keyword and concludes that it is more likely to be an English sentence than code. When libinjection is unaware of an SQL function the same behavior can be exhibited.

Attack in action

Here is a demonstration of modsecurity’s capability to block a malicious pattern for SQL injection. A forbidden page is returned which is the consequence of detection.

The input is blocked

In the following image, you can see the original request being slightly modified to bypass modsecurity and libinjection.

The request is allowed by the WAF

Source: A Scientific Notation Bug in MySQL left AWS WAF Clients Vulnerable to SQL Injection