日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

通信网络实验-嗅探器实现

發(fā)布時(shí)間:2023/12/29 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通信网络实验-嗅探器实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用WinPcap來(lái)實(shí)現(xiàn)嗅探器

一、嗅探器簡(jiǎn)介

嗅探器程序一般包括內(nèi)核部分和用戶分析部分,其中內(nèi)核部分負(fù)責(zé)從網(wǎng)絡(luò)中捕獲和過(guò)濾數(shù)據(jù),用戶分析部分負(fù)責(zé)界面、數(shù)據(jù)轉(zhuǎn)化和處理、格式化、協(xié)議分析,如果在內(nèi)核中沒(méi)有過(guò)濾數(shù)據(jù)包,在這里還要對(duì)數(shù)據(jù)進(jìn)行過(guò)濾。一個(gè)較為完整的基于網(wǎng)絡(luò)監(jiān)聽(tīng)和過(guò)濾的程序一般包含以下步驟:數(shù)據(jù)包捕獲、數(shù)據(jù)包過(guò)濾和分解、數(shù)據(jù)分析。
數(shù)據(jù)包捕獲常用的方法有兩種:

(1)通過(guò)設(shè)置路由器的監(jiān)聽(tīng)端口

(2)利用以太網(wǎng)絡(luò)的廣播特性。這種特性必須將網(wǎng)卡設(shè)置為混雜模式。監(jiān)聽(tīng)程序工作在網(wǎng)絡(luò)環(huán)境的底三層,可以攔截所有經(jīng)過(guò)該機(jī)器的網(wǎng)絡(luò)上傳送的數(shù)據(jù),然后將這些數(shù)據(jù)做相應(yīng)處理,可以實(shí)時(shí)分析這些數(shù)據(jù)的內(nèi)容,進(jìn)而分析網(wǎng)絡(luò)當(dāng)前狀態(tài)和整體布局。基于Windows的數(shù)據(jù)包捕獲方案有以下幾種:

1.使用原始套接字機(jī)制。方法簡(jiǎn)單,但功能有限,只能捕獲較高層的數(shù)據(jù)包;

2.直接連接調(diào)用NDIS庫(kù)函數(shù),這種方法功能非常強(qiáng)大,但是比較危險(xiǎn),很可能導(dǎo)致系統(tǒng)崩潰和網(wǎng)絡(luò)癱瘓;

3.使用或者自行編寫中間層驅(qū)動(dòng)程序,這是微軟公司推薦使用的一種方法,微軟提供的Win2000DDK中也提供了幾個(gè)這樣的驅(qū)動(dòng)程序,在具體的實(shí)現(xiàn)方式上可以分為用戶級(jí)和內(nèi)核級(jí)兩類。其中內(nèi)核級(jí)主要是TDI捕獲過(guò)濾驅(qū)動(dòng)程序,NDIS中間層捕獲過(guò)濾驅(qū)動(dòng)程序,NDIS捕獲過(guò)濾鉤子驅(qū)動(dòng)程序等等,它們都是利用網(wǎng)絡(luò)驅(qū)動(dòng)來(lái)實(shí)現(xiàn)的;而用戶級(jí)的包括SPI接口,Win2000包捕獲過(guò)濾接口等;

4.使用或自行編寫協(xié)議驅(qū)動(dòng)程序

5.使用第三方捕獲組件或者庫(kù),比如WinPcap.

捕獲數(shù)據(jù)包后,我們要進(jìn)行的工作是對(duì)其進(jìn)行包過(guò)濾和分解,就是在海量的數(shù)據(jù)里面找我們感興趣的內(nèi)容。一些基礎(chǔ)的過(guò)濾規(guī)則如下:

站過(guò)濾:專門篩選出來(lái)自一臺(tái)主機(jī)或者服務(wù)器的數(shù)據(jù)

協(xié)議過(guò)濾:根據(jù)不同的協(xié)議來(lái)篩選數(shù)據(jù),例如選擇TCP數(shù)據(jù)而非UDP數(shù)據(jù)

服務(wù)過(guò)濾:根據(jù)端口號(hào)來(lái)選擇特定數(shù)據(jù)包

通用過(guò)濾:通過(guò)數(shù)據(jù)包中某一位置開(kāi)始,選擇某些具有共同特征的數(shù)據(jù)包;

過(guò)濾完成后,必須進(jìn)行數(shù)據(jù)分析,這一部分就是對(duì)于已經(jīng)捕獲的數(shù)據(jù)包進(jìn)行各種分析,比如網(wǎng)絡(luò)流量分析,數(shù)據(jù)包中信息分析,敏感信息提取分析,其功能取決于系統(tǒng)要達(dá)到的目的。

下面,我們著重介紹一下使用WinPcap這一環(huán)境來(lái)實(shí)現(xiàn)一個(gè)嗅探器的過(guò)程。
WinPcap是用于網(wǎng)絡(luò)封包抓取的一套工具,包含了核心的封包過(guò)濾,一個(gè)底層動(dòng)態(tài)鏈接庫(kù)和一個(gè)高層系統(tǒng)函數(shù)庫(kù)。可以進(jìn)行信息包捕獲和網(wǎng)絡(luò)分析。很多不同的工具軟件都是使用WinPcap來(lái)進(jìn)行網(wǎng)絡(luò)分析、故障排除和網(wǎng)絡(luò)安全監(jiān)控等操作的,比如大名鼎鼎的WireShark軟件。

在安裝WireShark時(shí),它是默認(rèn)捆綁安裝WinPcap的。如果你沒(méi)有安裝WireShark的話,那么你也可以前往這一網(wǎng)頁(yè)進(jìn)行下載。要注意的是,除了安裝這一文件,我們還要下載開(kāi)發(fā)者套件,這個(gè)套間里面包含了一些頭文件、若干文檔和一些范例程序,對(duì)于我們的編程有很大的幫助。
下載之后,將開(kāi)發(fā)者工具解壓到某一個(gè)目錄下。至于這個(gè)庫(kù)的使用方法,請(qǐng)參考我的前一篇博文。

好了,現(xiàn)在我們就可以開(kāi)始進(jìn)行正式的開(kāi)發(fā)工作了。

使用WinPcap的基本流程十分規(guī)范,主要有以下幾步:

這些函數(shù)的定義都可以在幫助文檔里找到。在我們解壓后的開(kāi)發(fā)者工具包的docs文件夾里,就有所有我們需要的函數(shù)的使用方法和范例。我們可以直接在范例的基礎(chǔ)上進(jìn)行修改來(lái)完成我們的任務(wù)。

二、一個(gè)過(guò)濾UDP數(shù)據(jù)包的程序

下面是一個(gè)過(guò)濾網(wǎng)絡(luò)中udp數(shù)據(jù)包的程序。

#include <stdio.h> #include <stdlib.h> #include <ctime> #include "pcap.h" #include "remote-ext.h" typedef struct ip_address{u_char byte1;u_char byte2;u_char byte3;u_char byte4; }ip_address;//IPV4 header typedef struct ip_header{u_char ver_ihl;u_char tos;u_short tlen;u_short identification;u_short flags_fo;u_char ttl;u_char proto;u_short crc;ip_address saddr;ip_address daddr;u_int op_pad; }ip_header; //UDP header typedef struct udp_header{u_short sport;u_short dport;u_short len;u_short crc; }udp_header;void packet_handler(u_char *param, const struct pcap_pkthdr* header, const u_char *pkt_data);int main() {pcap_if_t *alldevs, *d;int inum, i = 0;pcap_t *adhandle;char errbuf[PCAP_ERRBUF_SIZE];u_int netmask;char packet_filter[] = "ip and udp";struct bpf_program fcode;/* pap_findalldevs_ex():this function returns a linked list of pcap_if structures, each of which contains comprehensive information about an attached adapter */ if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf) == -1) {fprintf(stderr, "Error in pcap_findalldevs :%s\n", errbuf);exit(1); }for (d = alldevs; d ; d = d->next) {printf("%d.%s", ++i, d->name);if (d->description){printf("(%s)\n", d->description);}else{printf("(No description available)\n");} }if (i == 0) {printf("\nNo interfaces found!Make sure WinPcap is installed.\n");return -1; } printf("Enter the interface number (1-%d):", i); scanf_s("%d", &inum); if (inum <1 || inum > i) {printf("\nInterface number out of range.\n");pcap_freealldevs(alldevs);return -1; } for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++); if ((adhandle = pcap_open_live(d->name,65536,1,1000,errbuf)) == NULL) {fprintf(stderr, "\nUnable to open the adapter.%s is not supported by WinPcap\n");pcap_freealldevs(alldevs);return -1; } if (d->addresses != NULL) {netmask = ((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr; } else {netmask = 0xffffff; } if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0) {fprintf(stderr, "\nUnable to compile the packet filter.Check the syntax.\n");pcap_freealldevs(alldevs);return -1; }if (pcap_setfilter(adhandle,&fcode) < 0) {fprintf(stderr, "\nError setting the filter.\n");pcap_freealldevs(alldevs);return -1; } printf("\nListening on %s...\n", d->description); pcap_freealldevs(alldevs); pcap_loop(adhandle, 0, packet_handler, NULL); return 0; }//Callback function invoked by libpcap for every incoming packet void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {struct tm ltime;char timestr[16];ip_header *ih;udp_header *uh;u_short sport, dport;time_t local_tv_sec;u_int ip_len;local_tv_sec = header->ts.tv_sec;localtime_s(&ltime,&local_tv_sec);strftime(timestr, sizeof(timestr), "%H:%M:%S", &ltime);printf("%s,%.6d len:%d", timestr, header->ts.tv_usec, header->len);ih = (ip_header*)(pkt_data + 14);ip_len = (ih->ver_ihl & 0xf) * 4;uh = (udp_header*)((u_char *)ih + ip_len);sport = ntohs(uh->sport);dport = ntohs(uh->dport);printf("%d. %d. %d. %d. %d -> %d. %d. %d. %d. %d.\n", ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4, sport, ih->daddr.byte1,ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4, dport); }

整個(gè)代碼的邏輯結(jié)構(gòu)完全遵循我們之前提到的流程,理解起來(lái)并不困難,這里就不對(duì)代碼做具體分析了。
嗅探器的運(yùn)行效果如下:

可以看到,這個(gè)程序已經(jīng)將適配器里的udp包信息給打印了出來(lái)。這就說(shuō)明我們的嗅探器已經(jīng)可以正常工作了。

三、捕獲FTP數(shù)據(jù)包中的用戶名和密碼

要使這個(gè)程序具有捕獲FTP中的用戶名和密碼,我們只需要將我們的過(guò)濾機(jī)制設(shè)置成ftp數(shù)據(jù),并且改寫packet_handler函數(shù)即可。

首先,我們將packet_filter改寫如下:
char packet_filter[] = "tcp dst port ftp";
然后,在程序中加入tcp_header的定義:

typedef struct tcp_header{u_short sport;u_short dport;u_int seq;u_int ack_num;u_char ihl;u_char frame;u_short wsize;u_short crc;u_short urg; }tcp_header;

然后,改寫packet_handler函數(shù):

void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {struct tm ltime;char timestr[16];ip_header *ih;tcp_header *th;u_short sport, dport;time_t local_tv_sec;u_char *pdata;u_int tcp_len;u_int ip_len;u_int data_len;u_int i;local_tv_sec = header->ts.tv_sec;localtime_s(&ltime,&local_tv_sec);strftime(timestr, sizeof(timestr), "%H:%M:%S", &ltime);printf("%s,%.6d len:%d ", timestr, header->ts.tv_usec, header->len);ih = (ip_header*)(pkt_data + 14);ip_len = (ih->ver_ihl & 0xf) * 4;th = (tcp_header*)((u_char *)ih + ip_len);sport = ntohs(th->sport);dport = ntohs(th->dport);printf("%d.%d.%d.%d:%d -> %d.%d.%d.%d:%d\n", ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4, sport, ih->daddr.byte1,ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4, dport);tcp_len = ((th->ihl & 0xf0) >> 4) * 4;pdata = (u_char*)th + tcp_len;data_len = header->len - ip_len - tcp_len - 16;if (*pdata == 'U' && *(pdata + 1) == 'S' && *(pdata + 2) == 'E' && *(pdata + 3) == 'R'){memset(user, 0, sizeof(user));pdata += 5;for (i = 0; i < data_len-5; i++){user[i] = *pdata;pdata++;}}if (*pdata == 'P' && *(pdata + 1) == 'A' && *(pdata + 2) == 'S' && *(pdata + 3) == 'S'){memset(pass, 0, sizeof(pass));pdata += 5;for (i = 0; i<data_len - 5; i++){pass[i] = *pdata;pdata++;}}printf("User:%s\n", user);printf("Password:%s\n", pass); }

然后怎么測(cè)試我們的程序能否正常工作呢?我們編譯并執(zhí)行這個(gè)程序,然后點(diǎn)擊開(kāi)始->運(yùn)行->輸入cmd->輸入ftp ftp.mcafee.com->輸入用戶名:anonymous->輸入密碼(這個(gè)密碼可以任意填寫),這時(shí)候在我們的程序里應(yīng)該就能看到你剛剛輸入的用戶名和密碼了:

總結(jié)

以上是生活随笔為你收集整理的通信网络实验-嗅探器实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。