其中
A的地址为:IP:192.168.10.1 MAC: AA-AA-AA-AA-AA-AA
B的地址为:IP:192.168.10.2 MAC: BB-BB-BB-BB-BB-BB
C的地址为:IP:192.168.10.3 MAC: CC-CC-CC-CC-CC-CC
假设B是属于一个嗅探爱好者的, 比如A机器的ARP缓存:
C:\>arp -aInterface: 192.168.10.1 on Interface 0x1000003 Internet Address Physical Address Type 192.168.10.3 CC-CC-CC-CC-CC-CC dynamic |
这是192.168.10.1机器上的ARP缓存表, 假设, A进行一次ping 192.168.10.3操作, PING主机C, 会查询本地的
ARP缓存表, 找到C的IP地址的MAC地址, 那么就会进行数据传输, 目的地就是C 的MAC地址。 如果A中没有C的ARP记
录, 那么A首先要广播一次ARP请求, 当C接收到A 的请求后就发送一个应答, 应答中包含有C的MAC地址, 然后A接
收到C的应答, 就会更新本地的ARP缓存。 接着使用这个MAC地址发送数据(由网卡附加MAC地址)。
因此, 本地高速缓存的这个ARP表是本地网络流通的基础, 而且这个缓存是动态的。
很多网络都是用Hub进行连接的。 数据包经过Hub传输到其他计算机的时候, Hub只是简单地把这个数据包广播
到Hub的所有端口上。
这就是上面举例中的一种网络结构。
现在A需要发送TCP数据包给C。 首先, A需要检查本地的ARP 缓存表, 查看是否有IP为192.168.10.3即C的ARP记
录, 如果没有那么A将要广播一个ARP请求, 当C接收到这个请求后, 就作出应答, 然后A更新自己的ARP缓存表。 并
且获得与C的IP相对应的MAC地址。 这时就传输这个TCP数据包, Ethernet帧中就包含了C的MAC地址。 当数据包传输
到HUB的时候, HUB直接把整个数据包广播到所有的端口, 然后C就能够接收到A发送的数据包。
正因为HUB把数据广播到所有的端口, 所以计算机B也能够收到A发送给C的数据包。 这正是达到了B嗅探的目的。
因此, Hub-Based的网络基本没有安全可言, 嗅探在这样的网络中非常容易。
交换机用来代替HUB, 正是为了能够解决HUB的几个安全问题, 其中就是能够来解决嗅探问题。 Switch不是把数
据包进行端口广播, 它将通过自己的ARP缓存来决定数据包传输到那个端口上。 因此, 在交换网络上, 如果把上面
例子中的HUB换为Switch, B就不会接收到A发送给C的数据包, 即便设置网卡为混杂模式, 也不能进行嗅探。
ARP协议并不只在发送了ARP请求才接收ARP应答。 当计算机接收到ARP应答数据包的时候, 就会对本地的ARP缓存
进行更新, 将应答中的IP和MAC地址存储在ARP缓存中。 因此, 在上面的假设网络中, B向A发送一个自己伪造的ARP应
答, 而这个应答中的数据为发送方IP地址是192.168.10.3(C的IP地址), MAC地址是DD-DD-DD-DD-DD-DD(C的MAC地
址本来应该是CC-CC-CC-CC-CC-CC, 这里被伪造了)。 当A接收到B伪造的ARP应答, 就会更新本地的ARP缓存(A可不
知道被伪造了)。
现在A机器的ARP缓存更新了:
C:\>arp -aInterface: 192.168.10.1 on Interface 0x1000003 Internet Address Physical Address Type 192.168.10.3 DD-DD-DD-DD-DD-DD dynamic |
这可不是小事。 局域网的网络流通可不是根据IP地址进行, 而是按照MAC地址进行传输。 现在192.168.10.3的
MAC地址在A上被改变成一个本不存在的MAC地址。 现在A开始Ping 192.168.10.3, 网卡递交的MAC地址是
DD-DD-DD-DD-DD-DD, 结果是什么呢?网络不通, A根本不能Ping通C!!
这就是一个简单的ARP欺骗。
我们来实现这样的ARP欺骗。 这里需要使用一个WinPcap提供的API和驱动。 (http://winpcap.polito.it/)
winpcap是一个伟大而且开放的项目。 Windows环境下的nmap、snort、windump都是使用的winpcap。
/////////////////////////////////////////////////////////// ARP Sender//// Creator: Refdom// Email: refdom@263.net// Home Page: www.opengram.com//// 2002/4/7/////////////////////////////////////////////////////////#include "stdafx.h"#include "Mac.h"//GetMacAddr(), 我写的把字符串转换为MAC地址的函数, 就不列在这里了#include |