You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:07:41