python3-端口扫描(TCP connect扫描,SYN扫描,FIN扫描)
利用python3进行端口扫描,TCP的方式有connect扫描,SYN扫描,FIN扫描,NULL扫描,ACK扫描,Xmas,windows扫描。本次展示前三种,代码仅供参数:
- 扫描方式 1:TCP connect扫描
扫描端与目标主机建立tcp连接,完成三次握手后,扫描端主动关闭连接(缺点:目标主机会记录下连接内容)
# -*- coding: utf-8 -*- import queue import socket import threading ''' 功能介绍: 通过TCPconnect进行端口扫描,需要用户输入ip,port,线程数(默认10) 函数介绍: Portscan_print(ip) #结果排序打印 Portscan_Threadfun(ip) #线程分配函数 Portscan_TCPconnect(ip, p) #扫描功能实现 Portscan_threadnum(ip,num=10) #控制线程数量 Portscan_portlist(ip,userport) #扫描端口处理 ''' def Portscan_Threadfun(ip): # 工具人 while True: if q.empty(): # 判断队列是否为空 break else: port = q.get() # 取出一个端口 Portscan_TCPconnect(ip, port) def Portscan_TCPconnect(ip, p): # TCPconnect功能实现 try: port = int(p) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if port == 3306 or port == 22 or port == 23 or port == 1521: s.settimeout(4) else: s.settimeout(1) s.connect((ip, port)) openport_list.append(port) except Exception as e: closeport_list.append(port) finally: s.close() def Portscan_print(ip): # 打印函数,排序 openport_list.sort() for i in openport_list: print(ip + "\t" + str(i) + " Open\t\t") closeport_list.sort() for i in closeport_list: print(ip + "\t" + str(i) + " Close") def Portscan_threadnum(ip, num=10): # 控制线程函数 thread_joinlist = [] for i in range(0, num): # 控制线程数 new_thread = threading.Thread(target=Portscan_Threadfun, args=(ip,)) new_thread.start() thread_joinlist.append(new_thread) for i in thread_joinlist: i.join() # 循环等待每个线程完成任务,之后在进行打印工作 def Portscan_portlist(ip, threadnum, userport=0): # 端口处理函数 global q global openport_list global closeport_list q = queue.Queue() openport_list = [] closeport_list = [] if userport: if ',' in userport: ports = userport.split(',') elif '-' in userport: ports = userport.split('-') tmpports = [] [tmpports.append(i) for i in range(int(ports[0]), int(ports[1]) + 1)] ports = tmpports else: ports = [userport] else: print('Default Ports') ports = [21, 22, 23, 53, 80, 111, 139, 161, 389, 443, 445, 512, 513, 514, 873, 1025, 1433, 1521, 3128, 3306, 3311, 3312, 3389, 5432, 5900, 5984, 6082, 6379, 7001, 7002, 8000, 8080, 8081, 8090, 9000, 9090, 8888, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 50030, 50070] [q.put(i) for i in ports] # 将端口加入queue队列 Portscan_threadnum(ip, threadnum) Portscan_print(ip) # 打印输出函数 if __name__ == '__main__': ip = '104.193.88.77' userport = '443' threadnum = 20 Portscan_portlist(ip, threadnum, userport)
- 扫描方式 2:SYN扫描
扫描主机主动向目标主机指定端口发送SYN数据,表示建立连接请求,如果目标主机回应SYN+ACK,说明端口活动。回复RST说明目标端口不存活。接着扫描主机回一个RST给目标主机拒绝连接。导致三次握手失败(不会留下连接记录)
# -*- coding: utf-8 -*- import queue import threading from scapy.sendrecv import sr from scapy.layers.inet import IP, TCP ''' 功能介绍: 通过TCPSYN进行端口扫描,需要用户输入ip,port,线程数(默认10) ''' def Portscan_Threadfun(ip): # 工具人 while True: if q.empty(): # 判断队列是否为空 break else: port = q.get() # 取出一个端口 Portscan_SYN(ip, port) def Portscan_SYN(ip, port): try: temp = sr(IP(dst=ip) / TCP(dport=(int(port)), flags='S'), timeout=2, verbose=False) if temp[0].res: result = temp[0].res # temp分回复和无回显 if (result[0][1].payload.flags) == 'SA': print('端口开放') openport_list.append(port) return 1 else: closeport_list.append(port) else: closeport_list.append(port) return 0 except: closeport_list.append(port) return 0 def Portscan_print(ip): # 打印函数,排序 openport_list.sort() for i in openport_list: print(ip + "\t" + str(i) + " Open\t\t") closeport_list.sort() for i in closeport_list: print(ip + "\t" + str(i) + " Close") def Portscan_threadnum(ip, num=10): # 控制线程函数 thread_joinlist = [] for i in range(0, num): # 控制线程数 new_thread = threading.Thread(target=Portscan_Threadfun, args=(ip,)) new_thread.start() thread_joinlist.append(new_thread) for i in thread_joinlist: i.join() # 循环等待每个线程完成任务,之后在进行打印工作 def Portscan_synport(ip,userport,threadnum=50): global q global openport_list global closeport_list openport_list = [] closeport_list = [] q = queue.Queue() if userport: if ',' in userport: ports = userport.split(',') elif '-' in userport: ports = userport.split('-') tmpports = [] [tmpports.append(i) for i in range(int(ports[0]), int(ports[1]) + 1)] ports = tmpports else: ports = [userport] else: print('Default Ports') ports = [21, 22, 23, 53, 80, 111, 139, 161, 389, 443, 445, 512, 513, 514, 873, 1025, 1433, 1521, 3128, 3306, 3311, 3312, 3389, 5432, 5900, 5984, 6082, 6379, 7001, 7002, 8000, 8080, 8081, 8090, 9000, 9090, 8888, 9200, 9300, 10000, 11211, 27017, 27018, 50000, 50030, 50070] [q.put(i) for i in ports] #将端口加入队列 Portscan_threadnum(ip,threadnum) Portscan_print(ip) if __name__ == '__main__': ip = '192.168.0.110' port = '400-500' Portscan_synport(ip,port)
- 扫描方式 3:FIN扫描
FIN扫描和NULL扫描类似,将标志位FIN置1,如果端口开放,则没有反应,端口关闭,目标主机会发送RST,同样在windows上不适用
from scapy.layers.inet import IP, TCP from scapy.sendrecv import sr, sr1 ''' 适用于Linux设备 通过设置flags位为'FIN',不回复则表示端口开启,回复并且回复的标志位为RST表示端口关闭 ''' def fin_scan(ip, port): p = IP(dst=ip) / TCP(dport=int(port), flags="F") ans = sr1(p, timeout=1, verbose=1) print(ans) if ans == None: print(ip, "port", port, "is open.") elif ans != None and ans[TCP].flags == 'RA': ans.display() print(ip, "port", port, "is closed.") if __name__ == '__main__': ip = '192.168.0.112' port = 55 fin_scan(ip,port)