为何Python调用Nmap扫描仅端口版本信息未输出?
问题描述
我尝试用Python实现Nmap端口扫描自动化,执行脚本后,除端口版本信息外,其余内容均正常输出。
代码如下:
import nmap nm = nmap.PortScanner() targetip = 127.0.0.1 firstport = 1 lastport = 1000 for i in range(firstport, lastport + 1): portinfos = nm.scan(targetip, str(i), arguments='-sV') state = portinfos['scan'][targetip]['tcp'][i]['state'] service = portinfos['scan'][targetip]['tcp'][i]['name'] version = portinfos['scan'][targetip]['tcp'][i]['version'] if state == 'open': print(f'\nPort: {i} \nService: {service} \nVersion: {version} \nStatus: {state}\n')
输出结果:
Port: 80 Service: http Version: Status: open
手动执行Nmap命令行时能正常拿到版本信息,但脚本里版本信息是空的,翻了论坛和库文档都没找到解决办法,想知道问题出在哪以及怎么修复。
环境信息:VSCode 1.87.2;Python 3.9.0;python-nmap 0.7.1
问题原因及修复方法
单端口扫描限制导致探测失效
当前代码循环逐个端口调用nm.scan(),这种单端口扫描模式下,Nmap的-sV版本探测缺少批量扫描时的上下文信息共享,探测效率和成功率大幅降低,因此拿不到版本信息。修复:改成批量扫描端口
直接一次性扫描整个端口范围,让Nmap优化探测逻辑,提升版本识别率:import nmap nm = nmap.PortScanner() targetip = '127.0.0.1' port_range = '1-1000' # 一次性扫描全端口范围并启用版本探测 scan_result = nm.scan(targetip, port_range, arguments='-sV') # 遍历所有开放端口 for host in scan_result['scan']: for proto in scan_result['scan'][host].all_protocols(): open_ports = scan_result['scan'][host][proto].keys() for port in open_ports: port_data = scan_result['scan'][host][proto][port] if port_data['state'] == 'open': service = port_data['name'] # 处理版本字段可能为空的情况 version = port_data.get('version', '未识别') print(f'\nPort: {port} \nService: {service} \nVersion: {version} \nStatus: {port_data["state"]}\n')字段匹配问题
部分场景下,python-nmap返回的字典里,服务的具体产品信息存在product字段,而version仅存版本号,单独取version会显示不全;甚至有些情况version字段本身不存在。修复:组合多字段获取完整版本
修改版本信息的获取逻辑,同时读取product和version,拼接成完整的版本描述:# 替换原版本获取的代码行 product = port_data.get('product', '') version_num = port_data.get('version', '') full_version = f"{product} {version_num}".strip() if (product or version_num) else '未识别'额外优化:提升探测强度
可以给-sV加上--version-intensity 9参数,最高强度的探测会发送更多特征包,进一步提升版本识别率,代价是扫描速度变慢:scan_result = nm.scan(targetip, port_range, arguments='-sV --version-intensity 9')
内容的提问来源于stack exchange,提问作者Tzfast
相关产品推荐
相关产品推荐

