ARP(地址解析协议)是一种把物理地址地址转换成逻辑地址的通讯协议,它属于TCP/IP协议栈中的数据链路层协议。下图是Wiki上的一副截图
公司主营业务:做网站、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出南宁免费做网站回馈大家。
所以它只有两层数据包头——以太网头、ARP头(TCP协议有三层,以太网头、IP头、TCP头;HTTP协议有四层,以太网头、IP头、TCP头、HTTP头)。
我一直使用物理地址、逻辑地址这两个术语;ARP是一种地址解析协议所以它可以实现任何两种地址之间的转换。只不过我们常用的是MAC地址转换成IP地址。
首先用tcpdump抓ARP包。(tcpdump -i en0 -xx -vvvv -n -e arp,希望你还记得这个最常用的选项。e选项表示输出以太网头部,-xx表示输出以太网16进制头部)
第二条数据包ARP回应,大家可以自行解读。
ARP攻击的原理
通过上面的数据包分析不难看出,ARP协议是非常天真的协议——发送ARP请求->解读ARP回应。PC1喊一句——谁有IP地址192.168.31.1,快点把MAC地址发给我;如果PC2拥有这个IP地址则回应ARP请求。但是这只是理想情况,事实上一个没有拥有IP地址192.168.31.1的机器也是可以发送回应包的。如果PC1信以为真那么就会拿到错误的“IP地址<->MAC地址”关系。这就是ARP攻击。
从应用层面看机器之间通讯是基于IP地址的,但是操作系统在发送数据包的时候会在IP头部加上以太网头。这是由于以太网规范所决定的——数据包在网络上传送使用的地址都是物理地址。错误“IP<->MAC映射”会导致“数据包不可达”——通俗的说“连不上对方”。如果这个IP地址刚好是网关,那就意味着——“断网”。
实施ARP攻击需要解决三个问题
探测ARP请求
以太网是“共享传输介质”,所以任何在网络上传递的数据包都可以被所有网卡探测到。为了减轻网卡的压力网卡设计的时候会只选择读取和自己MAC地址匹配的数据包(以太网数据包头目标地址=自己MAC地址)所以操作系统是无法读取“所有数据包”的。当然,这个开关是可以被关闭的——这就是混杂模式。在这种模式下所有的数据包都会被网卡接受并且传递到操作系统的TCP/IP协议栈。
ARP请求本身就是广播数据包所以我们打不打开"混杂模式"都可以弹出到ARP请求。我一般习惯开启混杂模式。
实现网络探测的库基本上都是脱胎于libpcap(包括tcpdump),这是一个非常历史悠久的库,我们直接上代码。
pcap_open_live第一个参数是网卡名字(比如:eth0),65545表示最大捕获65545bytes的数据包(其实我们永远到不了这个数字,一般1460或者1500就可以了),1表示开启混杂模式,0表示一直抓取数据;errbuf错误消息如果函数调用失败会把错误信息写入到这个字符串中。
pcap_loop第一个参数是pcap_open_live的返回值,它是一个结构体;第二个参数是抓取次数,-1表示一直抓取;on_pcaket是一个函数,每当抓取到数据包都会调用该函数(回调);最后一个参数是一个指针把共享数据传递到回调函数里面。
这个就是on_pcaket的原型(第一个参数是pcap_loop的最后一个参数),pkthdr表示抓取到数据包头指针;packet是数据包。
我们可以在on_packet里面直接判断packet是否为ARP请求
packet表示完整的数据包,所以它的开头一定是以太网数据包头。我们直接看结构体
就是以太网头的三个字段。
跳过以太网头一定是ARP头部,所以我们定义了指针arp_hdr。
发送ARP回应数据包
socket的封装提供了TCP和UDP两种接口,而我们要构造的ARP数据包不属于这两种所以只能通过RAW类型的socket来写入自己构造的数据包。我们使用libetnet来完成这个工作。
第一个参数告诉libnet,我们要直接构造数据链路层数据包——自己填充以太网头和ARP头;第二个参数是要发送数据包的网卡,第三个参数是错误处理。
构造一个ARPOP_REPLY类型的数据包(回应);mac_addr是自己的MAC地址;tpa是请求arp的目标地址(对于我们来说是源地址——即便我们不是192.168.31.1也是可以填写这个字段,系统不会校验这部分数据);后面的数据都可以通过以太网头和arp头填充。
最后加上以太网头
然后就可以发送了
请求者“应用”的回应包
PC1发送ARP请求,如果被我们的程序探测到并且我们“编造”一个ARP回应那么对于PC1来说它会收到两次ARP回应。一条是正确的ARP回应,一条是我们编造的ARP回应。
对于Windows来说它会选择最后到达的回应应用;对于Linux来说它会选择第一个到达的回应应用。(所以一些简单的ARP攻击Linux是天生免疫的,此处你可以尽情吐槽一下Windows的弱智)
所以如果我们要攻击Windows只需要sleep(1)再发送回应就行了;对于Linux来说就比较困难了——我们很难保证自己的数据包会优先到达。但是正所谓道高一次魔高一丈,我们不能欺骗Linux主机但是可以冒充Linux主机啊。简单来说就是:当网关发送ARP请求探测PC的时候我们可以冒充PC回应网关的请求,这也会到导致——断网。
尽情发挥吧
我只能提供一个简单的Demo,它会回应整个网络内所有的ARP请求(除了自己)。你可以加上一些判断语句实现“精准打击”只针对某个机器(比如知道它的IP地址或者MAC地址)。还可以发挥更多想象~~~
小心开车
ARP的防护办法其实很简单,以360的流量防火墙为例。它启动的时候会首先拿到当前网关的MAC地址,通过修改系统底层所有的ARP回应数据包都不会被真正的应用,这样就实现了“防”(你可以用MAC+IP地址绑定的方式固定网关,但是显的不够高大上)。
当收到ARP回应的时候360会比较自己保存的网关MAC地址,如果发现MAC地址发生了变化就认为发现了ARP攻击。最最致命的——无论你怎么伪造你都会暴漏自己的mac地址(回应ARP的时候头部以太网头的源地址是你自己的MAC地址)这是由于网卡本身的限制,如果mac地址不是自己的数据包是“发不出去的”。
完整代码
https://gist.github.com/fireflyc/796f55d54be39e629a2a1fcb2607a33b
总结
除了做坏事这种框架还可以做很多事情。它们的思路基本上都是一致的——探测数据包,通过应用处理,返回数据包。比如我们可以用DPDK(一种高性能的数据平面开发工具包,彻底无视Linux和TCP/IP协议栈)来探测数据包,通过移植TCP/IP协议到用户空间来绕过操作系统(kernel bypass)。
经过多年的努力我们已经解决了C10k的问题,现在又有人提出来C10M问题。基本上很多人的观点都基于kernel空间的TCP/IP是没有办法做到这一点的(受限于打开文件数量、维护每个连接的开销、操作系统处理网卡的方式),解决办法正是这种——kernel bypass的思路。
已经有人做了相关的工作比如libuinet、dpdk-ans,甚至还有人基于dpdk + dpdk-ans(用户空间TCP/IP协议栈) 移植了nginx(dpdk-nginx)。陈硕老师有一篇《C1000k 新思路:用户态TCP/IP 协议栈》大家也可以学习一下。
【本文是专栏作者邢森的原创文章,转载请联系作者本人获取授权】
新闻标题:深入理解ARP攻击
本文来源:http://www.stwzsj.com/qtweb/news18/2218.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联