tcp端口扫描(python多线程)
1 使用单线程扫描单台主机
首先实现的是对单台主机中0-1024端口的扫描,发现差不多每秒扫描一个端口,很慢。
import socket def tcp_scanner(host,port): client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: client.connect((host, port)) print('connected to host %s,port %d successfully' %(host,port)) return True except: # print('connected to host %s,port %d failed' %(host,port)) return False if __name__ == '__main__': host = "192.168.10.10" for port in range(1024): tcp_scanner(host,port)
2 使用多线程扫描单台主机
import threading,socket def tcp_scanner(host,port): client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: client.connect((host, port)) print('connected to host %s,port %d successfully' %(host,port)) client.close() return True except: # print('connected to host %s,port %d failed' %(host,port)) return False if __name__ == '__main__': host = "192.168.10.10" for port in range(1,1024): th = threading.Thread(target=tcp_scanner,args=(host,port)) th.start()
在运行以上代码时,出现报错:RuntimeError: can't start new thread,原因是超过了线程启动数的上限。
解决办法是修改最大文件描述符打开数。
3 使用多线程扫描多台主机
import threading,socket,subprocess def tcp_scanner(host,port): client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: client.connect((host, port)) print('connected to host %s,port %d successfully' %(host,port)) client.close() return True except: # print('connected to host %s,port %d failed' %(host,port)) return False def main(): for i in range(2,255): # host = "10.224.32.%d" %i host = "192.168.136.%d" %i cmd = 'fping %s 1>/dev/null 2>&1;echo $?' %host p = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) ret = int(p.stdout.read()) if ret == 0: for port in range(1,4000): th = threading.Thread(target=tcp_scanner,args=(host,port)) th.start() else: print('status of %s:False' %host) if __name__ == '__main__': main()
上面的问题又出现了,可以用的文件描述符不够,即使改到655350。毕竟是全盘扫描。
解决办法是加信号threading.Semaphore,限制线程数
''' create 2018/9/24 version 1.0 auth jabbok info scan all the tcp port of the listed hosts by multithreading,to know is it listened ''' import threading,socket,subprocess,time screenLock = threading.Semaphore(value=1) def tcp_scanner(host,port): socket.setdefaulttimeout(1) client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: client.connect((host, port)) print('connected to host %s,port %d successfully' %(host,port)) client.close() screenLock.acquire() return True except: screenLock.acquire() return False finally: screenLock.release() client.close() def main(): for i in range(2,255): # host = "10.224.32.%d" %i host = "192.168.136.%d" %i cmd = 'fping %s 1>/dev/null 2>&1;echo $?' %host p = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True) ret = int(p.stdout.read()) if ret == 0: for port in range(1,4000): th = threading.Thread(target=tcp_scanner,args=(host,port)) th.start() else: print('status of %s:False' %host) if __name__ == '__main__': main()