利用Python线程池以及队列模块实现PING扫描
本工具开始编写的时候使用多线程模块threading,但是发现运行的时候会报出很多的错误,其中一个解决办法是在创建的新的线程的时候,time.sleep()一定的时间,但这就从一定程度上失去了多线程的意义,还有一个比较简便的办法是利用线程池,ThreadPoolExecutor,可以指定线程池中的线程数,然后由ThreadPoolExecutor进行调度。
此外,子线程与主线程之间的变量是不能共享的,比如起初设想用列表存放活跃主机self.alive_hosts = [],但最后这个结果是错误的,因此需要用queue模块来存储这样的共享变量,然后在主线程中打印显示出来。
1 from scapy.all import * 2 import logging 3 import optparse 4 import sys 5 import ipaddress 6 import threading #开始用的是threading模块,后来改用线程池模块 7 import time 8 import queue 9 from concurrent.futures import ThreadPoolExecutor 10 11 logging.getLogger('scapy.runtime').setLevel(logging.ERROR) 12 13 class PingNetwork: 14 def __init__(self) -> None: 15 self.network = self.get_params() #目标网络(格式:192.168.140.0/24) 16 self.alive_hosts = [] #如果不用多线程,那么这个列表可以作为存放活跃主机的变量,但是如果用多线程,需要用队列 17 self.q = queue.Queue() 18 19 20 def get_params(self): 21 parser = optparse.OptionParser('Usage: < Program > -n network') 22 parser.add_option('-n', '--network', dest='network', type='string', help='Specify network to scan') 23 options, args = parser.parse_args() 24 if options.network is None: 25 print(parser.usage) 26 sys.exit(0) 27 try: 28 network = ipaddress.ip_network(options.network) #对于用户输入的网络参数通过ipaddress模块转换为相应的迭代对象 29 return network 30 except: 31 print("[-] Input ip network wirth right format. e.g 192.168.4.0/24") 32 sys.exit() 33 34 def icmp_host(self, ip): 35 try: 36 packet = IP(dst=ip)/ICMP() 37 res = sr1(packet, timeout=2, verbose=False) 38 # print(res, type(res)) 39 if res: 40 if res.type == 0: #判断是否为echo-reply 41 # print("="*100) 42 self.q.put(ip) 43 except: 44 pass 45 46 def run(self): 47 with ThreadPoolExecutor(30) as t: #这里用到线程池,并指定了线程数为30 48 for ip in self.network: 49 ip = str(ip) 50 t.submit(self.icmp_host, ip=ip) #submit方法与threading.Thread中方法的传入参数的方式不一样 51 52 53 if self.q.empty(): 54 55 print("[0] No online host found!") 56 else: 57 while not self.q.empty(): 58 print("[-] Online hosts as follows: \n") 59 60 print("\t%s" % self.q.get()) 61 62 if __name__ == "__main__": 63 pinger = PingNetwork() 64 pinger.run()
STRIVE FOR PROGRESS,NOT FOR PERFECTION