冰河淺析 - 揭開木馬的神秘面紗(上)
轉自INTERNET
前 言
在網上,大家最關心的事情之一就是木馬:最近出了新的木馬嗎?木馬究竟能實現哪些功能?木馬如何防治?木馬究竟是如何工作的?本文試圖以我國最著名的木馬之一 冰河為例,向大家剖析木馬的基本原理,為大家揭開木馬的神秘面紗。
木馬冰河是用C++Builder寫的,為了便於大家理解,我將用相對比較簡單的VB來說明它,其中涉及到一些WinSock編程和Windows API的知識,如果你不是很瞭解的話,請去查閱相關的資料。
一、基礎篇(揭開木馬的神秘面紗)
無論大家把木馬看得多神秘,也無論木馬能實現多麼強大的功能,木馬,其實質只是一個網絡客戶/服務程序。那麼,就讓我們從網絡客戶/服務程序的編寫開始。
1.基本概念:
網絡客戶/服務模式的原理是一台主機提供服務(服務器),另一台主機接受服務(客戶機)。作為服務器的主機一般會打開一個默認的端口並進行監聽(Listen), 如果有客戶機向服務器的這一端口提出連接請求(Connect Request), 服務器上的相應程序就會自動運行,來應答客戶機的請求,這個程序我們稱為守護進程(UNIX的術語,不過已經被移植到了MS系統上)。對於冰河,被控制端就成為一台服務器,控制端則是一台客戶機,G_server.exe是守護進程, G_client是客戶端應用程序。(這一點經常有人混淆,而且往往會給自己種了木馬!甚至還有人跟我爭得面紅耳赤,昏倒!!)
2.程序實現:
在VB中,可以使用Winsock控件來編寫網絡客戶/服務程序, 實現方法如下:
(其中,G_Server和G_Client均為Winsock控件)
服務端:
G_Server.LocalPort=7626(冰河的默認端口,可以改為別的值)
G_Server.Listen(等待連接)
客戶端:
G_Client.RemoteHost=ServerIP(設遠端地址為服務器地址)
G_Client.RemotePort=7626 (設遠程端口為冰河的默認端口,呵呵,知道嗎?這是冰河的生日哦)
(在這裡可以分配一個本地端口給G_Client, 如果不分配, 計算機將會自動分配一個, 建議讓計算機自動分配)
G_Client.Connect (調用Winsock控件的連接方法)
一旦服務端接到客戶端的連接請求ConnectionRequest,就接受連接
Private Sub G_Server_ConnectionRequest(ByVal requestID As Long)
G_Server.Accept requestID
End Sub
客戶機端用G_Client.SendData發送命令,而服務器在G_Server_DateArrive事件中接受並執行命令(幾乎所有的木馬功能都在這個事件處理程序中實現)
如果客戶斷開連接,則關閉連接並重新監聽端口
Private Sub G_Server_Close()
G_Server.Close (關閉連接)
G_Server.Listen (再次監聽)
End Sub
其他的部分可以用命令傳遞來進行,客戶端上傳一個命令,服務端解釋並執行命令......
二、控制篇(木馬控制了這個世界!)
由於Win98開放了所有的權限給用戶,因此,以用戶權限運行的木馬程序幾乎可以控制一切,讓我們來看看冰河究竟能做些什麼(看了後,你會認同我的觀點:稱冰河為木馬是不恰當的,冰河實現的功能之多,足以成為一個成功的遠程控制軟件)
因為冰河實現的功能實在太多,我不可能在這裡一一詳細地說明,所以下面僅對冰河的主要功能進行簡單的概述, 主要是使用Windows API函數, 如果你想知道這些函數的具體定義和參數, 請查詢WinAPI手冊。
1.遠程監控(控制對方鼠標、鍵盤,並監視對方屏幕)
keybd_event 模擬一個鍵盤動作(這個函數支持屏幕截圖哦)。
mouse_event 模擬一次鼠標事件(這個函數的參數太複雜,我要全寫在這裡會被編輯罵死的,只能寫一點主要的,其他的自己查WinAPI吧)
mouse_event(dwFlags,dx,dy,cButtons,dwExtraInfo)
dwFlags:
MOUSEEVENTF_ABSOLUTE 指定鼠標坐標系統中的一個絕對位置。
MOUSEEVENTF_MOVE 移動鼠標
MOUSEEVENTF_LEFTDOWN 模擬鼠標左鍵按下
MOUSEEVENTF_LEFTUP 模擬鼠標左鍵抬起
MOUSEEVENTF_RIGHTDOWN 模擬鼠標右鍵按下
MOUSEEVENTF_RIGHTUP 模擬鼠標右鍵按下
MOUSEEVENTF_MIDDLEDOWN 模擬鼠標中鍵按下
MOUSEEVENTF_MIDDLEUP 模擬鼠標中鍵按下
dx,dy:
MOUSEEVENTF_ABSOLUTE中的鼠標坐標
2.記錄各種口令信息(出於安全角度考慮,本文不探討這方面的問題,也請不要給我來信詢問)
3.獲取系統信息
a.取得計算機名 GetComputerName
b.更改計算機名 SetComputerName
c.當前用戶 GetUserName函數
d.系統路徑
Set FileSystem0bject = CreateObject("Scripting.FileSystemObject") (建立文件系統對像)
Set SystemDir = FileSystem0bject.getspecialfolder(1)
(取系統目錄)
Set SystemDir = FileSystem0bject.getspecialfolder(0)
(取Windows安裝目錄)
(友情提醒: FileSystemObject是一個很有用的對象,你可以用它來完成很多有用的文件操作)
e.取得系統版本 GetVersionEx(還有一個GetVersion,不過在32位windows下可能會有問題,所以建議用GetVersionEx
f.當前顯示分辨率
Width = screen.Width \ screen.TwipsPerPixelX
Height= screen.Height \ screen.TwipsPerPixelY
其實如果不用Windows API我們也能很容易的取到系統的各類信息,那就是Winodws的"垃圾站"-註冊表
比如計算機名和計算機標識吧:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\VNETSUP
中的Comment,ComputerName和WorkGroup
註冊公司和用戶名:
HKEY_USERS\.DEFAULT\Software\Microsoft\MS Setup (ACME)\UserInfo
至於如何取得註冊表鍵值請看第6部分
4.限制系統功能
a.遠程關機或重啟計算機,使用WinAPI中的如下函數可以實現:
ExitWindowsEx(ByVal uFlags,0)
當uFlags=0 EWX_LOGOFF 中止進程,然後註銷
=1 EWX_SHUTDOWN 關掉系統電源
=2 EWX_REBOOT 重新引導系統
=4 EWX_FORCE 強迫中止沒有響應的進程
b.鎖定鼠標
ClipCursor(lpRect As RECT)可以將指針限制到指定區域,或者用ShowCursor(FALSE)把鼠標隱藏起來也可以
注:RECT是一個矩形,定義如下:
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
c.鎖定系統 這個有太多的辦法了,嘿嘿,想Windows不死機都困難呀,比如,搞個死循環吧,當然,要想系統徹底崩潰還需要一點技巧,比如設備漏洞或者耗盡資源什麼的......
d.讓對方掉線 RasHangUp......
e.終止進程 ExitProcess......
f.關閉窗口 利用FindWindow函數找到窗口並利用SendMessage函數關閉窗口
5.遠程文件操作
無論在哪種編程語言裡, 文件操作功能都是比較簡單的, 在此就不贅述了,你也可以用上面提到的FileSystemObject對像來實現
6.註冊表操作
在VB中只要Set RegEdit=CreateObject("WScript.Shell")
就可以使用以下的註冊表功能:
刪除鍵值:RegEdit.RegDelete RegKey
增加鍵值:RegEdit.Write RegKey,RegValue
獲取鍵值:RegEdit.RegRead (Value)
記住,註冊表的鍵值要寫全路徑,否則會出錯的。
7.發送信息
很簡單,只是一個彈出式消息框而已,VB中用MsgBox("")就可以實現,其他程序也不太難的。
8.點對點通訊
呵呵,這個嘛隨便去看看什麼聊天軟件就行了
(因為比較簡單但是比較煩,所以我就不寫了,呵呵。又:我始終沒有搞懂冰河為什麼要在木馬裡搞這個東東,困惑......)
9.換牆紙
Call SystemParametersInfo(20,0,"BMP路徑名稱",&H1)
值得注意的是,如果使用了Active Desktop,換牆紙有可能會失敗,遇到這種問題,請不要找冰河和我,去找比爾蓋子吧。
三、潛行篇(Windows,一個捉迷藏的大森林)
木馬並不是合法的網絡服務程序(即使你是把木馬裝在女朋友的機子上,也是不合法的,當然,這種行為我可以理解,呵呵),因此,它必須想盡一切辦法隱藏自己,好在,Windows是一個捉迷藏的大森林!
1、在任務欄中隱藏自己:
這是最基本的了,如果連這個都做不到......(想像一下,如果Windows的任務欄裡出現一個國際象棋中木馬的圖標...@#$%!#@$...也太囂張了吧!)
在VB中,只要把form的Visible屬性設為False, ShowInTaskBar設為False, 程序就不會出現在任務欄中了。
2、在任務管理器中隱形:(就是按下Ctrl+Alt+Del時看不見那個名字叫做「木馬」的進程)
這個有點難度,不過還是難不倒我們,將程序設為「系統服務」可以很輕鬆的偽裝成比爾蓋子的嫡系部隊(Windows,我們和你是一家的,不要告訴別人我藏在哪兒...)。
在VB中如下的代碼可以實現這一功能:
Public Declare Function RegisterServiceProcess Lib "kernel32" (ByVal ProcessID As Long, ByVal ServiceFlags As Long) As Long
Public Declare Function GetCurrentProcessId Lib "kernel32" () As Long
(以上為聲明)
Private Sub Form_Load()
RegisterServiceProcess GetCurrentProcessId, 1 (註冊系統服務)
End Sub
Private Sub Form_Unload()
RegisterServiceProcess GetCurrentProcessId, 0 (取消系統服務)
End Sub
3、如何悄沒聲息地啟動:
你當然不會指望用戶每次啟動後點擊木馬圖標來運行服務端,木馬要做到的第二重要的事就是如何在每次用戶啟動時自動裝載服務端(第一重要的是如何讓對方中木馬,嘿嘿,這部分的內容將在後面提到)
Windows支持多種在系統啟動時自動加載應用程序的方法(簡直就像是為木馬特別定做的)啟動組、win.ini、system.ini、註冊表等等都是木馬藏身的好地方。冰河採用了多種方法確保你不能擺脫它(怎麼聽起來有點死纏爛打呀....哎呦,誰呀誰呀,那什麼黃鑫,不要拿雞蛋扔我!)首先,冰河會在註冊表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run和RUNSERVICE鍵值中加上了<system>\kernl32.exe(<system>是系統目錄), 其次如果你刪除了這個鍵值,自以為得意地喝著茶的時候,冰河又陰魂不散地出現了...怎麼回事?原來冰河的服務端會在c:\windows(這個會隨你windows的安裝目錄變化而變化)下生成一個叫sysexplr.exe文件(太像超級解霸了,好毒呀,冰河!),這個文件是與文本文件相關聯的,只要你打開文本(哪天不打開幾次文本?), sysexplr.exe文件就會重新生成krnel32.exe, 然後你還是被冰河控制著。(冰河就是這樣長期霸佔著窮苦勞動人民寶貴的系統資源的,555555)
4、端口
木馬都會很注意自己的端口(你呢?你關心你的6萬多個端口嗎?),如果你留意的話,你就會發現,木馬端口一般都在1000以上,而且呈越來越大的趨勢(netspy是1243....)這是因為,1000以下的端口是常用端口,佔用這些端口可能會造成系統不正常,這樣木馬就會很容易暴露; 而由於端口掃瞄是需要時間的(一個很快的端口掃瞄器在遠程也需要大約二十分鐘才能掃完所有的端口),故而使用諸如54321的端口會讓你很難發現它。在文章的末尾我給大家轉貼了一個常見木馬的端口表,你就對著這個表去查吧(不過,值得提醒的是,冰河及很多比較新的木馬都提供端口修改功能,所以,實際上木馬能以任意端口出現)
5.最新的隱身技術
目前,除了冰河使用的隱身技術外,更新、更隱蔽的方法已經出現,那就是-驅動程序及動態鏈接庫技術(冰河3.0會採用這種方法嗎?)。
驅動程序及動態鏈接庫技術和一般的木馬不同,它基本上擺脫了原有的木馬模式-監聽端口,而採用替代系統功能的方法(改寫驅動程序或動態鏈接庫)。這樣做的結果是:系統中沒有增加新的文件(所以不能用掃瞄的方法查殺)、不需要打開新的端口(所以不能用端口監視的方法查殺)、沒有新的進程(所以使用進程查看的方法發現不了它,也不能用kill進程的方法終止它的運行)。在正常運行時木馬幾乎沒有任何的症狀,而一旦木馬的控制端向被控端發出特定的信息後,隱藏的程序就立即開始運作......
事實上,我已經看到過幾個這樣類型的木馬,其中就有通過改寫vxd文件建立隱藏共享的木馬...(江湖上又將掀起新的波浪)