Type of SQL Injection Attack:
This section describes the following SQL injection techniques:
- Authorization bypass
- Using the SELECT command
- Using the INSERT command
- Using SQL server stored procedures
1. Authorization Bypass
The simplest SQL injection technique is bypassing logon
forms. Consider the following web application code:
SQLQuery
= "SELECT Username FROM Users WHERE Username = ‘" & strUsername
& "‘ AND Password = ‘" & strPassword & "‘"
strAuthCheck = GetQueryResult(SQLQuery) If strAuthCheck = "" Then
boolAuthenticated = False Else boolAuthenticated = True End If
Here’s what happens when a user
submits a username and password. The query will go through the Users table to
see if there is a row where the username and password in the row match those
supplied by the user. If such a row is found, the username is stored in the
variable strAuthCheck, which
indicates that the user should be authenticated. If there is no row that the
user-supplied data matches, strAuthCheck will be empty
and the user will not be authenticated.
If strUsername and strPassword can contain any characters that you want, you can modify
the actual SQL query structure so that a valid name will be returned by the
query even if you do not know a valid username or a password. How? Let’s say a
user fills out the logon form like this:
Login:
‘ OR ‘‘=‘ Password: ‘ OR ‘‘=‘
This will give SQLQuery the following value:
SELECT
Username FROM Users WHERE Username = ‘‘ OR ‘‘=‘‘ AND Password = ‘‘ OR ‘‘=‘‘
Instead of comparing the user-supplied data with that
present in the Users table, the query compares a quotation mark (nothing) to
another quotation mark (nothing). This, of course, will always return true.
(Please note that nothing is different from null.) Since all of the qualifying
conditions in the WHERE clause are now met, the application will select the username
from the first row in the table that is searched. It will pass this username to
strAuthCheck, which
will ensure our validation. It is also possible to use another row’s data,
using single result cycling techniques, which will be discussed later.
2. Using the SELECT Command
For other situations,
you must reverse-engineer several parts of the vulnerable web application’s SQL
query from the returned error messages. To do this, you must know how to
interpret the error messages and how to modify your injection string to defeat
them
Direct vs. Quoted
The first error that you normally encounter is the syntax
error. A syntax error indicates that the query does not conform to the proper
structure of an SQL query. The first thing that you need to determine is
whether injection is possible without escaping quotation.
In a direct injection, whatever argument you submit will
be used in the SQL query without any modification. Try taking the parameter’s
legitimate value and appending a space and the word “OR” to it. If that
generates an error, direct injection is possible. Direct values can be either
numeric values used in WHERE statements, such as this…
SQLString
= "SELECT FirstName, LastName, Title FROM Employees WHERE Employee =
" & intEmployeeID
…or the argument of an SQL keyword, such as table or
column name:
SQLString
= "SELECT FirstName, LastName, Title FROM Employees ORDER BY " &
strColumn
All other instances are quoted injection vulnerabilities.
In a quoted injection, whatever argument you submit has a quote prefixed and
appended to it by the application, like this:
SQLString
= "SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID =
‘" & strCity & "‘"
To “break out” of the quotes and
manipulate the query while maintaining valid syntax, your injection string must
contain a single quote before you use an SQL keyword, and end in a WHERE statement
that needs a quote appended to it. And now to address the problem of
“cheating.” Yes, SQL Server will ignore everything after a “;--” but it’s the
only server that does that.
better to learn how to do this the “hard way” so that
you’ll know how to handle an Oracle, DB/2, MySQL, or any other kind of database
server.
Basic UNION
SELECT queries are used to retrieve information from a database. Most web
applications that use dynamic content of any kind will build pages using
information returned from SELECT
queries. Most of the time, the part
of the query that you will be able to manipulate will be the WHERE clause.
To make the server return records other than those
intended, modify a WHERE clause by injecting a UNION SELECT. This allows multiple SELECT queries to be specified in one
statement. Here’s one example:
SELECT
CompanyName FROM Shippers WHERE 1 = 1 UNION ALL SELECT CompanyName FROM
Customers WHERE 1 = 1
This will return the recordsets from the first query and
the second query together. The ALL
is necessary to escape certain kinds
of SELECT DISTINCT statements. Just make sure that the first query (the one
the web application’s developer intended to be executed) returns no records.
Suppose you are working on a script with the following code:
SQLString
= "SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘"
& strCity & "‘"
And you use this injection string:
‘
UNION ALL SELECT OtherField FROM OtherTable WHERE ‘‘=‘
The following query will be sent to
the database server:
SELECT FirstName, LastName,
Title FROM Employees WHERE City = ‘‘ UNION ALL SELECT OtherField FROM
OtherTable WHERE ‘‘=‘‘
The database engine will inspect the
Employees table, looking for a row where City
is
set to “nothing.” Since it will not find it, no records will be returned. The
only records that will be returned will be from the injected query. In some
cases, using “nothing” will not work because there are entries in the table
where “nothing” is used, or because specifying “nothing” makes the web
application do something else. You simply need to specify a value that does not
occur in the table. When a number is expected, zero and negative numbers often
work well. For a text argument, simply use a string such as “NoSuchRecord” or
“NotInTable.”
Figure 1: Syntax breaking on direct injection.
The server returned the page illustrated in Figure 1 in
response to the following:
http://localhost/simpleunquoted.asp?city=-1
UNION SELECT Otherfield FROM OtherTable WHERE 1=1
A similar response was obtained with the following quoted
injection:
http://localhost/simplequoted.asp?city=’UNION
SELECT Otherfield FROM OtherTable WHERE “=’
Query Enumeration with Syntax Errors
Some database servers return the portion of the query
containing the syntax error in their error messages. In these cases you can
“bully” fragments of the SQL query from the server by deliberately creating
syntax errors. Depending on the way the query is designed, some strings will
return useful information and others will not.
Here’s my list of suggested attack strings. Several will
often return the same or no information, but there are instances where only one
of them will give you helpful information. Try them all
‘
BadValue’ ‘BadValue ‘ OR ‘ ‘ OR ; 9,9,9
Parentheses
If the syntax error contains a parenthesis in the cited
string (such as the SQL Server message used in the following example) or the
message complains about missing parentheses, add a parenthesis to the bad value
part of your injection string, and one to the WHERE clause. In some cases, you may need
to use two or more parentheses.
Here’s the code used in parenthesis.asp:
mySQL="SELECT LastName, FirstName,
Title, Notes, Extension FROM Employees WHERE (City = ‘" & strCity
& "‘)"
So, when you inject this value…
“‘) UNION SELECT OtherField FROM OtherTable WHERE (‘‘=‘”,
…the following query will be sent to the server:
SELECT
LastName, FirstName, Title, Notes, Extension FROM Employees WHERE (City = ‘‘)
UNION SELECT OtherField From OtherTable WHERE (‘‘=‘‘)
Figure
2: Parenthesis breaking on a quoted injection.
The server returned the page illustrated in Figure 2 in
response to the following:
http://localhost/parenthesis.asp?city=’
The same response was obtained with the following quoted
injection:
http://localhost/
parenthesis.asp?city=’) UNION SELECT Otherfield FROM OtherTable WHERE ( “=’
LIKE Queries
Another common debacle is being
trapped in a LIKE clause. Seeing the LIKE keyword
or percent signs cited in an error message are indications of this situation.
Most search functions use SQL queries with LIKE
clauses,
such as the following:
SQLString = "SELECT FirstName,
LastName, Title FROM Employees WHERE LastName LIKE ‘%" &
strLastNameSearch & "%’"
The percent signs are wildcards, so in this example the WHERE
clause would return true in any case
where strLastNameSearch appears
anywhere in LastName. To stop the intended query from returning records, your bad value
must be something that none of the values in the LastName field contain. The string that the web application appends
to the user input (usually a percent sign and single quote, and often parenthesis
as well) needs to be mirrored in the WHERE clause of the injection string. Also, using “nothing” as
your bad values will make the LIKE argument “%%” resulting
in a full wildcard, which returns all records. The second screenshot shows a
working injection query for the above code.
.....to be continued


No comments:
Post a Comment