arp协议详解攻击原理简单攻击源码

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

一.关于ARP协议的基础知识1.ARP的工作原理我们都知道以太网设备比如网卡都有自己全球唯一的MAC地址,它们是以MAC地址来传输以太网数据包的,但是它们却识别不了我们IP包中的IP地址,所以我们在以太网中进行IP通信的时候就需要一个协议来建立IP地址与MAC地址的对应关系,以使IP数据包能发到一个确定的地方去。这就是ARP(AddressResolutionProtocol,地址解析协议)。讲到此处,我们可以在命令行窗口中,输入arp–a来看一下效果,类似于这样的条目210.118.45.10000-0b-5f-e6-c5-d7dynamic就是我们电脑里存储的关于IP地址与MAC地址的对应关系,dynamic表示是临时存储在ARP缓存中的条目,过一段时间就会超时被删除(xp/2003系统是2分钟)。这样一来,比如我们的电脑要和一台机器比如210.118.45.1通信的时候,它会首先去检查arp缓存,查找是否有对应的arp条目,如果没有,它就会给这个以太网络发ARP请求包广播询问210.118.45.1的对应MAC地址,当然,网络中每台电脑都会收到这个请求包,但是它们发现210.118.45.1并非自己,就不会做出相应,而210.118.45.1就会给我们的电脑回复一个ARP应答包,告诉我们它的MAC地址是xx-xx-xx-xx-xx-xx,于是我们电脑的ARP缓存就会相应刷新,多了这么一条:210.118.45.1xx-xx-xx-xx-xx-xxdynamic为什么要有这么一个ARP缓存呢,试想一下如果没有缓存,我们每发一个IP包都要发个广播查询地址,岂不是又浪费带宽又浪费资源?而且我们的网络设备是无法识别ARP包的真伪的,如果我们按照ARP的格式来发送数据包,只要信息有效计算机就会根据包中的内容做相应的反应.试想一下,如果我们按照ARP响应包的相应的内容来刷新自己的ARP缓存中的列表,嘿嘿,那我们岂不是可以根据这点在没有安全防范的网络中玩些ARP包的小把戏了?在后面的文章里我就手把手来教你们如何填充发送ARP包,不过先别急,我们再继续学点基础知识^_^2.ARP包的格式既然我们要来做一个我们自己的ARP包,当然首先要学习一下ARP包的格式。从网络底层看来,一个ARP包是分为两个部分的,前面一个是物理帧头,后面一个才是ARP帧。首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLCHeader,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。DLCHeader字段长度(Byte)默认值备注接收方MAC6广播时,为ff-ff-ff-ff-ff-ff发送方MAC6Ethertype20x08060x0806是ARP帧的类型值图1物理帧头格式图1是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接收端的物理地址罢了,是不是很简单呢?接下来我们看一下ARP帧的格式.ARPFrame字段长度(Byte)默认值备注硬件类型20x1以太网类型值上层协议类型20x0800上层协议为IP协议MAC地址长度10x6以太网MAC地址长度为6IP地址长度10x4IP地址长度为4操作码20x1表示ARP请求包,0x2表示应答包发送方MAC6发送方IP4接收方MAC6接收方IP4填充数据18因为物理帧最小长度为64字节,前面的42字节再加上4个CRC校验字节,还差18个字节图2ARP帧格式我们可以看到需要我们填充的同样也只是MAC,IP,再加上一个1或2的操作码而已。3.ARP包的填充1)请求包的填充:比如我们的电脑MAC地址为aa-aa-aa-aa-aa-aa,IP为192.168.0.1我们想要查询192.168.0.99的MAC地址,应该怎么来做呢?首先填充DLCHeader,通过前面的学习我们知道,想要知道某个计算机对应的MAC地址是要给全网发送广播的,所以接收方MAC肯定是ffffffffffff,发送方MAC当然是自己啦,于是我们的DLCHeader就填充完成了,如图,加粗的是我们要手动输入的值(当然我编的程序比较智能,会根据你选择的ARP包类型帮你自动填入一些字段,你一用便知^_^)。DLCHeader字段长度(Byte)填充值接收方MAC6ffffffffffff发送方MAC6aaaaaaaaaaaaEthertype20x0806图3ARP请求包中DLCHeader内容接下来是ARP帧,请求包的操作码当然是1,发送方的MAC以及IP当然填入我们自己的,然后要注意一下,这里的接收方IP填入我们要查询的那个IP地址,就是192.168.0.99了,而接收方MAC填入任意值就行,不起作用,于是,如图,ARPFrame字段长度(Byte)填充值硬件类型21上层协议类型20800MAC地址长度16IP地址长度14操作码21发送方MAC6aaaaaaaaaaaa发送方IP4192.168.0.1接收方MAC6任意值xxxxxxxxxxxx接收方IP4192.168.0.99填充数据180图4ARP请求包中ARP帧的内容如果我们构造一个这样的包发送出去,如果192.168.0.99存在且是活动的,我们马上就会收到一个192.168.0.99发来的一个响应包,我们可以查看一下我们的ARP缓存列表,是不是多了一项类似这样的条目:192.168.0.99bb-bb-bb-bb-bb-bb是不是很神奇呢?我们再来看一下ARP响应包的构造2)响应包的填充有了前面详细的解说,你肯定就能自己说出响应包的填充方法来了吧,所以我就不细说了,列两个表就好了比如说给192.168.0.99(MAC为bb-bb-bb-bb-bb-bb)发一个ARP响应包,告诉它我们的MAC地址为aa-aa-aa-aa-aa-aa,就是如此来填充各个字段DLCHeader字段长度(Byte)填充值接收方MAC6bbbbbbbbbbbb发送方MAC6aaaaaaaaaaaaEthertype20x0806图5ARP响应包中DLCHeader内容ARPFrame字段长度(Byte)填充值硬件类型21上层协议类型20800MAC地址长度16IP地址长度14操作码22发送方MAC6aaaaaaaaaaaa发送方IP4192.168.0.1接收方MAC6bbbbbbbbbbbb接收方IP4192.168.0.99填充数据180图6ARP响应包中ARP帧的内容这样192.168.0.99的ARP缓存中就会多了一条关于我们192.168.0.1的地址映射。好了,终于到了编程实现它的时候了^_^我们主要是要用到pcap_open_live函数,不过这个函数winpcap的开发小组已经建议用pcap_open函数来代替,不过因为我的代码里面用的就是pcap_open_live,所以也不便于修改了,不过pcap_open_live使用起来也是没有任何问题的,下面是pcap_open_live的函数声明:/*************************************************pcap_t*pcap_open_live(char*device,intsnaplen,intpromisc,intto_ms,char*ebuf)功能:根据网卡名字打开网卡,并设置为混杂模式,然后返回其句柄参数:Device:就是前前面我们获得的网卡的名字;Snaplen:我们从每个数据包里取得数据的长度,比如设置为100,则每次我们只是获得每个数据包100个长度的数据,没有什么特殊需求的话就把它设置为65535最大值就可以了;Promisc:这个参数就是设置是否把网卡设置为“混杂模式”,设置为1即可;to_ms:超时时间,毫秒,一般设置为1000即可。返回值:pcap_t:类似于一个网卡“句柄”之类的,不过当然不是,这个参数是后面截获数据要用到的。******************************************************************************/虽然看起来比较复杂,不过用起来还是非常简单的,其实1行就OK了:pcap_t*adhandle;charerrbuf[PCAP_ERRBUF_SIZE];//打开网卡,并且设置为混杂模式//pCardName是前面传来的网卡名字参数adhandle=pcap_open_live(pCardName,65535,1,1000,errbuf);C.截获数据包并保存为文件:------------------------------------------------------当然,不把数据包保存为文件也可以,不过如果不保存的话,只能在截获到数据包的那一瞬间进行分析,转眼就没了^_^所以,为了便于日后分析,所以高手以及我个人经常是把数据包保存下来的慢慢分析的。但是注意网络流量,在流量非常大的时候注意硬盘空间呵呵,常常几秒中就有好几兆是很正常的事情。下面首先来详细讲解一下,这个步骤中需要用到的winpcap函数:/**************************************************************pcap_dumper_t*pcap_dump_open(pcap_t*p,constchar*fname)功能:建立或者打开存储数据包内容的文件,并返回其句柄参数:pcap_t*p:前面打开的网卡句柄;constchar*fname:要保存的文件名字返回值:pcap_dumper_t*:保存文件的描述句柄,具体细节我们不用关心***************************************************************//***************************************************************intpcap_next_ex(pcap_t*p,structpcap_pkthdr**pkt_header,u_char**pkt_data)功能:从网卡或者数据包文件中读取数据内容参数:pcap_t*p:网卡句柄structpcap_pkthdr**pkt_header:并非是数据包的指针,只是与数据包捕获驱动有关的一个Headeru_char**pkt_data:指向数据包内容的指针,包括了协议头返回值:1:如果成功读取数据包0:pcap_open_live()设定的超时时间之内没有读取到内容-1:出现错误-2:读文件时读到了末尾***************************************************************//***************************************************************voidpcap_dump(u_char*user,conststructpcap_pkthdr*h,constu_char*sp)功能:将数据包内容依次写入pcap_dump_open()指定的文件中参数:u_char*user:网卡句柄conststructpcap_pkthdr*h:并非是数据包的指针,只是与数据包捕获驱动有关的一个Headerconstu_char*sp:数据包内容指针返回值:Void****************************************************************/下面给出一段完整的捕获数据包的代码,是在线程中写的,为了程序清晰,我去掉了错误处理代码以及线程退出的代码,完整代码可下载文后的示例源码,老规矩,重要的步骤用粗体字标出。我们实际在捕获数据包的时候也最好是把代码放到另外的线程中。/**********************************************************进程:*这个是程序的核心部分,完成数据包的截获*参数:*p

1 / 23
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功