# 导入nmap模块,用于进行端口扫描 import nmap # 导入自定义的PortScan配置,这里用于提供nmap的搜索路径配置 from client.subdomain.oneforall.config import PortScan # 定义一个端口扫描函数,接收ip地址和可选的端口信息列表 def Nmap_Portscan(ip, port_info_list=None): # 打印开始扫描的提示信息 print(f'[+]端口扫描-开始nmap端口扫描[{ip}]') try: # 尝试初始化nmap扫描器,并设置nmap的搜索路径 nm = nmap.PortScanner(nmap_search_path=PortScan.nmap_search_path) except Exception as e: # 如果初始化失败,打印错误信息并返回None print(f'[-]端口扫描-nmap初始化失败[{ip}];{e}') return None # 如果传入了端口信息列表,则指定扫描的端口范围 if port_info_list: # 将端口列表转化为逗号分隔的字符串,适合nmap扫描 ports = ','.join([str(tmp) for tmp in port_info_list]) # 执行nmap扫描,指定扫描的ip和端口 nm.scan(hosts=ip, ports=ports, arguments='-Pn -T 4 -sV --version-intensity=5') else: # 如果没有指定端口信息,扫描所有端口 nm.scan(hosts=ip, arguments='-Pn -T 4 -sV --version-intensity=5') try: # 获取扫描到的端口列表,默认扫描TCP端口 port_list = nm[ip]['tcp'].keys() except Exception as e: # 如果扫描异常,捕获异常并打印错误信息 print(f'[-]端口扫描-nmap扫描异常[{ip}];{e}') return None else: # 初始化一个字典,用于存储扫描结果 port_dict = {} # 遍历扫描到的端口列表 for port in port_list: # 确保端口信息存在 if nm[ip].has_tcp(port): # 获取该端口的详细信息 port_info = nm[ip]['tcp'][port] # 获取端口的状态(如果未找到则默认为'no') state = port_info.get('state', 'no') # 如果端口是开放的(open),则收集更多信息 if state == 'open': # 获取端口的服务名称、产品名称和版本 name = port_info.get('name', '') product = port_info.get('product', '') version = port_info.get('version', '') # 将端口信息添加到字典中 port_dict[port] = {'ip': ip, 'port': port, 'name': name, 'product': product, 'version': version} # 打印扫描结果 print(f'[+]端口扫描-nmap扫描成功:{ip}:{port} {name} {product} {version}') # 打印扫描完成的提示信息 print(f'[+]端口扫描-nmap扫描完毕') # 返回扫描到的开放端口信息字典 return port_dict # 如果该脚本作为主程序执行 if __name__ == '__main__': # 调用端口扫描函数,扫描指定IP地址 info = Nmap_Portscan('1.1.1.1') # 打印扫描结果 print(info)