詞語解釋
“嗅探”是指在網(wǎng)絡(luò)中對數(shù)據(jù)包進行監(jiān)聽和抓取的行為,又稱為網(wǎng)絡(luò)嗅探、網(wǎng)絡(luò)監(jiān)聽或網(wǎng)絡(luò)抓包。它是一種網(wǎng)絡(luò)安全技術(shù),可以用來檢測網(wǎng)絡(luò)中的惡意行為,如攻擊、偷竊、欺詐等。 嗅探可以幫助網(wǎng)絡(luò)管理員發(fā)現(xiàn)網(wǎng)絡(luò)中的潛在威脅,以便采取相應的措施。它可以用來檢測網(wǎng)絡(luò)中的惡意軟件,并及時采取措施以防止攻擊。嗅探還可以幫助網(wǎng)絡(luò)管理員發(fā)現(xiàn)網(wǎng)絡(luò)中的安全漏洞,以便及時修復。 嗅探也可以用于監(jiān)控網(wǎng)絡(luò)上的用戶行為,以便及時發(fā)現(xiàn)網(wǎng)絡(luò)中的不當行為,如網(wǎng)絡(luò)盜竊、網(wǎng)絡(luò)欺詐等。此外,嗅探還可以幫助網(wǎng)絡(luò)管理員發(fā)現(xiàn)網(wǎng)絡(luò)中的性能問題,以便及時解決。 嗅探技術(shù)可以在網(wǎng)絡(luò)中監(jiān)控數(shù)據(jù)流量,以發(fā)現(xiàn)潛在的安全威脅和性能問題。嗅探技術(shù)可以幫助網(wǎng)絡(luò)管理員及時發(fā)現(xiàn)網(wǎng)絡(luò)中的安全漏洞和惡意行為,以便及時采取措施。此外,嗅探技術(shù)還可以用于監(jiān)控網(wǎng)絡(luò)上的用戶行為,以便及時發(fā)現(xiàn)網(wǎng)絡(luò)中的不當行為。 嗅探 sniff。嗅探器可以竊聽網(wǎng)絡(luò)上流經(jīng)的數(shù)據(jù)包。 用集線器hub組建的網(wǎng)絡(luò)是基于共享的原理的, 局域網(wǎng)內(nèi)所有的計算機都接收相同的數(shù)據(jù)包, 而網(wǎng)卡構(gòu)造了硬件的“過濾器“ 通過識別MAC地址過濾掉和自己無關(guān)的信息, 嗅探程序只需關(guān)閉這個過濾器, 將網(wǎng)卡設(shè)置為“混雜模式“就可以進行嗅探 用交換機switch組建的網(wǎng)絡(luò)是基于“交換“原理的 ,交換機不是把數(shù)據(jù)包發(fā)到所有的端口上, 而是發(fā)到目的網(wǎng)卡所在的端口。 這樣嗅探起來會麻煩一些,嗅探程序一般利用“ARP欺騙“的方法 ,通過改變MAC地址等手段,欺騙交換機將數(shù)據(jù)包發(fā)給自己, 嗅探分析完畢再轉(zhuǎn)發(fā)出去 一 前言 SNIFF真是一個古老的話題,關(guān)于在網(wǎng)絡(luò)上采用SNIFF來獲取敏感信息已經(jīng)不是什么新鮮事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢?SNIFF就是嗅探器,就是竊聽器,SNIFF靜悄悄的工作在網(wǎng)絡(luò)的底層,把你的秘密全部記錄下來?催^威爾史密斯演的《全民公敵》嗎?SNIFF就象里面精巧的竊聽器一樣,讓你防不勝防。 SNIFF可以是軟件,也可以是硬件,既然是軟件那就要分平臺,有WINDOWS下的、UNXI下的等,硬件的SNIFF稱為網(wǎng)絡(luò)分析儀,反正不管硬件軟件,目標只有一個,就是獲取在網(wǎng)絡(luò)上傳輸?shù)母鞣N信息。本文僅僅介紹軟件的SNIFF。 當你舒適的坐在家里,愜意的享受網(wǎng)絡(luò)給你帶來的便利,收取你的EMAIL,購買你喜歡的物品的時候,你是否會想到你的朋友給你的信件,你的信用卡帳號變成了一個又一個的信息包在網(wǎng)絡(luò)上不停的傳送著,你是否曾經(jīng)這些信息包會通過網(wǎng)絡(luò)流入別人的機器呢?你的擔憂不是沒有道理的,因為SNIFF可以讓你的擔憂變成實實在在的危險。就好像一個人躲在你身后偷看一樣。。。。。。 二 網(wǎng)絡(luò)基礎(chǔ)知識 “網(wǎng)絡(luò)基礎(chǔ)知識”,是不是聽起來有點跑題了?雖然聽起來這和我們要談的SNIFF沒什么關(guān)系,可是還是要說一說的,萬丈高樓平地起,如果連地基都沒打好,怎么蓋樓?!如果你對網(wǎng)絡(luò)還不是十分清楚的話,最好能靜下心來好好看看,要知道,這是基礎(chǔ)的基礎(chǔ),在這里我只是簡單的說一下,免得到時候有人迷糊,詳細的最好能夠自己去找書看看。 。1)TCP/IP體系結(jié)構(gòu) 開放系統(tǒng)互連(OSI)模型將網(wǎng)絡(luò)劃分為七層模型,分別用以在各層上實現(xiàn)不同的功能,這七層分別為:應用層、表示層、會話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層及物理層。而TCP/IP體系也同樣遵循這七層標準,只不過在某些OSI功能上進行了壓縮,將表示層及會話層合并入應用層中,所以實際上我們打交道的TCP/IP僅僅有5層而已,網(wǎng)絡(luò)上的分層結(jié)構(gòu)決定了在各層上的協(xié)議分布及功能實現(xiàn),從而決定了各層上網(wǎng)絡(luò)設(shè)備的使用。實際上很多成功的系統(tǒng)都是基于OSI模型的,如:如幀中繼、ATM、ISDN等。 TCP/IP的網(wǎng)絡(luò)體系結(jié)構(gòu)(部分) 從上面的圖中我們可以看出,第一層物理層和第二層數(shù)據(jù)鏈路層是TCP/IP的基礎(chǔ),而TCP/IP本身并不十分關(guān)心低層,因為處在數(shù)據(jù)鏈路層的網(wǎng)絡(luò)設(shè)備驅(qū)動程序?qū)⑸蠈拥膮f(xié)議和實際的物理接口隔離開來。網(wǎng)絡(luò)設(shè)備驅(qū)動程序位于介質(zhì)訪問子層(MAC)。2)網(wǎng)絡(luò)上的設(shè)備 中繼器:中繼器的主要功能是終結(jié)一個網(wǎng)段的信號并在另一個網(wǎng)段再生該信號,一句話,就是簡單的放大而已,工作在物理層上! 網(wǎng) 橋:網(wǎng)橋使用MAC物理地址實現(xiàn)中繼功能,可以用來分隔網(wǎng)段或連接部分異種網(wǎng)絡(luò),工作在數(shù)據(jù)鏈路層。 路由器:路由器使用網(wǎng)絡(luò)層地址(IP,X.121,E.164等),主要負責數(shù)據(jù)包的路由尋徑,也能處理物理層和數(shù)據(jù)鏈路層上的工作。 網(wǎng) 關(guān):主要工作在網(wǎng)絡(luò)第四層以上,主要實現(xiàn)收斂功能及協(xié)議轉(zhuǎn)換,不過很多時候網(wǎng)關(guān)都被用來描述任何網(wǎng)絡(luò)互連設(shè)備。 。3)TCP/IP與以太網(wǎng) 以太網(wǎng)和TCP/IP可以說是相互相成的,可以說兩者的關(guān)系幾乎是密不可分,以太網(wǎng)在一二層提供物理上的連線,而TCP/IP工作在上層,使用32位的IP地址,以太網(wǎng)則使用48位的MAC地址,兩者間使用ARP和RARP協(xié)議進行相互轉(zhuǎn)換。從我們上面TCP/IP的模型圖中可以清楚的看到兩者的關(guān)系。 載波監(jiān)聽/沖突檢測(CSMA/CD)技術(shù)被普遍的使用在以太網(wǎng)中,所謂載波監(jiān)聽是指在以太網(wǎng)中的每個站點都具有同等的權(quán)利,在傳輸自己的數(shù)據(jù)時,首先監(jiān)聽信道是否空閑,如果空閑,就傳輸自己的數(shù)據(jù),如果信道被占用,就等待信道空閑。而沖突檢測則是為了防止發(fā)生兩個站點同時監(jiān)測到網(wǎng)絡(luò)沒有被使用時而產(chǎn)生沖突。以太網(wǎng)采用廣播機制,所有與網(wǎng)絡(luò)連接的工作站都可以看到網(wǎng)絡(luò)上傳遞的數(shù)據(jù)。 為了加深你的理解,我們來看看下面的圖,一個典型的在以太網(wǎng)中客戶與服務器使用TCP/IP協(xié)議的通信 以太網(wǎng) 唆唆了這么多,有人煩了吧?相信我,這是基礎(chǔ)的基礎(chǔ),可以說是說得是很簡單拉,如果需要,拿出個幾十萬字來說上面的內(nèi)容,我想也不嫌多,好了,讓我們進入下一節(jié),sniff的原理。 三 SNIFF的原理 要知道在以太網(wǎng)中,所有的通訊都是廣播的,也就是說通常在同一個網(wǎng)段的所有網(wǎng)絡(luò)接口都可以訪問在物理媒體上傳輸?shù)乃袛?shù)據(jù),而每一個網(wǎng)絡(luò)接口都有一個唯一的硬件地址,這個硬件地址也就是網(wǎng)卡的MAC地址,大多數(shù)系統(tǒng)使用48比特的地址,這個地址用來表示網(wǎng)絡(luò)中的每一個設(shè)備,一般來說每一塊網(wǎng)卡上的MFC地址都是不同的,每個網(wǎng)卡廠家得到一段地址,然后用這段地址分配給其生產(chǎn)的每個網(wǎng)卡一個地址。在硬件地址和IP地址間使用ARP和RARP協(xié)議進行相互轉(zhuǎn)換。 在正常的情況下,一個網(wǎng)絡(luò)接口應該只響應這樣的兩種數(shù)據(jù)幀: 1.與自己硬件地址相匹配的數(shù)據(jù)幀!2.發(fā)向所有機器的廣播數(shù)據(jù)幀。 在一個實際的系統(tǒng)中,數(shù)據(jù)的收發(fā)是由網(wǎng)卡來完成的,網(wǎng)卡接收到傳輸來的數(shù)據(jù),網(wǎng)卡內(nèi)的單片程序接收數(shù)據(jù)幀的目的MAC地址,根據(jù)計算機上的網(wǎng)卡驅(qū)動程序設(shè)置的接收模式判斷該不該接收,認為該接收就接收后產(chǎn)生中斷信號通知CPU,認為不該接收就丟掉不管,所以不該接收的數(shù)據(jù)網(wǎng)卡就截斷了,計算機根本就不知道。CPU得到中斷信號產(chǎn)生中斷,操作系統(tǒng)就根據(jù)網(wǎng)卡的驅(qū)動程序設(shè)置的網(wǎng)卡中斷程序地址調(diào)用驅(qū)動程序接收數(shù)據(jù),驅(qū)動程序接收數(shù)據(jù)后放入信號堆棧讓操作系統(tǒng)處理。而對于網(wǎng)卡來說一般有四種接收模式: 廣播方式:該模式下的網(wǎng)卡能夠接收網(wǎng)絡(luò)中的廣播信息!〗M播方式:設(shè)置在該模式下的網(wǎng)卡能夠接收組播數(shù)據(jù)。 直接方式:在這種模式下,只有目的網(wǎng)卡才能接收該數(shù)據(jù)。混雜模式:在這種模式下的網(wǎng)卡能夠接收一切通過它的數(shù)據(jù),而不管該數(shù)據(jù)是否是傳給它的。 好了,現(xiàn)在我們總結(jié)一下,首先,我們知道了在以太網(wǎng)中是基于廣播方式傳送數(shù)據(jù)的,也就是說,所有的物理信號都要經(jīng)過我的機器,再次,網(wǎng)卡可以置于一種模式叫混雜模式(promiscuous),在這種模式下工作的網(wǎng)卡能夠接收到一切通過它的數(shù)據(jù),而不管實際上數(shù)據(jù)的目的地址是不是他。這實際上就是我們SNIFF工作的基本原理:讓網(wǎng)卡接收一切他所能接收的數(shù)據(jù)。 我們來看一個簡單的例子,如圖一所示,機器A、B、C與集線器HUB相連接,集線器HUB通過路由器Router訪問外部網(wǎng)絡(luò)。這是一個很簡單也很常見的情況,比如說在公司大樓里,我所在的網(wǎng)絡(luò)部辦公室里的幾臺機器通過集線器連接,而網(wǎng)絡(luò)部、開發(fā)部、市場部也是同樣如此,幾個部門的集線器通過路由器連接。還是回到我們的圖一上來,值得注意的一點是機器A、B、C使用一個普通的HUB連接的,不是用SWITCH,也不是用ROUTER,使用SWITCH和ROUTER的情況要比這復雜得多。 我們假設(shè)一下機器A上的管理員為了維護機器C,使用了一個FTP命令向機器C進行遠程登陸,那么在這個用HUB連接的網(wǎng)絡(luò)里數(shù)據(jù)走向過程是這樣的。首先機器A上的管理員輸入的登陸機器C的FTP口令經(jīng)過應用層FTP協(xié)議、傳輸層TCP協(xié)議、網(wǎng)絡(luò)層IP協(xié)議、數(shù)據(jù)鏈路層上的以太網(wǎng)驅(qū)動程序一層一層的包裹,最后送到了物理層,我們的網(wǎng)線上。接下來數(shù)據(jù)幀送到了HUB上,現(xiàn)在由HUB向每一個接點廣播由機器A發(fā)出的數(shù)據(jù)幀,機器B接收到由HUB廣播發(fā)出的數(shù)據(jù)幀,并檢查在數(shù)據(jù)幀中的地址是否和自己的地址相匹配,發(fā)現(xiàn)不是發(fā)向自己的后把這數(shù)據(jù)幀丟棄,不予理睬。而機器C也接收到了數(shù)據(jù)幀,并在比較之后發(fā)現(xiàn)是發(fā)現(xiàn)自己的,接下來他就對這數(shù)據(jù)幀進行分析處理。 在上面這個簡單的例子中,機器B上的管理員如果很好奇,他很想知道究竟登陸機器C上FTP口令是什么?那么他要做的很簡單,僅僅需要把自己機器上的網(wǎng)卡置于混雜模式,并對接收到的數(shù)據(jù)幀進行分析,從而找到包含在數(shù)據(jù)幀中的口令信息。 四 做一個自己的sniff 在上一節(jié)里,我們已經(jīng)知道了SNIFF的基本原理是怎么一回事,這一節(jié)我們來親自動手做一個自己的sniff,畢竟,用程序代碼來說話比什么都要來得真實,也容易加深理解。 回頭想一想我們上面說的原理,我們要做的事情有幾件: 1. 把網(wǎng)卡置于混雜模式。 2. 捕獲數(shù)據(jù)包! 3.分析數(shù)據(jù)包。 注:下面的源代碼取至Chad Renfro的<< Basic Packet-SnifferConstruction from the Ground Up>>一文中 /************************Tcp_sniff_2.c********************/ 1.#include 2.#include 3.#include 4.#include 5.#include 6.#include 7.#include 8.#include 9.#include "headers.h" #define INTERFACE "eth0" /*Prototype area*/ 10.int Open_Raw_Socket(void); 11.int Set_Promisc(char *interface, intsock); 12.int main() { 13.int sock, bytes_recieved, fromlen; 14.char buffer[65535]; 15.struct sockaddr_in from; 16.struct ip *ip; 17.struct tcp *tcp; 18.sock = Open_Raw_Socket(); 19. Set_Promisc(INTERFACE, sock); 20. while(1) 22. { 23. fromlen = sizeof from; 24. bytes_recieved = recvfrom(sock, buffer, sizeofbuffer, 0, (struct sockaddr *)&from, &fromlen); 25. printf(" Bytes received :::%5d ",bytes_recieved); 26. printf("Source address :::%s ",inet_ntoa(from.sin_addr)); 27. ip = (struct ip *)buffer; /*See if this is a TCP packet*/ 28. if(ip->ip_protocol == 6) { 29. printf("IP header length :::%d ",ip->ip_length); 30. printf("Protocol :::%d ",ip->ip_protocol); 31. tcp = (struct tcp *)(buffer +(4*ip->ip_length)); 32. printf("Source port :::%d ",ntohs(tcp->tcp_source_port)); 33. printf("Dest port :::%d ",ntohs(tcp->tcp_dest_port)); 34. } 35. } 36.} 37.int Open_Raw_Socket() { 38. int sock; 39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0){ /*Then the socket was not created properly and must die*/ 40. perror("The raw socket was not created"); 41. exit(0); 42. }; 43. return(sock); 44. } 45.int Set_Promisc(char *interface, int sock ) { 46. struct ifreq ifr; 47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1); 48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { /*Could not retrieve flags for the interface*/ 49. perror("Could not retrive flags for the interface"); 50. exit(0); 51. } 52. printf("The interface is ::: %s ", interface); 53. perror("Retrieved flags from interface successfully"); 54. ifr.ifr_flags |= IFF_PROMISC; 55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) { /*Could not set the flags on the interface */ 56. perror("Could not set the PROMISC flag:"); 57. exit(0); 58. } 59. printf("Setting interface ::: %s ::: to promisc",interface); 60. return(0); 61. } /***********************EOF**********************************/ 上面這段程序中有很詳細的注解,不過我想還是有必要說一說,首先第10行--intOpen_Raw_Socket(void); 是我們的自定義函數(shù),具體內(nèi)容如下: 37.int Open_Raw_Socket() { 38. int sock; 39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0){ /*Then the socket was not created properly and must die*/ 40. perror("The raw socket was not created"); 41. exit(0); 42. }; 43. return(sock); 44. } 第39行 if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { 這里我們調(diào)用了socket函數(shù),使創(chuàng)建了了一個原始套接口,使之收到TCP/IP信息包。 接下來第11行-int Set_Promisc(char *interface, intsock),這也是我們的自定義函數(shù),目的是把網(wǎng)卡置于混雜模式,具體內(nèi)容如下: 45.int Set_Promisc(char *interface, int sock ) { 46. struct ifreq ifr; 47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1); 48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { /*Could not retrieve flags for the interface*/ 49. perror("Could not retrive flags for the interface"); 50. exit(0); 51. } 52. printf("The interface is ::: %s ", interface); 53. perror("Retrieved flags from interface successfully"); 54. ifr.ifr_flags |= IFF_PROMISC; 55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) { /*Could not set the flags on the interface */ 56. perror("Could not set the PROMISC flag:"); 57. exit(0); 58. } 59. printf("Setting interface ::: %s ::: to promisc",interface); 60. return(0); 61. } 首先 struct ifreq ifr; 定一了一個ifrreg的結(jié)構(gòu)ifr,接下來strncpy(ifr.ifr_name,interface,strnlen(interface)+1);,就是把我們網(wǎng)絡(luò)設(shè)備的名字填充到ifr結(jié)構(gòu)中,在這里#define INTERFACE "eth0" ,讓我們再往下看,ioctl(sock, SIOCGIFFLAGS,&ifr),SIOCGIFFLAGS請求表示需要獲取接口標志,現(xiàn)在到了第54行,在我們成功的獲取接口標志后把他設(shè)置成混雜模式,ifr.ifr_flags|= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS,&ifr)。OK,現(xiàn)在我們所說的第一步已經(jīng)完成--------把網(wǎng)卡置于混雜模式。 現(xiàn)在進入第二步,捕獲數(shù)據(jù)包。從第20行開始,我們進入了一個死循環(huán),while(1),在第24行,recvfrom(sock,buffer, sizeof buffer, 0, (struct sockaddr *)&from,&fromlen),這個函數(shù)要做的就是接收數(shù)據(jù),冰把接收到的數(shù)據(jù)放入buffer中。就是這么簡單,已經(jīng)完成了我們要捕獲數(shù)據(jù)包的任務。 到了第三步,分析數(shù)據(jù)包。27行,ip = (struct ip*)buffer,使我們在頭文件中的IP結(jié)構(gòu)對應于所接收到的數(shù)據(jù),接下來判斷在網(wǎng)絡(luò)層中是否使用的是TCP協(xié)議,if(ip->ip_protocol== 6) ,如果答案是,tcp信息包從整個IP/TCP包 buffer +(4*ip->ip_length) 地址處開始,所以31行 tcp = (struct tcp*)(buffer +(4*ip->ip_length)),然后對應結(jié)構(gòu)把你所需要的信息輸出。 /*************************headers.h**************************/ /*structure of an ip header*/ struct ip { unsigned int ip_length:4; /*little-endian*/ unsigned int ip_version:4; unsigned char ip_tos; unsigned short ip_total_length; unsigned short ip_id; unsigned short ip_flags; unsigned char ip_ttl; unsigned char ip_protocol; unsigned short ip_cksum; unsigned int ip_source; unsigned int ip_dest; }; /* Structure of a TCP header */ struct tcp { unsigned short tcp_source_port; unsigned short tcp_dest_port; unsigned int tcp_seqno; unsigned int tcp_ackno; unsigned int tcp_res1:4, /*little-endian*/ tcp_hlen:4, tcp_fin:1, tcp_syn:1, tcp_rst:1, tcp_psh:1, tcp_ack:1, tcp_urg:1, tcp_res2:2; unsigned short tcp_winsize; unsigned short tcp_cksum; unsigned short tcp_urgent; }; /*********************EOF***********************************/ 從上面的分析我們可以清楚的認識到,認識一個SNIFF需要對TCP/IP協(xié)議有著詳細的了解,否則你根本無法找到你需要的信息。有了上面的基礎(chǔ),你可以自己來做一個你需要的SNIFF了。
嗅探 sniff。嗅探器可以竊聽網(wǎng)絡(luò)上流經(jīng)的數(shù)據(jù)包。 用集線器hub組建的網(wǎng)絡(luò)是基于共享的原理的, 局域網(wǎng)內(nèi)所有的計算機都接收相同的數(shù)據(jù)包, 而網(wǎng)卡構(gòu)造了硬件的“過濾器“ 通過識別MAC地址過濾掉和自己無關(guān)的信息, 嗅探程序只需關(guān)閉這個過濾器, 將網(wǎng)卡設(shè)置為“混雜模式“就可以進行嗅探 用交換機switch組建的網(wǎng)絡(luò)是基于“交換“原理的 ,交換機不是把數(shù)據(jù)包發(fā)到所有的端口上, 而是發(fā)到目的網(wǎng)卡所在的端口。 這樣嗅探起來會麻煩一些,嗅探程序一般利用“ARP欺騙“的方法 ,通過改變MAC地址等手段,欺騙交換機將數(shù)據(jù)包發(fā)給自己, 嗅探分析完畢再轉(zhuǎn)發(fā)出去 一 前言 SNIFF真是一個古老的話題,關(guān)于在網(wǎng)絡(luò)上采用SNIFF來獲取敏感信息已經(jīng)不是什么新鮮事,也不乏很多成功的案例,那么,SNIFF究竟是什么呢?SNIFF就是嗅探器,就是竊聽器,SNIFF靜悄悄的工作在網(wǎng)絡(luò)的底層,把你的秘密全部記錄下來?催^威爾史密斯演的《全民公敵》嗎?SNIFF就象里面精巧的竊聽器一樣,讓你防不勝防。 SNIFF可以是軟件,也可以是硬件,既然是軟件那就要分平臺,有WINDOWS下的、UNXI下的等,硬件的SNIFF稱為網(wǎng)絡(luò)分析儀,反正不管硬件軟件,目標只有一個,就是獲取在網(wǎng)絡(luò)上傳輸?shù)母鞣N信息。本文僅僅介紹軟件的SNIFF。 當你舒適的坐在家里,愜意的享受網(wǎng)絡(luò)給你帶來的便利,收取你的EMAIL,購買你喜歡的物品的時候,你是否會想到你的朋友給你的信件,你的信用卡帳號變成了一個又一個的信息包在網(wǎng)絡(luò)上不停的傳送著,你是否曾經(jīng)這些信息包會通過網(wǎng)絡(luò)流入別人的機器呢?你的擔憂不是沒有道理的,因為SNIFF可以讓你的擔憂變成實實在在的危險。就好像一個人躲在你身后偷看一樣。。。。。。 二 網(wǎng)絡(luò)基礎(chǔ)知識 “網(wǎng)絡(luò)基礎(chǔ)知識”,是不是聽起來有點跑題了?雖然聽起來這和我們要談的SNIFF沒什么關(guān)系,可是還是要說一說的,萬丈高樓平地起,如果連地基都沒打好,怎么蓋樓?!如果你對網(wǎng)絡(luò)還不是十分清楚的話,最好能靜下心來好好看看,要知道,這是基礎(chǔ)的基礎(chǔ),在這里我只是簡單的說一下,免得到時候有人迷糊,詳細的最好能夠自己去找書看看。 。1)TCP/IP體系結(jié)構(gòu) 開放系統(tǒng)互連(OSI)模型將網(wǎng)絡(luò)劃分為七層模型,分別用以在各層上實現(xiàn)不同的功能,這七層分別為:應用層、表示層、會話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層及物理層。而TCP/IP體系也同樣遵循這七層標準,只不過在某些OSI功能上進行了壓縮,將表示層及會話層合并入應用層中,所以實際上我們打交道的TCP/IP僅僅有5層而已,網(wǎng)絡(luò)上的分層結(jié)構(gòu)決定了在各層上的協(xié)議分布及功能實現(xiàn),從而決定了各層上網(wǎng)絡(luò)設(shè)備的使用。實際上很多成功的系統(tǒng)都是基于OSI模型的,如:如幀中繼、ATM、ISDN等。 TCP/IP的網(wǎng)絡(luò)體系結(jié)構(gòu)(部分) 從上面的圖中我們可以看出,第一層物理層和第二層數(shù)據(jù)鏈路層是TCP/IP的基礎(chǔ),而TCP/IP本身并不十分關(guān)心低層,因為處在數(shù)據(jù)鏈路層的網(wǎng)絡(luò)設(shè)備驅(qū)動程序?qū)⑸蠈拥膮f(xié)議和實際的物理接口隔離開來。網(wǎng)絡(luò)設(shè)備驅(qū)動程序位于介質(zhì)訪問子層(MAC)。2)網(wǎng)絡(luò)上的設(shè)備 中繼器:中繼器的主要功能是終結(jié)一個網(wǎng)段的信號并在另一個網(wǎng)段再生該信號,一句話,就是簡單的放大而已,工作在物理層上! 網(wǎng) 橋:網(wǎng)橋使用MAC物理地址實現(xiàn)中繼功能,可以用來分隔網(wǎng)段或連接部分異種網(wǎng)絡(luò),工作在數(shù)據(jù)鏈路層。 路由器:路由器使用網(wǎng)絡(luò)層地址(IP,X.121,E.164等),主要負責數(shù)據(jù)包的路由尋徑,也能處理物理層和數(shù)據(jù)鏈路層上的工作。 網(wǎng) 關(guān):主要工作在網(wǎng)絡(luò)第四層以上,主要實現(xiàn)收斂功能及協(xié)議轉(zhuǎn)換,不過很多時候網(wǎng)關(guān)都被用來描述任何網(wǎng)絡(luò)互連設(shè)備。 。3)TCP/IP與以太網(wǎng) 以太網(wǎng)和TCP/IP可以說是相互相成的,可以說兩者的關(guān)系幾乎是密不可分,以太網(wǎng)在一二層提供物理上的連線,而TCP/IP工作在上層,使用32位的IP地址,以太網(wǎng)則使用48位的MAC地址,兩者間使用ARP和RARP協(xié)議進行相互轉(zhuǎn)換。從我們上面TCP/IP的模型圖中可以清楚的看到兩者的關(guān)系。 載波監(jiān)聽/沖突檢測(CSMA/CD)技術(shù)被普遍的使用在以太網(wǎng)中,所謂載波監(jiān)聽是指在以太網(wǎng)中的每個站點都具有同等的權(quán)利,在傳輸自己的數(shù)據(jù)時,首先監(jiān)聽信道是否空閑,如果空閑,就傳輸自己的數(shù)據(jù),如果信道被占用,就等待信道空閑。而沖突檢測則是為了防止發(fā)生兩個站點同時監(jiān)測到網(wǎng)絡(luò)沒有被使用時而產(chǎn)生沖突。以太網(wǎng)采用廣播機制,所有與網(wǎng)絡(luò)連接的工作站都可以看到網(wǎng)絡(luò)上傳遞的數(shù)據(jù)。 為了加深你的理解,我們來看看下面的圖,一個典型的在以太網(wǎng)中客戶與服務器使用TCP/IP協(xié)議的通信 以太網(wǎng) 唆唆了這么多,有人煩了吧?相信我,這是基礎(chǔ)的基礎(chǔ),可以說是說得是很簡單拉,如果需要,拿出個幾十萬字來說上面的內(nèi)容,我想也不嫌多,好了,讓我們進入下一節(jié),sniff的原理。 三 SNIFF的原理 要知道在以太網(wǎng)中,所有的通訊都是廣播的,也就是說通常在同一個網(wǎng)段的所有網(wǎng)絡(luò)接口都可以訪問在物理媒體上傳輸?shù)乃袛?shù)據(jù),而每一個網(wǎng)絡(luò)接口都有一個唯一的硬件地址,這個硬件地址也就是網(wǎng)卡的MAC地址,大多數(shù)系統(tǒng)使用48比特的地址,這個地址用來表示網(wǎng)絡(luò)中的每一個設(shè)備,一般來說每一塊網(wǎng)卡上的MFC地址都是不同的,每個網(wǎng)卡廠家得到一段地址,然后用這段地址分配給其生產(chǎn)的每個網(wǎng)卡一個地址。在硬件地址和IP地址間使用ARP和RARP協(xié)議進行相互轉(zhuǎn)換。 在正常的情況下,一個網(wǎng)絡(luò)接口應該只響應這樣的兩種數(shù)據(jù)幀: 1.與自己硬件地址相匹配的數(shù)據(jù)幀!2.發(fā)向所有機器的廣播數(shù)據(jù)幀。 在一個實際的系統(tǒng)中,數(shù)據(jù)的收發(fā)是由網(wǎng)卡來完成的,網(wǎng)卡接收到傳輸來的數(shù)據(jù),網(wǎng)卡內(nèi)的單片程序接收數(shù)據(jù)幀的目的MAC地址,根據(jù)計算機上的網(wǎng)卡驅(qū)動程序設(shè)置的接收模式判斷該不該接收,認為該接收就接收后產(chǎn)生中斷信號通知CPU,認為不該接收就丟掉不管,所以不該接收的數(shù)據(jù)網(wǎng)卡就截斷了,計算機根本就不知道。CPU得到中斷信號產(chǎn)生中斷,操作系統(tǒng)就根據(jù)網(wǎng)卡的驅(qū)動程序設(shè)置的網(wǎng)卡中斷程序地址調(diào)用驅(qū)動程序接收數(shù)據(jù),驅(qū)動程序接收數(shù)據(jù)后放入信號堆棧讓操作系統(tǒng)處理。而對于網(wǎng)卡來說一般有四種接收模式: 廣播方式:該模式下的網(wǎng)卡能夠接收網(wǎng)絡(luò)中的廣播信息!〗M播方式:設(shè)置在該模式下的網(wǎng)卡能夠接收組播數(shù)據(jù)。 直接方式:在這種模式下,只有目的網(wǎng)卡才能接收該數(shù)據(jù)。混雜模式:在這種模式下的網(wǎng)卡能夠接收一切通過它的數(shù)據(jù),而不管該數(shù)據(jù)是否是傳給它的。 好了,現(xiàn)在我們總結(jié)一下,首先,我們知道了在以太網(wǎng)中是基于廣播方式傳送數(shù)據(jù)的,也就是說,所有的物理信號都要經(jīng)過我的機器,再次,網(wǎng)卡可以置于一種模式叫混雜模式(promiscuous),在這種模式下工作的網(wǎng)卡能夠接收到一切通過它的數(shù)據(jù),而不管實際上數(shù)據(jù)的目的地址是不是他。這實際上就是我們SNIFF工作的基本原理:讓網(wǎng)卡接收一切他所能接收的數(shù)據(jù)。 我們來看一個簡單的例子,如圖一所示,機器A、B、C與集線器HUB相連接,集線器HUB通過路由器Router訪問外部網(wǎng)絡(luò)。這是一個很簡單也很常見的情況,比如說在公司大樓里,我所在的網(wǎng)絡(luò)部辦公室里的幾臺機器通過集線器連接,而網(wǎng)絡(luò)部、開發(fā)部、市場部也是同樣如此,幾個部門的集線器通過路由器連接。還是回到我們的圖一上來,值得注意的一點是機器A、B、C使用一個普通的HUB連接的,不是用SWITCH,也不是用ROUTER,使用SWITCH和ROUTER的情況要比這復雜得多。 我們假設(shè)一下機器A上的管理員為了維護機器C,使用了一個FTP命令向機器C進行遠程登陸,那么在這個用HUB連接的網(wǎng)絡(luò)里數(shù)據(jù)走向過程是這樣的。首先機器A上的管理員輸入的登陸機器C的FTP口令經(jīng)過應用層FTP協(xié)議、傳輸層TCP協(xié)議、網(wǎng)絡(luò)層IP協(xié)議、數(shù)據(jù)鏈路層上的以太網(wǎng)驅(qū)動程序一層一層的包裹,最后送到了物理層,我們的網(wǎng)線上。接下來數(shù)據(jù)幀送到了HUB上,現(xiàn)在由HUB向每一個接點廣播由機器A發(fā)出的數(shù)據(jù)幀,機器B接收到由HUB廣播發(fā)出的數(shù)據(jù)幀,并檢查在數(shù)據(jù)幀中的地址是否和自己的地址相匹配,發(fā)現(xiàn)不是發(fā)向自己的后把這數(shù)據(jù)幀丟棄,不予理睬。而機器C也接收到了數(shù)據(jù)幀,并在比較之后發(fā)現(xiàn)是發(fā)現(xiàn)自己的,接下來他就對這數(shù)據(jù)幀進行分析處理。 在上面這個簡單的例子中,機器B上的管理員如果很好奇,他很想知道究竟登陸機器C上FTP口令是什么?那么他要做的很簡單,僅僅需要把自己機器上的網(wǎng)卡置于混雜模式,并對接收到的數(shù)據(jù)幀進行分析,從而找到包含在數(shù)據(jù)幀中的口令信息。 四 做一個自己的sniff 在上一節(jié)里,我們已經(jīng)知道了SNIFF的基本原理是怎么一回事,這一節(jié)我們來親自動手做一個自己的sniff,畢竟,用程序代碼來說話比什么都要來得真實,也容易加深理解。 回頭想一想我們上面說的原理,我們要做的事情有幾件: 1. 把網(wǎng)卡置于混雜模式。 2. 捕獲數(shù)據(jù)包! 3.分析數(shù)據(jù)包。 注:下面的源代碼取至Chad Renfro的<< Basic Packet-SnifferConstruction from the Ground Up>>一文中 /************************Tcp_sniff_2.c********************/ 1.#include 2.#include 3.#include 4.#include 5.#include 6.#include 7.#include 8.#include 9.#include "headers.h" #define INTERFACE "eth0" /*Prototype area*/ 10.int Open_Raw_Socket(void); 11.int Set_Promisc(char *interface, intsock); 12.int main() { 13.int sock, bytes_recieved, fromlen; 14.char buffer[65535]; 15.struct sockaddr_in from; 16.struct ip *ip; 17.struct tcp *tcp; 18.sock = Open_Raw_Socket(); 19. Set_Promisc(INTERFACE, sock); 20. while(1) 22. { 23. fromlen = sizeof from; 24. bytes_recieved = recvfrom(sock, buffer, sizeofbuffer, 0, (struct sockaddr *)&from, &fromlen); 25. printf(" Bytes received :::%5d ",bytes_recieved); 26. printf("Source address :::%s ",inet_ntoa(from.sin_addr)); 27. ip = (struct ip *)buffer; /*See if this is a TCP packet*/ 28. if(ip->ip_protocol == 6) { 29. printf("IP header length :::%d ",ip->ip_length); 30. printf("Protocol :::%d ",ip->ip_protocol); 31. tcp = (struct tcp *)(buffer +(4*ip->ip_length)); 32. printf("Source port :::%d ",ntohs(tcp->tcp_source_port)); 33. printf("Dest port :::%d ",ntohs(tcp->tcp_dest_port)); 34. } 35. } 36.} 37.int Open_Raw_Socket() { 38. int sock; 39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0){ /*Then the socket was not created properly and must die*/ 40. perror("The raw socket was not created"); 41. exit(0); 42. }; 43. return(sock); 44. } 45.int Set_Promisc(char *interface, int sock ) { 46. struct ifreq ifr; 47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1); 48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { /*Could not retrieve flags for the interface*/ 49. perror("Could not retrive flags for the interface"); 50. exit(0); 51. } 52. printf("The interface is ::: %s ", interface); 53. perror("Retrieved flags from interface successfully"); 54. ifr.ifr_flags |= IFF_PROMISC; 55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) { /*Could not set the flags on the interface */ 56. perror("Could not set the PROMISC flag:"); 57. exit(0); 58. } 59. printf("Setting interface ::: %s ::: to promisc",interface); 60. return(0); 61. } /***********************EOF**********************************/ 上面這段程序中有很詳細的注解,不過我想還是有必要說一說,首先第10行--intOpen_Raw_Socket(void); 是我們的自定義函數(shù),具體內(nèi)容如下: 37.int Open_Raw_Socket() { 38. int sock; 39. if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0){ /*Then the socket was not created properly and must die*/ 40. perror("The raw socket was not created"); 41. exit(0); 42. }; 43. return(sock); 44. } 第39行 if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { 這里我們調(diào)用了socket函數(shù),使創(chuàng)建了了一個原始套接口,使之收到TCP/IP信息包。 接下來第11行-int Set_Promisc(char *interface, intsock),這也是我們的自定義函數(shù),目的是把網(wǎng)卡置于混雜模式,具體內(nèi)容如下: 45.int Set_Promisc(char *interface, int sock ) { 46. struct ifreq ifr; 47. strncpy(ifr.ifr_name, interface,strnlen(interface)+1); 48. if((ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)) { /*Could not retrieve flags for the interface*/ 49. perror("Could not retrive flags for the interface"); 50. exit(0); 51. } 52. printf("The interface is ::: %s ", interface); 53. perror("Retrieved flags from interface successfully"); 54. ifr.ifr_flags |= IFF_PROMISC; 55. if (ioctl (sock, SIOCSIFFLAGS, &ifr) == -1 ) { /*Could not set the flags on the interface */ 56. perror("Could not set the PROMISC flag:"); 57. exit(0); 58. } 59. printf("Setting interface ::: %s ::: to promisc",interface); 60. return(0); 61. } 首先 struct ifreq ifr; 定一了一個ifrreg的結(jié)構(gòu)ifr,接下來strncpy(ifr.ifr_name,interface,strnlen(interface)+1);,就是把我們網(wǎng)絡(luò)設(shè)備的名字填充到ifr結(jié)構(gòu)中,在這里#define INTERFACE "eth0" ,讓我們再往下看,ioctl(sock, SIOCGIFFLAGS,&ifr),SIOCGIFFLAGS請求表示需要獲取接口標志,現(xiàn)在到了第54行,在我們成功的獲取接口標志后把他設(shè)置成混雜模式,ifr.ifr_flags|= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS,&ifr)。OK,現(xiàn)在我們所說的第一步已經(jīng)完成--------把網(wǎng)卡置于混雜模式。 現(xiàn)在進入第二步,捕獲數(shù)據(jù)包。從第20行開始,我們進入了一個死循環(huán),while(1),在第24行,recvfrom(sock,buffer, sizeof buffer, 0, (struct sockaddr *)&from,&fromlen),這個函數(shù)要做的就是接收數(shù)據(jù),冰把接收到的數(shù)據(jù)放入buffer中。就是這么簡單,已經(jīng)完成了我們要捕獲數(shù)據(jù)包的任務。 到了第三步,分析數(shù)據(jù)包。27行,ip = (struct ip*)buffer,使我們在頭文件中的IP結(jié)構(gòu)對應于所接收到的數(shù)據(jù),接下來判斷在網(wǎng)絡(luò)層中是否使用的是TCP協(xié)議,if(ip->ip_protocol== 6) ,如果答案是,tcp信息包從整個IP/TCP包 buffer +(4*ip->ip_length) 地址處開始,所以31行 tcp = (struct tcp*)(buffer +(4*ip->ip_length)),然后對應結(jié)構(gòu)把你所需要的信息輸出。 /*************************headers.h**************************/ /*structure of an ip header*/ struct ip { unsigned int ip_length:4; /*little-endian*/ unsigned int ip_version:4; unsigned char ip_tos; unsigned short ip_total_length; unsigned short ip_id; unsigned short ip_flags; unsigned char ip_ttl; unsigned char ip_protocol; unsigned short ip_cksum; unsigned int ip_source; unsigned int ip_dest; }; /* Structure of a TCP header */ struct tcp { unsigned short tcp_source_port; unsigned short tcp_dest_port; unsigned int tcp_seqno; unsigned int tcp_ackno; unsigned int tcp_res1:4, /*little-endian*/ tcp_hlen:4, tcp_fin:1, tcp_syn:1, tcp_rst:1, tcp_psh:1, tcp_ack:1, tcp_urg:1, tcp_res2:2; unsigned short tcp_winsize; unsigned short tcp_cksum; unsigned short tcp_urgent; }; /*********************EOF***********************************/ 從上面的分析我們可以清楚的認識到,認識一個SNIFF需要對TCP/IP協(xié)議有著詳細的了解,否則你根本無法找到你需要的信息。有了上面的基礎(chǔ),你可以自己來做一個你需要的SNIFF了。
抱歉,此頁面的內(nèi)容受版權(quán)保護,復制需扣除次數(shù),次數(shù)不足時需付費購買。
如需下載請點擊:點擊此處下載
掃碼付費即可復制
短波 | 3g門戶 | 802.22 | 波特 | 波特 | FACCH/F | 手機瀏覽器 | JUNOS | 數(shù)據(jù)倉庫 | laser | 中繼線路 | 雙向中繼 |
移動通信網(wǎng) | 通信人才網(wǎng) | 更新日志 | 團隊博客 | 免責聲明 | 關(guān)于詞典 | 幫助