Web
Applications and SQL Injection
SQL injection is a technique for exploiting web
applications that use client-supplied data in SQL queries, but without first
stripping potentially harmful characters. Despite being remarkably simple to
protect against, there is an astonishing number of production systems connected
to the Internet that are vulnerable to this type of attack. The objective of
this article is to focus the techniques that can be used to take advantage of a
web application that is vulnerable to SQL injection, and to make clear the
correct mechanisms that should be put in place to protect against SQL injection
and input validation problems in general.
Character Encoding
Most web browsers will not properly
interpret requests containing punctuation characters and many other symbols
unless they are URL-encoded. In this article, I have used regular ASCII
characters in the examples and screenshots to maintain maximum readability. In
practice, though, you will need to substitute %25 for percent sign, %2B for
plus sign, etc., in the HTTP request statement.
Testing for Vulnerability
Thoroughly checking a web application
for SQL injection vulnerability takes more effort than one might guess. It’s
nice when you throw a single quote into the first argument of a script and the
server returns a nice blank, white screen with nothing but an ODBC error on it,
but such is not always the case.
It is very easy to overlook a perfectly vulnerable script
if you don’t pay attention to details.
You should always check every parameter of every script on
the server. Developers and development teams can be awfully inconsistent. The
programmer who designed Script A might have had nothing to do with the
development of Script B, so where one might be immune to SQL injection,
the other might be ripe for abuse. In fact, the programmer who worked on Function
A in Script A might have nothing to do with Function B in Script
A, so while one parameter in one script might be vulnerable, another might
not. Even if an entire web application is conceived, designed, coded and tested
by one programmer, one vulnerable parameter might be overlooked. You never can
be sure. Test everything.
Testing procedure
Replace the argument of each parameter with a single quote
and an SQL keyword (such as "‘ WHERE"). Each parameter needs to be tested individually. Not
only that, but when testing each parameter, leave all of the other parameters
unchanged, with valid data as their arguments. It can be tempting to simply
delete everything you’re not working with to make things look simpler,
particularly with applications that have parameter lines that go into many
thousands of characters. Leaving out parameters or giving other parameters bad
arguments while you’re testing another for SQL injection can break the
application in other ways that prevent you from determining whether or not SQL
injection is possible. For instance, assume that this is a completely valid,
unaltered parameter line
ContactName=Marco%20Anders&CompanyName=Amredo%20Corporation
While this parameter line gives you an
ODBC error
ContactName=Marco%20Anders&CompanyName=‘%20OR
And checking with this line might simply return an error
indicating that you need to specify a ContactName value.
CompanyName=‘
This line…
ContactName=BadContactName&CompanyName=‘
…might give you the same page as the request that didn’t
specify ContactName at all. Or, it might give you the
site’s default homepage. Or, perhaps when the application couldn’t find the
specified ContactName, it didn’t
bother to look at CompanyName, so it didn’t even pass the argument of that parameter into
an SQL statement. Or, it might give you something completely different. So,
when testing for SQL injection, always use the full parameter line, giving
every argument except the one that you are testing a legitimate value.
Evaluating Results
If the server returns a database error message of some
kind, injection was definitely successful. However, the messages aren’t always
obvious. Again, developers do some strange things, so you should look in every
possible place for evidence of successful injection. First, search through the
entire source of the returned page for phrases such as “ODBC,” “SQL Server,”
“Syntax,” etc. More details on the nature of the error can be in hidden input,
comments, etc. Check the headers. I have seen web applications on production
systems that return an error message with absolutely no information in the body
of the HTTP response, but that have the database error message in a header.
Many web applications have these kinds of features built into them for
debugging and QA purposes, and then developers forget to remove or disable them
before release.
You should look not only on the immediately returned page, but
also in linked pages. During a recent penetration test, I saw a web application
that returned a generic error message page in response to an SQL injection
attack. Clicking on a stop sign image next to the error retrieved another page
giving the full SQL Server error message.
Another thing to watch out for is a 302 page redirect. You may be
whisked away from the database error message page before you even get a chance
to notice it.
Note that SQL injection may be successful even if the server
returns an ODBC error messages. Many times the server returns a properly
formatted, seemingly generic error message page telling you that there was “an
internal server error” or a “problem processing your request.”
Some web applications are designed to
return the client to the site’s main page whenever any type of error occurs. If
you receive a 500 Error page back, chances are that injection is occurring.
Many sites have a default 500 Internal Server Error page that claims that the
server is down for maintenance, or that politely asks the user to send an
e-mail to their support staff. It can be possible to take advantage of these
sites using stored procedure techniques, which are discussed later.
Attacks
This section describes the following SQL injection
techniques:
-Authorization bypass
-Using the SELECT command
-Using the INSERT command
-Using SQL server stored procedures
No comments:
Post a Comment