SQL Injection
' OR '1= '1' -- -
Last updated
' OR '1= '1' -- -
Last updated
Structured Query Language (SQL) is a language used to communicate and interact with relational databases. SQL Databases, such as PostGreSQL, MySQL, MSSQL and Oracle.
SQL Injection on the other hand, is the injection of SQL queries to manipulate the database into executing queries to extract data or even achieve command execution.
It occurs when user input is not sanitised, queries don't use parameterised variables and input is passed into queries. SQL syntax is kind of like English, so suppose have a query like this:
It uses the SELECT
verb to retrieve data, and the other variables are as follows:
products
is the table name.
category
and released
are the column names within products
WHERE
and AND
used to specify extra conditions to filter data.
Easy right? Now, suppose that a website has a login page that takes in a username and password from the user. It then authenticates users based on this query:
Now, what were to happen if a user keys in ' OR 1=1 -- -
? The resultant query (in a poorly designed application) would look like:
The first quote 'escapes' the string, and the -- -
comments the rest of the query. OR is used to create a fake logical expression, followed by 1=1
which is a true statement.
For logical OR,
statement1 OR statement2
returns true if either statement 1 or 2 is true. For logical AND, it requires both statements to be true to return true.
This is a basic SQL Injection technique, using ' OR 1=1--
to bypass a simple login that does not validate user input.
UNION is a command in SQL that allows for an additional SELECT query to be processed, and appends the results to the original query.
There are a few requirements for this to work:
Individual queries (on the LEFT and RIGHT of UNION) must return the same number of columns.
Data types in each column must be compatible between individual queries.
In other words, make sure that username and password are both strings, not integers.
To use UNION injection, one has to determine:
How many columns are present within that table?
Which columns returned from the original query are of suitable data types?
One method for determining how many columns there are is brute forcing the possible number of columns:
A query with the correct number of columns would be processed without errors. This can be indicated by the response HTTP code. For example, if a 404 is returned, then the wrong number of columns has been entered.
The reason for using NULL
is because it is convertible to every commonly used data type. This means it's kind of compatible with all of them.
All the earlier vulnerabilities return the query's result. But what if it doesn't? The backend database could simply process the request without printing it out on the screen via exception handling. This is where Blind SQLI is used to play 'hangman' with the database.
There are 2 types of Blind SQL Injection, time-based and boolean-based.
Boolean-based SQL Injection relies on the website returning different results when a true
and false
query is processed. For example, a false
condition can return a different error message or a 404.
I normally test this using one guaranteed false and true query, and then checking if the response is different:
From here, one can retrieve data character by character:
The SUBSTRING command, which would each character position indicated by <num>
until a 'true' condition is returned.
Now, suppose that the website does not have a visual difference on true or false queries, thus preventing us from guessing characters.
The sleep
function within SQL Databases can be used. A true
condition would call sleep()
, and one can measure the amount of time taken for the response to be returned: