MS SQL - Advanced SQL Injection (2002).pdf

(190 KB) Pobierz
Advanced SQL Injection In SQL Server Applications
(more) Advanced SQL Injection
Chris Anley [chris@ngssoftware.com]
18/06/2002
An NGSSoftware Insight Security Research (NISR) Publication
©2002 Next Generation Security Software Ltd
http://www.ngssoftware.com
30147030.001.png
Table of Contents
Page 2
[Abstract]
This paper addresses the subject of SQL Injection in a Microsoft SQL Server/IIS/Active
Server Pages environment, but most of the techniques discussed have equivalents in other
database environments. It should be viewed as a "follow up", or perhaps an appendix, to
the previous paper, "Advanced SQL Injection".
The paper covers in more detail some of the points described in its predecessor, providing
examples to clarify areas where the previous paper was perhaps unclear. An effective
method for privilege escalation is described that makes use of the openrowset function to
scan a network. A novel method for extracting information in the absence of 'helpful'
error messages is described; the use of time delays as a transmission channel. Finally, a
number of miscellaneous observations and useful hints are provided, collated from
responses to the original paper, and various conversations around the subject of SQL
injection in a SQL Server environment.
This paper assumes that the reader is familiar with the content of "Advanced SQL
Injection".
[Clarifications]
[Best practice]
The following measures represent the best - practice in deploying a secure SQL server
application:
Lock down the SQL server. See http://www.sqlsecurity.com for further
information on how this can be achieved.
Apply stringent network filtering to the SQL server, using IPSec, filtering routers
or some other network packet filtering mechanism. The specifics of the rule set
will depend on the environment, but the aim is to prevent direct connection to the
SQL server on TCP port 1433 and UDP port 1434 from any untrusted source.
Also ensure that the SQL server cannot connect 'out', for example on TCP 21, 80,
139, 443, 445 or 1433 or UDP 53. This is of course dependent on individual
circumstances.
Apply comprehensive input validation in any Web application that submits
queries to the server. See 'Advanced SQL Injection' for a few simple examples.
Wherever possible, restrict the actions of web applications to stored procedures,
and call those stored procedures using some 'parameterised' API. See the docs on
ADODB.Command for more information.
At the time of writing, using the ADODB.Command object (or similar) to access
parameterised stored procedures appears to be immune to SQL injection. That does not
mean that no one will be able to come up with a way of injecting SQL into an application
coded this way. It is extremely dangerous to place your faith in a single defence; best
practice is therefore to always validate all input with SQL Injection in mind.
Page 3
[Stored procedures]
The following is an excerpt from a USENET message, and reflects some common
misconceptions:
<%
strSQL = "sp_adduser '" & Replace(Request.Form("username"),"'","''") &
"','"
& Replace(Request.Form("password"),"'","''") & "'," &
Replace(Request.Form("userlevel"),"'","''")
%>
This was intended to show how a stored procedure can be safely called, avoiding SQL
injection. The name 'sp_adduser' is intended to represent some user - written stored
procedure rather than the system stored procedure of the same name.
There are two misunderstandings here; first, any query string that is composed 'on the fly'
like this is potentially vulnerable to SQL injection, even if it is calling a stored
procedure . Second, closer examination of the final parameter will reveal that it is not
delimited with single quotes. Presumably this reflects a numeric field. Were the attacker
to submit a 'userlevel' that looked like this:
1; shutdown--
…the SQL server would shut down, given appropriate privileges. Once you're submitting
arbitrary SQL, you don't need single quotes because you can use the 'char' function and
many others to compose strings for you.
[Linked servers]
Pre-authenticated links can be added between SQL servers using the
sp_addlinkedsrvlogin stored procedure. This results in an attacker being effectively
granted the ability to query the remote servers with whatever credentials were provided
when the link was added. This can often be fatal to the security of an organisation that
uses SQL replication, since an attacker may be able to tunnel attacks through several SQL
servers to a server inside the "internal" network of the organisation. Pre-authenticated
links and replication models should be carefully considered before deployment.
There are several ways of querying remote servers; the most straightforward being to use
the name of the server in a four-part object name:
select * from my_internal_server.master.dbo.sysobjects
Perhaps the most useful syntax for an attacker is the 'OPENQUERY' syntax:
select * from OPENQUERY ( [my_internal_server], 'select @@version;
delete from logs')
Page 4
This technique is an important one to an attacker, since (in our experience) pre-
authenticated links are likely to exist, and although the initial database server may be
tightly controlled, the 'back - end' server is likely to be poorly protected.
[Three tier applications and error messages]
Another popular misconception is that the SQL injection attacks described in the previous
paper do not work in 'three-tier' applications, that is, applications which use ASP as a
presentation layer, COM objects as an application layer, and SQL Server as the database
layer. This is untrue; in the absence of input validation, the application layer is vulnerable
to SQL injection in precisely the same way, and in a default configuration the error
messages will propagate to the browser.
Even if the application tier 'handles' error messages, it is still relatively straightforward
for an attacker to extract information from the database (see 'Using time delays as a
communications channel' below). The best protection is to remove the problem at source,
with input validation.
[Privilege escalation]
DBAs and Web Application Developers are becoming increasingly familiar with SQL
injection. Perhaps because of this applications are being configured more often to use low
- privileged accounts on SQL servers. While this is an encouraging trend, there are
several straightforward means to escalate privileges from a low - privileged user to an
administrative account, given the ability to submit an arbitrary query to the server. This
section describes these techniques, and discusses the countermeasures that can be taken
against them.
In general, when an attacker wishes to compromise a network, they will attempt to
determine what authentication mechanisms are in place, and then use these authentication
mechanisms to obtain access to poorly - configured administrative accounts. For
example, an attacker will commonly try blank or 'Joe' passwords for NT domain
accounts, ssh servers, FTP servers, SNMP communities and so on.
The same is true of SQL Server. If an attacker has access to an account that can issue the
'OPENROWSET' command, they can attempt to re-authenticate with the SQL Server,
effectively allowing them to guess passwords. There are several variants of the
'OPENROWSET' syntax, but the following are the most useful:
Using MSDASQL:
select * from OPENROWSET('MSDASQL','DRIVER={SQL
Server};SERVER=;uid=sa;pwd=bar','select @@version')
Using SQLOLEDB:
select * from OPENROWSET('SQLOLEDB','';'sa';'bar','select @@version')
Page 5
Zgłoś jeśli naruszono regulamin