| 热门文章 |
 |
|
| 编辑推荐 |
 |
|
|
|
s 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\n", 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行--int Open_Raw_Socket(void); 是我们的自定义函数,具体内容如下:
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) {
这里我们调用了socket函数,使创建了了一个原始套接口,使之收到TCP/IP信息包。
接下来第11行-int Set_Promisc(char *interface, int sock),这也是我们的自定义函数, 目的是把网卡置于混杂模式,具体内容如下: 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\n", 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的结构ifr,接下来 strncpy(ifr.ifr_name, interface,strnlen(interface)+1);,就是把我们网络设备的名字填 充到ifr结构中,在这里 #define INTERFACE "eth0" ,让我们再往下看, ioctl(sock, SIOCGIFFLAGS, &ifr),SIOCGIFFLAGS请求表示需要获取接口标志,现在到了 第54行,在我们成功的获取接口标志后把他设置成混杂模式, ifr.ifr_flags |= IFF_PROMISC;ioctl (sock, SIOCSIFFLAGS, &ifr)。OK,现在我们所说的 第一步已经完成--------把网卡置于混杂模式。
现在进入第二步,捕获数据包。从第20行开始,我们进入了一个死循环,while(1),在 第24行,recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr *)&from, &fromlen), 这个函数要做的就是接收数据,冰把接收到的数据放入buffer中。就是这么简单,已经完成了我 们要捕获数据包的任务。
到了第三步,分析数据包。27行,ip = (struct ip *)buffer,使我们在头文件中的IP结 构对应于所接收到的数据,接下来判断在网络层中是否使用的是TCP协议, if(ip->ip_protocol == 6) ,如果答案是,tcp信息包从整个IP/TCP包 buffer + (4*ip->ip_length) 地址处开始,所以31行 tcp = (struct tcp *)(buffer + (4*ip->ip_length)),然后对应 结构把你所需要的信息输出。 /*************************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协议有着详细的了解, 否则你根本无法找到你需要的信息。有了上面的基础,你可以自己来做一个你需要的SNIFF了。
五 常用的SNIFF
很少有原因会让你自己亲自动手来做一个自己的SNIFF,除非你是想了解他的原理,或者是 其他一些特别的原因,比如你要在某个特殊的环境拦截一些特殊的数据包。下面我们就来看 看一些在网络上经常使用的SNIFF。
(1)windows环境下
windows环境下当然是大名鼎鼎的netxray以及sniffer pro了,实际上很多人都是用他在 windows环境下抓包来分析,不过我想很少有人笨到去在别人的机器上安装一个图形界面的SNIFF, 除非他和管理员很熟悉........ netxray的使用就不多说了,反正windows下的东西就是 click,click,click,非常的方便用户。
(2)UNUX环境下
UNUX环境下的sniff可以说是百花齐放,一抓就是一大把,如sniffit,snoop,tcpdump,dsniff 等都是比较常见的,他们都有一个好处就是发布源代码,可以让你研究,当然也都是免费的:)
1. sniffit
sniffit可以运行在Solaris、SGI和Linux等平台上,由Lawrence Berkeley Laboratory 实验 室开发的一个免费的网络监听软件。最近Sniffit 0.3.7也推出了NT版本,并也支持WINDOWS2000.
使用方法: -v 显示版本信息 -a 以ASCII形式将监听的结果输出。 -A 在进行记录时,所有不可打印的字符都用代替 -b 等同于同时使用参数-t & -s。 -d 将监听所得内容以十六进制方式显示在当前终端 -p 记录连接到的包,0为所有端口。缺省为0。 -P protocol 选择要检查的协议,缺省为TCP。可能的选择有IP、TCP、ICMP、UDP和他们的组合。 -s 指定sniffer 检查从 发送的数据包。 -t 指定sniffer 检查发送到的数据包。 -i 进入交互模式 -l 设定数据包大小,default是300字节 注:参数可以用@来表示一个IP范围,比如 -t 192.168.@ -t和-s 只适用于TCP/UDP数据包,对 于ICMP和IP也进行解释。但如果只选择了-p参数,则只用于TCP和UDP包。
举例说明:
#sniffit -a -p 21 -t xxx.xxx.xxx.xxx
监听流向机器xxx.xxx.xxx.xxx的21端口(FTP)的信息,并以ASCII显示
#sniffit -d -p 23 -b xxx.xxx.xxx.xxx
监听所有流出或流入机器xxx.xxx.xxx.xxx的23端口(telnet)的信息,并以16进制显示
你可以在这里找到sniffit http://reptile.rug.ac.be/~coder/sniffit/sniffit.html
2. snoop
snoop默认情况安装在Solaris下,是一个用于显示网络交通的程序,不过SNIFF是把双刃剑, 既然管理员能用他来监视自己的网络,当然一个心怀恶意的入侵者也可以用他来SNIFF自己感兴 趣的内容。值得一提的是, SNOOP被发现存在一个缓冲区溢出漏洞,当以导致入侵者以运行 snoop(通常为root)的身份远程进入系统。这是题外话,暂且就此打住。
使用方法: [ -a ] # Listen to packets on audio [ -d device ] # settable to le?, ie?, bf?, tr? [ -s snaplen ] # Truncate packets [ -c count ] # Quit after count packets [ -P ] # Turn OFF promiscuous mode [ -D ] # Report dropped packets [ -S ] # Report packet size [ -i file ] # Read previously captured pa上一页 [1] [2] [3] [4] 下一页
|
|
|