1 #coding = utf-8 2 3 ''' 4 python 3.4 5 通過簡單的TCP端口連接來判斷指定IP是否開放了指定端口。 6 ''' 7 8 import socket 9 import optparse 10 import re 11 import threading 12 import sys 13 14 def anlyze_host(target_host): 15 #將從--host參數獲取到的目標值轉換為標准的xxx.xxx.xxx.xxx形式,其中主要是利用socket的gethostbyname函數將域名形式的值轉換為四位點進制形式 16 try: 17 pattern = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') #匹配標准點進制的IP 18 match = pattern.match(target_host) 19 if match: 20 return(match.group()) 21 else: 22 try: 23 target_host = socket.gethostbyname(target_host) #如果不是,就把target_host的值作為域名進行解析 24 return(target_host) 25 except Exception as err: 26 print('地址解析錯誤:',err) 27 exit(0) 28 except Exception as err: 29 print('請注意錯誤1:',sys.exc_info()[0],err) 30 print(parser.usage) 31 exit(0) 32 33 34 def anlyze_port(target_port): 35 #解析--port參數傳入的值,返回端口列表 36 try: 37 pattern = re.compile(r'(\d+)-(\d+)') #解析連接符-模式 38 match = pattern.match(target_port) 39 if match: 40 start_port = int(match.group(1)) 41 end_port = int(match.group(2)) 42 return([x for x in range(start_port,end_port + 1)]) 43 else: 44 return([int(x) for x in target_port.split(',')]) 45 except Exception as err: 46 print('請注意錯誤2:',sys.exc_info()[0],err) 47 print(parser.usage) 48 exit(0) 49 50 def scanner(target_host,target_port): 51 #創建一個socket對象 52 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 53 s.settimeout(5) 54 try: 55 s.connect((target_host,target_port)) 56 #s.sendall(b'hello\r\n\r\n') 57 #message = s.recv(100) 58 #if message: 59 print('[+]%s的%3s端口:打開' % (target_host,target_port)) #若可以建立連接,表示此端口是打開的 60 # print(' %s' % message.decode('utf-8')) 61 except socket.timeout: 62 print('[-]%s的%3s端口:關閉' % (target_host,target_port)) #如果連接超時,表示此端口關閉 63 except Exception as err: 64 print('請注意錯誤3:',sys.exc_info()[0],err) 65 exit(0) 66 67 68 69 def main(): 70 usage = 'Usage:%prog -h <host> -p <port>' 71 parser = optparse.OptionParser(usage,version='%prog v1.0') 72 parser.add_option('--host',dest='target_host',type='string', 73 help='需要掃描的主機,域名或IP') 74 parser.add_option('--port',dest='target_port',type='string', 75 help='需要掃描的主機端口,支持1-100或21,53,80兩種形式') 76 (options,args) = parser.parse_args() 77 if options.target_host == None or options.target_port == None: 78 print(parser.usage) 79 exit(0) 80 else: 81 target_host = options.target_host 82 target_port = options.target_port 83 84 target_host = anlyze_host(target_host) 85 target_port = anlyze_port(target_port) 86 87 for port in target_port: 88 t = threading.Thread(target=scanner,args=(target_host,port))#多線程掃描端口 89 t.start() 90 91 if __name__ == '__main__': 92 main()
運行的結果為:
1 c:\Python34\python.exe TcpScanner.py --host 192.168.2.1 --port 1-1024 2 [+]192.168.2.1的 25端口:打開 3 [+]192.168.2.1的110端口:打開 4 [+]192.168.2.1的119端口:打開 5 [+]192.168.2.1的143端口:打開 6 [+]192.168.2.1的465端口:打開 7 [+]192.168.2.1的563端口:打開 8 [+]192.168.2.1的587端口:打開 9 [+]192.168.2.1的993端口:打開 10 [+]192.168.2.1的995端口:打開 11 [+]192.168.2.1的 80端口:打開 12 [-]192.168.2.1的 1端口:關閉 13 [-]192.168.2.1的 18端口:關閉 14 [-]192.168.2.1的 4端口:關閉 15 [-]192.168.2.1的 8端口:關閉 16 [-]192.168.2.1的 13端口:關閉 17 [-]192.168.2.1的 9端口:關閉 18 [-]192.168.2.1的 42端口:關閉 19 [-]192.168.2.1的 19端口:關閉 20 [-]192.168.2.1的 67端口:關閉 21 [-]192.168.2.1的 21端口:關閉 22 [-]192.168.2.1的 14端口:關閉 23 [-]192.168.2.1的 17端口:關閉 24 ……