[ZLG-ARM] Linux系统下的网络监听技术

[复制链接]
1906|1
 楼主| billen 发表于 2009-6-4 16:52 | 显示全部楼层 |阅读模式
在网络中,当信息进行传播的时候,可以利用工具,将网络接口设置在监听的模式,便可将网络中正在传播的信息截获或者捕获到,从而进行攻击。<br /><br />网络监听在网络中的任何一个位置模式下都可实施进行。而黑客一般都是利用网络监听来截取用户口令。比如当有人占领了一台主机之后,那么他要再想将战果扩大到这个主机所在的整个局域网话,监听往往是他们选择的捷径。<br /><br />很多时候我在各类安全论坛上看到一些初学的爱好者,在他们认为如果占领了某主机之后那么想进入它的内部网应该是很简单的。其实非也,进入了某主机再想转入它的内部网络里的其它机器也都不是一件容易的事情。<br /><br />因为你除了要拿到他们的口令之外还有就是他们共享的绝对路径,当然了,这个路径的尽头必须是有写的权限了。在这个时候,运行已经被控制的主机上的监听程序就会有大收效。不过却是一件费神的事情,而且还需要当事者有足够的耐心和应变能力。<br /><br />主要包括:<br />  数据帧的截获<br />  对数据帧的分析归类<br />  dos攻击的检测和预防<br />  IP冒用的检测和攻击<br />  在网络检测上的应用<br />  对垃圾邮件的初步过滤<br /><br />关于Linux下网络监听技术主要有两个要点:<br /><br />  1)如何尽可能完整的截取网络上的数据帧,因为以太网上每时每刻都可能有信息传递,而且根据以太网的规模不同网络上的信息量也变化不大,所以截取数据帧不仅要保证数据帧的完整,而且还要考虑到如何才能减少漏截取数据帧。<br /><br />  2)就是对截取的数据帧的过滤分析,所谓监听当然要“听”得懂才行,所以把截取的数据帧翻译成我们能用的数据,监听才算成功。<br />&nbsp;<br /> &nbsp;&nbsp;<br />网络监听的原理<br /><br />  Ethernet协议的工作方式是将要发送的数据包发往连接在一起的所有主机。在包头中包括有应该接收数据包的主机的正确地址,因为只有与数据包中目标地址一致的那台主机才能接收到信息包,但是当主机工作在监听模式下的话不管数据包中的目标物理地址是什么,主机都将可以接收到。<br /><br />许多局域网内有十几台甚至上百台主机是通过一个电缆、一个集线器连接在一起的,在协议的高层或者用户来看,当同一网络中的两台主机通信的时候,源主机将写有目的的主机地址的数据包直接发向目的主机,或者当网络中的一台主机同外界的主机通信时,源主机将写有目的的主机IP地址的数据包发向网关。<br /><br />但这种数据包并不能在协议栈的高层直接发送出去,要发送的数据包必须从TCP/IP协议的IP层交给网络接口,也就是所说的数据链路层。网络接口不会识别IP地址的。<br /><br />在网络接口由IP层来的带有IP地址的数据包又增加了一部分以太祯的祯头的信息。在祯头中,有两个域分别为只有网络接口才能识别的源主机和目的主机的物理地址这是一个48位的地址,这个48位的地址是与IP地址相对应的,换句话说就是一个IP地址也会对应一个物理地址。<br /><br />对于作为网关的主机,由于它连接了多个网络,它也就同时具备有很多个IP地址,在每个网络中它都有一个。而发向网络外的祯中继携带的就是网关的物理地址。<br />Ethernet中填写了物理地址的祯从网络接口中,也就是从网卡中发送出去传送到物理的线路上。<br /><br />如果局域网是由一条粗网或细网连接成的,那么数字信号在电缆上传输信号就能够到达线路上的每一台主机。再当使用集线器的时候,发送出去的信号到达集线器,由集线器再发向连接在集线器上的每一条线路。<br /><br />这样在物理线路上传输的数字信号也就能到达连接在集线器上的每个主机了。当数字信号到达一台主机的网络接口时,正常状态下网络接口对读入数据祯进行检查,如果数据祯中携带的物理地址是自己的或者物理地址是广播地址,那么就会将数据祯交给IP层软件。<br /><br />对于每个到达网络接口的数据祯都要进行这个过程的。但是当主机工作在监听模式下的话,所有的数据祯都将被交给上层协议软件处理。<br />&nbsp;<br /> &nbsp;&nbsp;<br />当连接在同一条电缆或集线器上的主机被逻辑地分为几个子网的时候,那么要是有一台主机处于监听模式,它还将可以接收到发向与自己不在同一个子网(使用了不同的掩码、IP地址和网关)的主机的数据包,在同一个物理信道上传输的所有信息都可以被接收到。<br /><br />在UNIX系统上,当拥有超级权限的用户要想使自己所控制的主机进入监听模式,只需要向Interface(网络接口)发送I/O控制命令,就可以使主机设置成监听模式了。而在Windows9x的系统中则不论用户是否有权限都将可以通过直接运行监听工具就可以实现了。<br />&nbsp;<br /> &nbsp;&nbsp;<br />在网络监听时,常常要保存大量的信息(也包含很多的垃圾信息),并将对收集的信息进行大量的整理,这样就会使正在监听的机器对其它用户的请求响应变的很慢。<br /><br />同时监听程序在运行的时候需要消耗大量的处理器时间,如果在这个时候就详细的分析包中的内容,许多包就会来不及接收而被漏走。所以监听程序很多时候就会将监听得到的包存放在文件中等待以后分析。<br /><br />分析监听到的数据包是很头疼的事情。因为网络中的数据包都非常之复杂。两台主机之间连续发送和接收数据包,在监听到的结果中必然会加一些别的主机交互的数据包。监听程序将同一TCP会话的包整理到一起就相当不容易了,如果你还期望将用户详细信息整理出来就需要根据协议对包进行大量的分析。Internet上那么多的协议,运行进起的话这个监听程序将会十分的大哦。<br />现在网络中所使用的协议都是较早前设计的,许多协议的实现都是基于一种非常友好的,通信的双方充分信任的基础。<br /><br />在通常的网络环境之下,用户的信息包括口令都是以明文的方式在网上传输的,因此进行网络监听从而获得用户信息并不是一件难点事情,只要掌握有初步的TCP/IP协议知识就可以轻松的监听到你想要的信息的。<br />&nbsp;<br /> &nbsp;&nbsp;<br />以太网上的数据帧主要涉及Tcp/ip协议,针对以下几个协议的分析:IP,ARP,RARP,IPX,其中重点在于ip和&nbsp;arp协议,这两个协议是多数网络协议的基础,因此把他们研究彻底,就对大多数的协议的原理和特性比较清楚了。<br /><br />由于各种协议的数据帧个不相同,所以涉及很多的数据帧头格式分析,接下来将一一描述。<br />&nbsp;<br /> &nbsp;&nbsp;<br />在linux&nbsp;下监听网络,应先设置网卡状态,使其处于杂混模式以便监听网络上的所有数据帧。然后选择用Linux&nbsp;socket&nbsp;来截取数据帧,通过设置socket()&nbsp;函数参数值,可以使socket截取未处理的网络数据帧,关键是函数的参数设置,下面就是有关的程序部分:<br /><br /><br />代码:<br />if&nbsp;(&nbsp;(&nbsp;fd=socket&nbsp;(AF_INET,&nbsp;SOCK_PACKET,htons(0x0003)))&lt0)    {perror&nbsp;(“can&nbsp;get&nbsp;SOCK_PACKET&nbsp;socket      ”);    exit(0);    }<br /><br />AF_INET=2&nbsp;表示&nbsp;internet&nbsp;ip&nbsp;protocol<br /><br />SOCK_PACKET=10&nbsp;表示&nbsp;截取数据帧的层次在物理层,既不作处理。<br /><br />Htons(0x0003)表示&nbsp;截取的数据帧的类型为不确定,既接受所有的包。<br /><br />  总的设定就是网卡上截取所有的数据帧。这样就可以截取底层数据帧,因为返回的将是一个指向数据的指针,为了分析方便,我设置了一个基本的数据帧头结构。<br /><br /><br /><br />代码:<br />Struct&nbsp;etherpacket    {struct&nbsp;ethhdr&nbsp;eth;    struct&nbsp;iphdr&nbsp;ip;    struct&nbsp;tcphdr&nbsp;tcp;    char&nbsp;buff[8192];    }&nbsp;ep;&nbsp;<br /><br />将返回的指针赋值给指向数据帧头结构的指针,然后对其进行分析。<br />下是有关协议的报头:ethhdr&nbsp;这是以太网数据帧的mac报头:<br /><br /> |48bit&nbsp;目的物理地址&nbsp;|&nbsp;48bit&nbsp;源物理地址&nbsp;|&nbsp;16bit&nbsp;协议地址|<br /><br />相应的数据结构如下<br /><br /><br />代码:<br />struct&nbsp;ethhdr    {    unsigned&nbsp;char&nbsp;h_dest[ETH_ALEN];    unsigned&nbsp;char&nbsp;h_source[ETH_ALEN];    unsigned&nbsp;short&nbsp;h_proto;    }&nbsp;<br /><br />其中h_dest[6]是48位的目标地址的网卡物理地址,h_source&nbsp;[6]&nbsp;是48位的源地址的物理网卡地址。H_proto是16位的以太网协议,其中主要有0x0800&nbsp;ip,0x8035.X25,0x8137&nbsp;ipx,0x8863-0x8864&nbsp;pppoe(这是Linux的&nbsp;ppp),0x0600&nbsp;ether&nbsp;_loop_back&nbsp;,0x0200-0x0201&nbsp;pup等.<br /><br />Iphdr&nbsp;这是ip协议的报头,由此可以定义其结构如下:<br /><br /><br />代码:<br />struct&nbsp;iphdr    {    #elif&nbsp;defined&nbsp;(_LITTLE_ENDIAN_BITFIELD)    _u8&nbsp;version&nbsp;:4,    #elif&nbsp;defined&nbsp;(_BIG_ENDIAN_BITFIELD)    _u8&nbsp;version:4,    ihl:4;    #else    #error&nbsp;'Please&nbsp;fix'    #endif    _u8&nbsp;tos;    _16&nbsp;tot_len;    _u16&nbsp;id;    _u16&nbsp;frag_off;    _u8&nbsp;ttl;    _u8&nbsp;protocol;    _u16&nbsp;check;    _u32&nbsp;saddr;    _u32&nbsp;daddr;    };<br /><br />这是Linux&nbsp;的ip协议报头,针对版本的不同它可以有不同的定义,我们国内一般用BIG的定义,其中version&nbsp;是ip的版本,protocol是ip的协议分类主要有0x06&nbsp;tcp.0x11&nbsp;udp,0x01&nbsp;icmp,0x02&nbsp;igmp等<br />&nbsp;<br /> &nbsp;&nbsp;<br />saddr是32位的源ip地址,daddr是32位的目标ip地址,相应的数据结构:<br /><br /><br />代码:<br />struct&nbsp;arphdr    {    unsigned&nbsp;short&nbsp;int&nbsp;ar_hrd;    unsigned&nbsp;short&nbsp;int&nbsp;ar_pro;    unsigned&nbsp;char&nbsp;ar_hln;    unsigned&nbsp;char&nbsp;ar_pln;    unsigned&nbsp;short&nbsp;int&nbsp;ar_op;    #if&nbsp;0    unsigned&nbsp;char&nbsp;_ar_sha[ETH_ALEN];    unsigned&nbsp;char&nbsp;_ar_sip[4];    unsigned&nbsp;char&nbsp;_ar_tha[ETH_ALEN];    unsigned&nbsp;char&nbsp;_ar_tip[4];    #end&nbsp;if    };<br /><br />这是linux&nbsp;的arp&nbsp;协议报头,其中ar_hrd&nbsp;是硬件地址的格式,ar_pro协议地址的格式,ar_hln是硬件地址的长度,ar_pln时协议地址的长度,ar_op是arp协议的分类0x001是arp&nbsp;echo&nbsp;0x0002&nbsp;是&nbsp;arp&nbsp;reply.接下来的分别是源地址的物理地址,源ip地址,目标地址的物理地址,目标ip地址.<br /><br />Tcphdr&nbsp;ip协议的tcp协议报头以下是相应数据结构:<br /><br /><br />代码:<br />struct&nbsp;tcphdr    {    u_int16_t&nbsp;source;    u_int16_t&nbsp;dest;    u_int32_t&nbsp;seq;    u_int32_t&nbsp;ack_seq;    #&nbsp;if&nbsp;_BYTE_ORDER&nbsp;==&nbsp;_LITTLE&nbsp;_ENDIAN    u_int16_t&nbsp;resl:4;    u_int16_t&nbsp;doff:4;    u_int16_t&nbsp;fin:1;    u_int16_t&nbsp;syn:1;    u_int16_t&nbsp;rst:1;    u_int16_t&nbsp;psh:1;    u_int16_t&nbsp;ack:1;    u_int16_t&nbsp;urg:1;    u_int16_t&nbsp;res2:2;    #elif&nbsp;_BYTE&nbsp;_ORDER&nbsp;==&nbsp;_BIG&nbsp;_ENDIAN    u_int16_t&nbsp;doff:4;    u_int16_t&nbsp;res1:4;    u_int16_t&nbsp;res2:2;    u_int16_t&nbsp;urg:1;    u_int16_t&nbsp;ack:1;    u_int16_t&nbsp;psh:1;    u_int16_t&nbsp;rst:1;    u_int16_t&nbsp;syn:1;    u_int16_t&nbsp;fin:1;    #else    #error&nbsp;'Adjust&nbsp;your&nbsp;defines'    #endif    u_int16_t&nbsp;window;    u_int16_t&nbsp;check;    u_int16_t&nbsp;urg_ptr;    };<br /><br />这是Linux&nbsp;下tcp协议的一部分与ip协议相同取BIG,其中source是源端口,dest&nbsp;是目的端口,seq是s序,ack_seq是a序号,其余的是tcp的连接标志其中包括6个标志:syn表示连接请求,urg&nbsp;表示紧急信息,fin表示连接结束,ack表示连接应答,psh表示推栈标志,rst表示中断连接。window是表示接受数据窗口大小,check是校验码,urg&nbsp;ptr是紧急指针<br />Udphdr&nbsp;这是udp协议报头:<br /><br /><br />代码:<br />struct&nbsp;udphdr&nbsp;{    u_int16_t&nbsp;source;    u_int16_t&nbsp;dest;    u_int16_t&nbsp;len;    u_int16_t&nbsp;check;    }<br /><br />这是Linux下ip协议中udp协议的一部分,结构很明显&nbsp;source&nbsp;源端口,dest目的端口,len&nbsp;udp&nbsp;长度,check&nbsp;是校验码.<br /><br />Icmphdr&nbsp;这是ip协议的icmp协议的报头:<br /><br /><br />代码:<br />struct&nbsp;icmphdr    {    u_int8_t&nbsp;type;    u_int8_t&nbsp;code;    u_int16_t&nbsp;checksum;    union    {    struct    {    u_int16_t&nbsp;id;    u_int16_t&nbsp;sequence;    }&nbsp;echo;    u_int32_t&nbsp;gateway;    struct    {    u_int16_t_unused;    u_int16_t&nbsp;mtu;    }&nbsp;frag;    }&nbsp;un;<br />
armpc 发表于 2009-6-4 17:12 | 显示全部楼层

顶一个

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

53

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部