📄 嗅探的基本原理.txt
字号:
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 packets
[ -o file ] # Capture packets in file
[ -n file ] # Load addr-to-name table from file
[ -N ] # Create addr-to-name table
[ -t r|a|d ] # Time: Relative, Absolute or Delta
[ -v ] # Verbose packet display
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -