Show Menu

SQL Injection Cheat Sheet (DRAFT) by

This is a draft cheat sheet. It is a work in progress and is not finished yet.


Perhaps the most well known web app flaw
Easier to address from an app security perspe­ctive, but remains a common flaw.
Apps employ relational databases for a multitude of reasons
App interfaces to add, update and render data
Flaw originates from app allowing user-s­upplied input to be dynami­cally used in a SQL query
Numerous different Relational Database Management Systems in use including Oracle, MySQL, MSSQL

Key SQL Verbs

Retrieves data from tables, most commonly used
Add data to table
Modify existing data
Delete data in a table
Delete a table
Combine data from multiple queries

SQL Query Modifiers

Filter SQL query to apply only when a condition is met
Combine WHERE to narrow SQL query
LIMIT #1, #2
Limits rows returned to #2, many rows starting at #1, same results with LIMIT 2 OFFSET 1
Sort by column number

Important SQL Data Types

Boolean True/False
Fixed length string
Variable length string
Note: Names for data types may vary across RDBMSs

SQL Special Chatacters

' , "
String delimiter
Terminates a SQL statements
-- , # , /*
Comment delimiters
% , *
Wildcard characters
|| , + , " "
String concat­enation characters
+ , < , > , =
Mathem­atical operators
Test for equiva­lence
( )
Calling functions, sub-qu­eries, and INSERTs
Null byte

SQL Injection Example Code

Server­-side PHP code taking the value of URL query parameter name as input to SQL SELECT

$ sql="SELECT * FROM Users WHERE lname=­'$_­GET­["na­me"]­';"

The resulting query if normal input is John
URL: http:/­/ur­l/s­­p?n­ame­=John
SQL Query: SELECT * FROM Users WHERE lname=­'John';
Normal result.

Injected Input Query
Input is John'
URL: http:/­/ur­l/s­­p?n­ame­=John'
SQL Query: SELECT * FROM Users WHERE lname=­'Jo­hn'';
Stray ' causes error.

Inject Input Query 2
Input is John'; --
URL: http:/­/ur­l/s­­p?n­ame­=Jo­hn';--
SQL Query: SELECT * FROM Users WHERE lname=­'Jo­hn'­;--';
Normal results.

' or 1=1; --

A payload or variation upon that is found in most SQLi docume­ntation
The single quote* closes out any string.
The 1=1 changes query logic because it is always true.
;-- Ends the payload completing the statement and comments out the remaining code to prevent syntax errors
Note: Some RDBMS require a space after "­--" comment delimiter.

SQLi Balancing Act

Involves finding correct prefixes, payloads and suffixes to evoke desired behavior.
Signif­icant aspect of discov­ering SQLi flaws is determ­ining reusable pieces of our injection.
Most obvious balancing act is quotes.
The most common data type our input will land within are strings so proper prefixes and suffixes to accomm­odate strings are necessary.
Example with comments: John';--
SELECT...W­HERE lname=­'Jo­hn'­;--';

Example without comments: John' OR '1'='1
SELECT...W­HERE lname=­'John' OR '1'='1';

Balancing Column Numbers and Data Types

INSERT and UNION statement require us to know the number of columns required or used, otherwise a DB Syntax Error will occur
INSERT and UNION statements also require the data type associated with the columns to be compat­ible.
ORDER BY [#] is another option where the number is increm­entally increased until an error is thrown.
Note: Numbers and strings are typically compat­ible.

Discovery of SQLi

Input locations that levera­ge/­int­eract with backend DB such as login functi­ona­lity.
HTTP Request portions that are common input locations:
GET URL query parameters
POST payload
HTTP User-agent
HTTP COOKIE and User-agent are more likely to be blind.

Classes of SQLi

One vulner­ability encoun­tered in a variety of ways
Simplest catego­riz­ation is blind versus visible, but there is spectrum.
In-Ban­d/I­nline SQLi is a flaw that allows us to see the result of our injection. They are easier to discover and exploit.
Blind SQLi is the same vulner­ability but with no visible response.

Error Messages

Database Error Messages
Not only hint at the presence of SQLi but may guide us in crafting input for exploi­tation. If you see database error messages it is NOT blind SQLI
Custom Error Messages
Can require a different approach because the error will not indicate if the input is being interp­reted.

Equivalent String Injections

Inline Commenting
Concat­enation (with or without spaces)
Comment delimiters (--, /**/, #) can allow injections to succeed that would otherwise fail.
The -- and # are useful SQL suffixes.
Injecting into the middle of a SQL statem­ent­/query will not allow us to alter the rest of the SQL statement but it will show us if our input is being interp­reted on the backend when we experience custome error messages (Blind SQLi).

Binary­/Bo­olean Inference Testing

John' AND 1;#
John' AND 1=1;#
John' AND 0;#
John' AND 1=0;#
If it evaluates to True (AND 1=1) or False (AND 1=0)
Prefix: Dent' AND
Evaluates: substr­((s­elect table_name from inform­ati­on_­sch­ema.tables limit 1,),1,1) > "­a"
Suffix: ;#

Blind Timing Inferences

When there is no discer­nible output or errors the use of timing­-based inference is a viable option.
Relies on respon­siv­eness of app for the inference by artifi­cially inducing a delay when a condition evaluates.
Sleep(10) - MySQL

Out-of­-Band SQLi

No errors messages
No visible responses
No boolea­n/i­nfe­rence opport­unities without or without timing
Requires an altern­ative commun­ication channel to discover or exploit these flaws
Out-of­-Band Channels may provide for faster ex-fil­tration of some flaws suscep­tible to inference techni­ques. Typically leverages HTTP or DNS to tunnel commun­ica­tions back to attacker controlled server

Query Disclosure

UNION SELECT is used to disclose the vulnerable query we are injecting into.
John' UNION SELECT '1','2­','3', info FROM inform­ati­on_­sch­­oce­ssl­ist;#
SELECT * FROM Customers WHERE lname=­'John' UNION SELECT '1','2­','3'', info FROM inform­ati­on_­sch­­oce­ssl­ist;#'