現代木馬的實現是建立在一種既可靠,又不易被宿主發現的通訊方案上的,本文就是對各種方案的實現方法,可靠性,安全性做了一些理論上的探討。充分的理解木馬的客戶端和服務端是怎么進行隱藏的,不但可以幫助您能深刻的理解網絡通信的原理,也可以更有效的做好安全防范。基于此我們編發了此文,下面我們進入正題。
首先應該明確的是受害者的機器上運行的木馬程序我們稱之為服務端,控制者機器上運行的我們稱之為客戶端(其實對于現代的木馬,已經很難說誰是客戶,誰是服務了,不過我們還是繼續用這種叫法)。另外雖然Windows9x仍然有巨大的用戶基礎,但是Windows9x向Windows XP遷徙只是早晚問題,所以這里的討論主要是針對NT/2000/XP平臺的。
1.使用TCP協議,服務端偵聽,客戶端連接。
這是最簡單,最早,最廣泛使用的一種通訊方案。使用過冰河或者被冰河客戶端掃過的對此一定不會陌生。這種通訊方案是服務端在宿主機器上開一個TCP端口,然后等待客戶端的連接,在通過對客戶端的認證后,客戶端就可以控制服務端了。由于是建立在TCP協議基礎上,所以通訊的可靠性是得到保證的。但是通訊的安全性卻很成問題。首先,使用像fport,tcpview pro這樣的工具可以很容易的發現在某一端口上偵聽的進程,以及進程對應的可執行文件。其次,在安裝了防火墻的機器上,當客戶端連接到服務端時,很容易引起防火墻報警。
2.使用TCP協議。
客戶端偵聽,服務端連接。這就是所謂的反向連接技術了。為了克服服務端在某一端口上偵聽易被發現這一缺點,現在服務端不再偵聽端口,而是去連接客戶端在偵聽的某一端口。這樣用一般的port scanner或者fport就發現不了服務端了。而為了更好的麻痹宿主機,客戶端偵聽的端口一般是21,80,23這種任何人都要訪問的端口。雖然在安裝了防火墻的機器上,服務端去連接客戶端還是要引起防火墻報警,但是一個粗心的用戶很可能會忽略“應用程序xxxxx試圖訪問xxx.xxx.xxx.xxx通過端口80”這樣的警告。
這種反向連接技術要解決的一個問題是,服務端如何找到客戶端。由于一般客戶端都是撥號上網的,沒有一個固定的IP,所以客戶端IP不可能硬編碼在服務端程序中。當然由于撥號上網用戶的IP一般都是處于一個固定的IP地址范圍內,服務端也可以掃描這個范圍,然后根據被掃描主機的反饋來確定是否是自己的客戶端,但是服務端掃描一個IP地址范圍也太。另一個方法是客戶端通過一個有固定IP或者固定域名的第三方發布自己的IP,實現的方法就很多了,比如通過一個公共的郵箱,通過一個個人主頁,就看你有多大的想象力。
3.使用UDP協議。
服務端偵聽,客戶端連接;客戶端偵聽,服務端連接。方法和安全性與使用TCP協議差不多。需要注意的是UDP不是一個可靠的協議,所以,必須在UDP協議的基礎上設計一個自己的可靠的報文傳遞協議。
4.解決防火墻問題。
無論是服務端被動偵聽,還是服務端主動連接,在服務端和客戶端試圖建立連接時都會引起防火墻得報警。畢竟粗心得用戶不會很多,所以,解決防火墻報警是服務端必須要解決的一個問題。一種方法是代碼注入,服務端將自己注入到一個可以合法的與外界進行網絡通訊的進程(比如 IE, ICQ, OICQ, TELNTED, FTPD, IIS等)的地址空間中,然后或者可以以一個新線程的形式運行,或者只是修改宿主進程,截獲宿主進程的網絡系統調用(WinSock)。后者的實現可能要麻煩一些。如果是以新線程的形式運行,那么然后或者可以被動偵聽,或者可以主動連接。
無論哪種情況都不會引起防火墻的報警(當然不是百分之百不會引起防火墻報警)。但要注意的是如果是被動偵聽的話,比如寄生在IE內,用fport會發現IE在某一個端口偵聽,這有可能會引起細心的用戶的警覺。所以比較好得方法是在新線程內去主動連接客戶端,而且連的是客戶端的80端口;如果是寄生在OICQ內,何不連接客戶端的8000端口。使用代碼注入需要服務端具有若干特權,考慮到一般用戶都是以Admin身份啟動NT的,這應該不是一個問題(如果服務端是作為一個service啟動的話,就更沒問題了)。 5.服務端主動連接時客戶端IP的公布問題。
使用第三方公布客戶端IP不是一種可靠的方法。比如如果是通過一個個人主頁發布客戶端IP的話,一旦由于種種原因,這個個人主頁被主頁提供商取消的話,服務端就找不到客戶端了。而這種個人主頁被主頁提供商取消的可能性是很大的。同時客戶端也要冒暴露自己的IP的風險。所以更好的方法是客戶端通過某種方法主動告訴服務端自己的IP和端口,然后服務端來連接。這樣可以保證最大的可靠性,安全性和靈活性。
服務端怎么收到客戶端的通知呢?一種方法是我們截獲其他進程收到的TCP數據或者UDP包,然后分析截獲的數據,從中確定是否客戶端發來了一個報告其IP的數據片斷。另一種方法是使用RAW socket來收聽ECHO REPLY類型的ICMP包,在ICMP數據包的數據去就包含了客戶端IP。而對于普通用戶來說,由于要上網瀏覽,這樣的ICMP包是很少過濾掉的。
6.用ICMP來通訊。
既然客戶端可以通過發一個ICMP(ECHO REPLY)來告訴服務端它的IP,那為什么不把所有服務端和客戶端的通訊都建立在ICMP的基礎上呢?服務端向客戶端發ICMP(ECHO REQUEST),客戶端向服務端發ICMP(ECHO REPLY),然后可以在ICMP基礎上建立一個自己的可靠數據報通訊協議。如果不怕煩的話,還可以建立一個TCP over ICMP。由于一般的用戶這兩類ICMP包都是設為無警告放行的,這種方法的隱秘性還是很強的。
7. 用自定義的協議來通訊。
我們知道IP頭的協議字段指定了這個IP包承載得數據的協議,比如TCP,UDP,ICMP等等。我們完全可以把這個字段設為我們自己定義的值(>80),定義自己的通訊協議。不過估計這種IP包將會被所有的防火墻過濾掉。
8.關于服務器上的木馬的通訊隱藏。
前面所說都是針對個人用戶(大部分都是撥號用戶,包括Modem,ISDN,ADSL,FTTX+LA,Cable Modem)。對這類機器來說,一般都沒有開什么服務,而且一般都使用了個人防火墻,同時ICMP ECHO REPLY/REQUEST都是放行的,所有才有我們上述的各種方案。而對于服務器來說,至少要開HTTP服務,同時,又一般位于專門的防火墻之后。這個專門的防火墻很可能過濾掉除類型為TCP,且目的端口為80的IP包之外的所有的IP包,更不要說各類ICMP包了。向下的方案通不過,我們可以試試向上的方案。一種方法就是注射到IIS服務的進程空間中,然后在IIS接受到木馬客戶端的請求前來個預處理,在IIS將數據發給木馬客戶端時來個后處理,不過我不知道怎么實現,不知哪為高手知道。
另一種方法就是寫一個ISAPI AP,這樣,木馬客戶端發個 "http://xxx.xxx.xxx.xxx/backdoor.dll?cmd=dir+c:"請求來發命令了。當然,一切信息都是加密得。RPC除了RPC over SMB,RPC over TCP等等外,還有一個RPC over HTTP,事實上QQ的http代理就是他自己定義的一個rpc over http,至少QQ自己是這么叫的。現在,我們也來了個rpc over http。
通訊隱藏技術只是木馬隱藏諸技術中得一部分,但也是最重要的一部分。因為他不但要保護木馬,還要保護木馬得控制者,所以不管是木馬編寫者,還是防火墻編寫者,都應該對這一部分給于足夠的重視。