摘要:服務(wù)器和客戶機(jī)如何通信是木馬研究的一個(gè)核心技術(shù),該文講述了如何利用網(wǎng)絡(luò)協(xié)議躲避了防火墻和系統(tǒng)工具的檢查,成功實(shí)現(xiàn)了木馬的隱蔽通信,給出的源代碼均調(diào)試通過。
關(guān)鍵詞:木馬通信;隱藏通信
中圖分類號:TP393文獻(xiàn)標(biāo)識碼:A文章編號:1009-3044(2008)35-2481-03
Covert Technologies on Communications of Trojan Horse
ZHANG Chun-cheng, LU Gang, FENG Yuan
(PLA Artillery Academy Computer Center,Hefei 230031,China)
Abstracr:The communications between server and client is a kernel technology to research Trojan.This paper describes how to hide out inspect of firewall and system tools through network protocol, and successful implement on covert communications of Trojan. These sound codes are all debugged and passed.
Key words:communications of trojan horse;covert communications
1 引言
木馬通常需要利用一定的通信方式進(jìn)行信息交流(如接收控制者的指令、向控制端傳遞信息等)。系統(tǒng)和應(yīng)用程序一般采用 TCP/UDP 通信端口的形式與控制端進(jìn)行通信。木馬一般也是利用 TCP/UDP 端口與控制端進(jìn)行通信。通常情況下,木馬進(jìn)行通信時(shí)直接打開一個(gè)或幾個(gè)屬于自己的 TCP/UDP 端口。早期的木馬在系統(tǒng)中運(yùn)行后都是打開固定的端口,后來的木馬在植入時(shí)可隨機(jī)設(shè)定通信時(shí)打開的端口,具有了一定的隨機(jī)性。可是通過端口掃描很容易發(fā)現(xiàn)這些可疑的通信端口。事實(shí)上,目前的許多木馬檢測軟件正是通過掃描本地和遠(yuǎn)程主機(jī)系統(tǒng)中打開的已知木馬端口進(jìn)行木馬檢測的。木馬通信端口成為暴露木馬形蹤一個(gè)很不安全的因素。為此采用新技術(shù)的木馬對其通信形式進(jìn)行了隱蔽和變通,使其很難被端口掃描發(fā)現(xiàn)。
2 木馬通信形式的隱蔽技術(shù)
木馬為隱蔽通信形式所采用的手段有:端口寄生、反彈端口、潛伏技術(shù),嗅探技術(shù)。
2.1 端口寄生
端口寄生指木馬寄生在系統(tǒng)中一個(gè)已經(jīng)打開的通信端口,如 TCP 80 端口,木馬平時(shí)只是監(jiān)聽此端口,遇到特殊的指令才進(jìn)行解釋執(zhí)行。此時(shí)木馬實(shí)際上是寄生在系統(tǒng)中已有的系統(tǒng)服務(wù)和應(yīng)用程序之上的,因此,在掃描或查看系統(tǒng)中通信端口時(shí)是不會發(fā)現(xiàn)異常的。在 Windows 9X 系統(tǒng)中進(jìn)行此類操作相對比較簡單,但是在 Windows NT/2K 系統(tǒng)中實(shí)現(xiàn)端口寄生相對比較麻煩。在控制端與木馬進(jìn)行通信時(shí),如木馬所在目標(biāo)系統(tǒng)有防火墻的保護(hù),控制端向木馬發(fā)起主動連接就有可能被過濾掉。
2.2 反彈端口
反彈端口就是木馬針對防火墻所采用的技術(shù)[1]。防火墻對于向內(nèi)的鏈接進(jìn)行非常嚴(yán)格的過濾,對于向外的連接比較信任。與一般的木馬相反,反彈端口木馬使用主動端口,控制端使用被動端口。木馬定時(shí)監(jiān)測控制端的存在,發(fā)現(xiàn)控制端上線,立即主動連接控制端打開的被動端口。為了隱蔽起見,控制端的被動端口一般開在 TCP80。這樣,即使用戶使用端口掃描軟件檢查自己的端口,發(fā)現(xiàn)的也是類似 TCP USERIP:1026 CONTROLLERIP:80 ESTABLISHED 這種情況,用戶可能誤認(rèn)為是自己在瀏覽網(wǎng)頁。這種反彈端口的木馬常常會采用固定 IP 的第三方存儲空間來進(jìn)行控制端 IP 地址的傳遞。
下面的代碼演示了被控制端的客戶套接字連接控制端的服務(wù)套接字。
CServerSocket *pMy; //CServerSocket是CAsyncSocket的派生類
……
//初始化是開始連接,同時(shí)建立定時(shí)器
BOOL CServiceDlg::OnInitDialog()
{
CDialog::OnInitDialog();
pMy=NULL;
SetTimer(199,30000,NULL);
pMy=new MySock;
pMy->Create();
pMy->Connect(m_ip,80); //連接目標(biāo)的80端口,讓人感覺在上網(wǎng)
}
//在定時(shí)器中檢查是否有連接,否則試圖重新連接
Void CServiceDlg::OnTimer(UINT nIDEvent)
{
If(nIDEvent=199){
If(pMy->Send(“test”,4)=SOCKET_ERROR){
pMy->Detach();
delete pMy;
pMy=NULL;
pMy=new MySock;
pMy->Create();
pMy->Connect(m_ip,80);
}
}
CDialog::OnTimer(nIDEvent);
}
2.3 潛伏技術(shù)
ICMP(互聯(lián)網(wǎng)控制報(bào)文協(xié)議)是 IP 協(xié)議的附屬協(xié)議,用來傳遞差錯(cuò)報(bào)文以及其他需要注意的消息報(bào)文。它是由內(nèi)核或進(jìn)程直接處理而不會打開通信端口。采用潛伏技術(shù)進(jìn)行通信的木馬一般都是使用 ICMP協(xié)議。由于不利用 TCP/UDP 協(xié)議,不會打開通信端口,所以不會被一些端口掃描軟件和利用端口進(jìn)行木馬防范的軟件檢測到[2]。通常情況下,木馬利用 ICMP 報(bào)文與控制端進(jìn)行通信時(shí)將自己偽裝成一個(gè) Ping 的進(jìn)程,這樣系統(tǒng)就會將 ICMP_ECHOREPLY(Ping 的回包)的監(jiān)聽、處理權(quán)交給木馬進(jìn)程,一旦事先約定好的 ICMP_ECHOREPLY 包出現(xiàn)(可以判斷包大小、ICMP_SEQ 等特征,這此包實(shí)為控制端發(fā)給木馬的命令和數(shù)據(jù)),木馬就會接受、分析并從報(bào)文中解碼出命令和數(shù)據(jù)盡而采取相應(yīng)的操作。
有的采用潛伏技術(shù)的木馬不會完全采用 ICMP 協(xié)議進(jìn)行通信,它們只是監(jiān)聽 ICMP 報(bào)文,當(dāng)出現(xiàn)特殊的報(bào)文時(shí),例如特殊大小的包,特殊的報(bào)文結(jié)構(gòu)等,它會打開 TCP 端口等待控制端的連接。在本地可以看到狀態(tài)為 ESTABLISHED 的木馬連接(如果端口的最大連接數(shù)設(shè)為 1,在遠(yuǎn)程用 CONNECT 方法進(jìn)行端口掃描時(shí)沒有辦法發(fā)現(xiàn))。一個(gè)嚴(yán)格采用潛伏技術(shù)的木馬會嚴(yán)格地使用 ICMP 協(xié)議來進(jìn)行數(shù)據(jù)和控制命令的傳遞(數(shù)據(jù)放在 ICMP 的報(bào)文中)。
木馬利用 ICMP 協(xié)議與控制端進(jìn)行通信的基本過程如下:
為了實(shí)現(xiàn)發(fā)送/監(jiān)聽 ICMP 報(bào)文,都要首先建立 SOCK_RAW(原始套接口)。建立 SOCK_RAW 之前需要定義一個(gè) IP 首部,然后定義一個(gè) ICMP 首部:
typedef struct _ihdr {
BYTE i_type; //8 位類型
BYTE i_code; //8 位代碼
USHORT i_cksum; //16 位校驗(yàn)和
USHORT i_id; //識別號(一般用進(jìn)程號作為識別號)
USHORT i_seq; //報(bào)文序列號
ULONG timestamp; //時(shí)間戳
}IcmpHeader;
這時(shí)可以通過 WSASocket 建立一個(gè)原始套接口
SockRaw=WSASocket(
AF_INET, //協(xié)議族
SOCK_RAW, //協(xié)議類型,SOCK_R
IPPROTO_ICMP, //協(xié)議,IPPROT
NULL, //WSAPROTOCOL_INFO 置空
0, //保留字,永遠(yuǎn)置為 0
WSA_FLAG_OVERLAPPED //標(biāo)志位
);
隨后使用 fill_icmp_data 子程序填充 ICMP 報(bào)文段,調(diào)用 CheckSum 子程序計(jì)算 ICMP 校驗(yàn)和。然后通過 sendto 函數(shù)發(fā)送 ICMP_ECHOREPLY 報(bào)文:
sendto(sockRaw,icmp_data,datasize,0,(structsockaddr*)dest,sizeof(dest));
木馬控制端監(jiān)聽程序的基本操作與木馬端相同,只是需要使用 recvfrm 函數(shù)接收ICMP_ECHOREPLY 報(bào)文并用 decoder 函數(shù)將接收來的報(bào)文解碼為數(shù)據(jù)和命令:
recv_icmp=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)from,fromlen);
decode_resp(recvbuf,recv_icmp,from);
對于嚴(yán)格采用 ICMP 協(xié)議通信的木馬,除非過濾分析網(wǎng)絡(luò)鏈路層的信息或者監(jiān)視 Windows 系統(tǒng)的 Socket API 調(diào)用,否則是很難發(fā)現(xiàn)其行蹤的。
2.4 嗅探技術(shù)
2.4.1 共享環(huán)境下嗅探技術(shù)原理
嗅探技術(shù)即 sniffer 技術(shù),指在網(wǎng)絡(luò)上監(jiān)聽數(shù)據(jù)報(bào)文的方法[3]。一般來說,sniffer 技術(shù)應(yīng)用環(huán)境為共享式以太網(wǎng)(Hub-based Ethernet)。在以太網(wǎng)中,所有的通訊都是廣播的,通常在同一個(gè)網(wǎng)段的所有網(wǎng)絡(luò)接口都可以訪問在物理媒體上傳輸?shù)乃袛?shù)據(jù)。在實(shí)際系統(tǒng)中,數(shù)據(jù)的收發(fā)是由網(wǎng)卡來完成。當(dāng)收到網(wǎng)絡(luò)上傳輸來的數(shù)據(jù)時(shí),首先由網(wǎng)卡對數(shù)據(jù)幀的目的 MAC 地址進(jìn)行檢查,如果目的 MAC 地址與本地的 MAC 地址相匹配,則認(rèn)為應(yīng)接收該數(shù)據(jù)并產(chǎn)生相應(yīng)的中斷信號通知 CPU,如果不匹配,則直接丟棄該數(shù)據(jù)幀,本地計(jì)算機(jī)將根本不知道有數(shù)據(jù)幀的到來。網(wǎng)卡一般有如下 4 種接收模式:
1) 廣播方式,網(wǎng)卡能夠接收網(wǎng)絡(luò)中的廣播信息。
2) 組播方式,網(wǎng)卡能夠接收組播數(shù)據(jù)。
3) 直接方式,只有目的網(wǎng)卡才能接收該數(shù)據(jù)。
4) 混雜模式,網(wǎng)卡能夠接收一切通過的數(shù)據(jù)。
由于所有的物理信號都能被連接在該網(wǎng)絡(luò)上的計(jì)算機(jī)所接收,因此可以通過混雜模式(promiscuous mode)方式使網(wǎng)卡能夠接收到一切通過它的數(shù)據(jù),而不管實(shí)際上數(shù)據(jù)的目的地址是不是計(jì)算機(jī)。
2.4.2 Sniffer 技術(shù)的實(shí)現(xiàn)
假定攻擊者事先知道被攻擊主機(jī)所在網(wǎng)段的 IP 地址范圍,因此黑客可以構(gòu)造IP 報(bào)文,其目的地址為局域網(wǎng)內(nèi)某臺主機(jī)的地址(可以隨便設(shè)定),源地址也可以隨意設(shè)定,然后向此局域網(wǎng)內(nèi)發(fā)送報(bào)文。被攻擊主機(jī)中的木馬程序使用 sniffer 技術(shù)監(jiān)聽網(wǎng)絡(luò)數(shù)據(jù)報(bào)文,并且依據(jù)攻擊者事先設(shè)定的通信協(xié)議來辨別和提取黑客的數(shù)據(jù)報(bào)文。
實(shí)現(xiàn)時(shí)利用了 WinSock 2 的特性,可以不使用驅(qū)動程序,因此程序核心部分代碼如下。首先打開一個(gè) socket,參數(shù)必須是 AF_INET、SOCK_RAW 和 IPP不能設(shè)置 SIO_RCVALL 屬性:
m_s = socket( AF_INET , SOCK_RAW , IPPROTO_IP ) ;
然后設(shè)置該 socket 的超時(shí)參數(shù)等選項(xiàng):
int rcvtimeo = 4000 ;
if( setsockopt( m_s,SOL_SOCKET,SO_RCVTIMEO, (const cha
sizeof(rcvtimeo))==SOCKET_ERROR)
{
//錯(cuò)誤處理代碼
};
再將該 socket 與本機(jī)的某個(gè)網(wǎng)絡(luò)接口綁定。
接下來就可以設(shè)置 SIO_RCVALL 屬性。
if( SOCKET_ERROR != WSAIoctl( m_s, SIO_RCVALL , dwBuffer
sizeof(dwBufferInLen),dwBufferLen, sizeof(dwBufferLen), dwBytesRe
NULL ) )
{
// 錯(cuò)誤處理代碼
};
……
此后就可以利用這個(gè) socket(m_s)來讀取網(wǎng)絡(luò)上的數(shù)據(jù)包了。
3 結(jié)束語
該文重點(diǎn)研究了木馬系統(tǒng)中涉及到的隱蔽通信技術(shù)及實(shí)現(xiàn)。由于防火墻技術(shù)的不斷改進(jìn)和系統(tǒng)對網(wǎng)絡(luò)協(xié)議漏洞的定期修補(bǔ),木馬的通信技術(shù)將會變得更為復(fù)雜和接近底層。
參考文獻(xiàn):
[1] 朱明,徐驀,劉春明.木馬病毒分析及其檢測方法研究[J]計(jì)算機(jī)工程與應(yīng)用,2003(28):176-179.
[2] 趙樹升.計(jì)算機(jī)病毒分析與防治簡明教程[M].北京:清華大學(xué),2007.
[3] 胡勇.網(wǎng)絡(luò)嗅探器及安全對策[J].現(xiàn)代電子技術(shù),1999(4):5-6.