python-nmap实现python利用nmap进行扫描分析

2024-12-31 15:50

本文主要是介绍python-nmap实现python利用nmap进行扫描分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了...

前言

Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里。可以使用python-nmap这个python库,它提供了一个简单的接口来使用nmap进行扫描。

python-nmap的基本使用

安装这个模块之前,请提前安装好nmap工具,python-nmap模块自身不提供任何扫描功能,只是提供一个接口来使用namp。

pip install python-nmap

目前最新版本是0.7.1支持python3,python2的版本详细参考:https://pypi.org/project/python-nmap/

PortScanner扫描

python-nmap其中的一个核心类是PortScanner,它负责与nmap扫描器进行交互,用于执行扫描并管理扫描结果。

首先需要创建一个PortScanner实例:

import nmap
nm = nmap.PortScanner()

执行扫描:

使用 scan() 方法执行网络扫描。可以指定目标主机、端口范围、扫描类型等参数。

def scan(  # NOQA: CFQ001, C901
    self, hosts="127.0.0.1", ports=None, arguments="-sV", sudo=False, timeout=0
):
    """
    :param hosts: 主机字符串,如 nmap 使用的 'scanme.nmap.org' 或 '198.116.0-255.1-127' 或 '216.163.128.20/20'
    :param ports: 端口字符串,如 nmap 使用的 '22,53,110,143-4564'
    :param arguments: nmap 参数字符串 '-sU -sX -sC'
    :param sudo: 如果为 True,则使用 sudo 启动 nmap
    :param timeout: 整数,如果大于零,将在指定秒数后终止扫描,否则将无限期等待
    :returns: 扫描结果作为字典
    """

例如扫描主机和端口,scan() 返回一个字典作为扫描结果。

scan_result = nm.scan("192.168.88.150", "22")

python-nmap实现python利用nmap进行扫描分析

获取扫描结果:

PortScanner封装了一系列方法,可以方便的获取扫描结果中我们想要的数据,而不需要去手动的解析上面返回的这一长串字典数据。

1、all_hosts() 获取所有扫描的主机

all_hosts = nm.all_hosts()

返回一个排序后的列表,包含所有扫描的ip地址。

['192.168.88.150']

2、command_line() 获取当前用于扫描的nmap命令

command_line = nm.command_line()

返回当前的扫描命令,这里的参数列表中的 -oX - 它会让nmap的把XML格式作为标准输出。

nmap -oX - -p 22 -sV 192.168.88.150

3、scaninfo() 获取当前扫描信息

scaninfo = nm.scaninfo()

返回一个当前扫描信息的字典。

{'tcp': {'method': 'syn', 'services': '22'}}

4、scanstats() 获取扫描统计信息

scan_stats = nm.scanstats()

返回一个当前描统计信息的字典,包括扫描时间等。

{'timestr': 'Mon Dec 30 17:25:17 2024', 'elapsed': '6.59'China编程, 'uphosts': '1', 'downhosts': '0', 'totalhosts': '1'}

5、has_host() 检查特定主机是否被扫描

has_host = nm.has_host("192.168.88.150")

如果有扫描结果返回True,否则返回False。

6、以 CSV 格式获取扫描结果

csv_result = nm.csv()

返回csv格式的文本输出。

host;hostname;hostname_type;protocol;port;name;state;product;extrainfo;reason;version;conf;cpe
192.168.88.150;;;tcp;22;ssh;open;OpenSSH;"Ubuntu linux; protocol 2.0";syn-ack;8.9p1 Ubuntu 3ubuntu0.10;10;cpe:/o:linux:linux_kernel

写一个小案例,扫描一个网段内的所有存活主机。

import nmap

nm = nmap.PortScanner()
nm.scaChina编程n(hosts='192.168.88.0/24', arguments='-sn')
hosts_list = [(x, nm[x]['status']['state']) for x in nm.all_hosts()]

for host, status in hosts_list:
    if status == 'up':
        print(f'{host} status: {status}')

python-nmap实现python利用nmap进行扫描分析

除了上述PortScanner类提供的几个基本方法,其实还可以更加灵活的运用。

PortScannerAsync异步扫描

对于需要同时扫描多个主机或端口范围的情况,使用PortScanner同步扫描,并不是一个好办法。好在python-nmap提供了一个异步扫描的方案,PortScannerAsync使用多进程技术异步扫描,避免同步扫描可能导致的阻塞,提高了扫描效率。

首先需要创建一个PortScannerAsync实例:

import nmap
nm_async = nmap.PortScannerAsync()

同样是使用 scan() 方法执行扫描:

def scan(  # NOQA: CFQ002
    self,
    hosts="127.0.0.1",
    ports=None,
    arguments="-sV",
    callback=None,
    sudo=False,
    timeout=0,
):
    """
	:param hosts: 主机字符串,格式与 nmap 使用的格式相同,例如'scanme.nmap.org' 或 '198.116.0-255.1-127' 或 '216.163.128.20/20'。
	:param ports: 端口字符串,格式与 nmap 使用的格式相同,例如 '22,53,110,143-4564'。
	:param arguments: nmap 的参数字符串,例如 '-sU -sX -sC'。
	:param callback: 回调函数,该函数以(主机,扫描数据)作为参数。
	:param sudo: 如果为真,则使用 sudo 启动 nmap。
	:param timeout: 整数,如果大于零,将会在指定秒数之后终止扫描,否则将无限期等待。
	"""

和PortScanner的scan()很类似,但是多了一个callback参数,需要传一个回调函数,用于扫描结束后的结果处理。

import nmap

# 定义回调函数(扫描结果处理)
def scan_callback(host, data):
	"""
	:param host: 扫描完主机ip地址
	:param data:扫描结果
	"""
    print(host, data)

nm_async = nmap.PortScannerAsync()
hosts = '192.168.88.0/24'
ports = '1-1000'
arguments = '-sS'

if __name__ == '__main__':
	# 创建一个新的进程扫描,避免主进程阻塞
    nm_async.scan(hosts, ports, arguments, callback=scan_callback)

    while nm_async.still_scanning():
		# still_scanning判断是否还在扫描
        print("scanning...")
        nm_async.wait(1)

python-nmap实现python利用nmap进行扫描分析

使用异步扫描,类似于放到后台扫描,避免了一直阻塞主进程。当然使用Process和PortScanner也可以实现一样的效果,PortScannerAsync是python-nmap封装好了,开箱即用。

python-nmap的源码分析

python-nmap其实已经比较完善了,但是如果想用做一些二次开发,不妨来看看源码,分析分析它的的工作流程。

这里主要看一下PortScanner和PortScannerAsync这两类。其中PortScanner是python-nmap的核心类,scan方法又是PortScanner的核心方法,其实只要了解了scan方法就知道python-nmap的整个逻辑了。

PortScanner的全貌:

python-nmap实现python利用nmap进行扫描分析

后面6个函数前面介绍过,前面的几个函数主要也是为scan函数服务的,重点看scan函数。

scan函数的逻辑并不复杂,简单说,接收用户输入,构建完整的nmap命令行参数列表,交给nmap扫描, 获取nmap扫描结果,解析扫描结果并返回。

scan函数简化后的代码逻辑:

def scan(self, hosts="127.0.0.1", ports=None, arguments="-sV", sudo=False, timeout=0):

    # 对输入参数(主机、端口、扫描参数等)进行类型检查和合法性验证
    if sys.version_info[0] == 2:
        ......
    else:
        ......

    # shlex模块对主机和扫描参数进行分割处理
    h_args = shlex.split(hosts)
    f_args = shlex.split(arguments)

    # 构建完整的nmap命令行参数列表
    args = ([self._nmap_path, "-oX", "-"] + h_args + ["-p", ports] * (ports is not None) + f_args)

    # 启动nmap进程
    p = subprocess.Popen(args, bufsize=100000, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
						stderr=subprocess.PIPE,)


    # 超时处理
    if timeout == 0:
        (self._nmap_last_output, nmap_err) = p.communicate()
    else:
        ......

    return self.analyse_nmap_xml_scan(nmap_xml_output=self._nmap_last_output,  nmap_err=nmap_err)
  • 它首先对输入参数(主机、端口、扫描参数等)进行类型检查和合法性验证,确保符合nmap命令的要求。
  • 然后,使用shlex模块对主机和扫描参数进行分割处理,构建完整的nmap命令行参数列表。
  • 在执行扫描过程中,通过subprocess.Popen启动nmap进程,并根据设置的超时时间等待扫描完成或进行超时处理。
  • 构建nmap命令行参数列把XML格式作为标准输出。所以定义一个analyse_nmap_xml_scan函数来解析nmap的xml输出,该函数会将nmap生成的xml扫描结果解析为一个结构化的Python字典。

扫描结果的解析与存储也是重要一环,它在analyse_nmap_xml_scan函数实现。

analyse_nmap_xml_scan函数简化后的代码逻辑:

def analyse_nmap_xml_scan( self, nmap_xml_output=None, nmap_err=nmap_err):

    if nmap_xml_output is not None:
        self._nmap_last_output = nmap_xml_output

    scan_result = {}

    # 将XML字符串转换为元素树
    try:
        dom = ET.fromstring(self._nmap_last_output)
    except Exception:
        pass
python
    # 扫描结果存储结构, get等方法拿到树中的数据
    scan_result["nmap"] = {
        "command_line": dom.get("args"),
        "scaninfo": {
            "timestr": dom.find("runstats/finished").get("timestr"),
            ......
        },
    }

    return scan_result

在analyse_nmap_xml_scan函数中,它会从nmap_xml_output拿到nmap的xml结果输出,再使用xml.etree.ElementTree模块对javascriptnmap扫描生成的xml输出进行解析。使用fromstring方法将xml字符串转换为可操作的元素树,然后遍历树的各个元素,提取关键信息。

通过遍历xml树结构,提取诸如扫描命令行信息、扫描统计数据、主机详细信息。对于每个主机,分别解析其地址信息、主机名信息、端口信息以及脚本输出信息,并将这些信息按照层次结构存储在scan_result字典中,也就是scan函数最后返回的内容。

其实nmap提供5种不同的输出格式,默认的方式是interactive output发送给标准输出。但-oX -会让nmap输出xml到标准输出stdout,而xml输出对于程序处理非常方便的。

PortScannerAsync类也很清晰,它使用PortScanner类进行端口扫描,multiprocessing库的Process类用于创建进程,以此实现异步扫描。

PortScannerAsync类简化后的代码逻辑:

def __scan_progressive__(self, hosts, ports, arguments, callback, timeout):

    # 此函数在一个单独的进程中执行扫描操作,并调用回调函数处理结果
    try:
        scan_data = self._nm.scan(host, ports, arguments, timeout)
    except Exception:
        scan_data = None

    if callback is not None:
        callback(host, scan_data)
    return

class PortScannerAsync(object):

    def __init__(self):
        self._process = None
        self._nm = PortScanner()   #创建一个PortScanner实例,用于执行扫描操作
        return

    def scan(self, hosts="127.0.0.1", ports=None, arguments="-sV", callback=None, timeout=0):

        if sys.version_info[0] == 2:
            ......
        else:
            ......

        self._process = Process(   # 创建一个新的进程对象,将 __scan_progressive__ 函数作为目标函数
            target=__scan_progressive__,
            args=(self, hosts, ports, arguments, callback, timeout),
     python   )
        self._process.daemon = True
        self._process.start()

        return

__scan_progressive__函数,它是执行扫描任务和调用回调函数的核心部分,调用 self._nm.scan 方法进行扫描,调用 callback 函数以处理扫描结果。

scan函数会创建一个新的进程并指定 _scan_progressive_ 函数作为目标函数,将自身实例、扫描参数和回调函数等传递给该函数。

在目标函数中,针对每个发现的主机,调用PortScanner实例的scan方法进行扫描,并在扫描完成后调用用户提供的回调函数,将主机信息和扫描结果传递给回调函数进行处理。

PortScannerAsync还提供了一些管理进程的函数,用于扩展。

python-nmap实现python利用nmap进行扫描分析

以上就是python利用nmap实现扫描分析的详细内容,更多关于python nmap的资料请关注编程China编程(www.chinasem.cn)其它相关文章!

这篇关于python-nmap实现python利用nmap进行扫描分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1152871

相关文章

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

python中列表list切分的实现

《python中列表list切分的实现》列表是Python中最常用的数据结构之一,经常需要对列表进行切分操作,本文主要介绍了python中列表list切分的实现,文中通过示例代码介绍的非常详细,对大家... 目录一、列表切片的基本用法1.1 基本切片操作1.2 切片的负索引1.3 切片的省略二、列表切分的高

基于Python实现一个PDF特殊字体提取工具

《基于Python实现一个PDF特殊字体提取工具》在PDF文档处理场景中,我们常常需要针对特定格式的文本内容进行提取分析,本文介绍的PDF特殊字体提取器是一款基于Python开发的桌面应用程序感兴趣的... 目录一、应用背景与功能概述二、技术架构与核心组件2.1 技术选型2.2 系统架构三、核心功能实现解析

通过Python脚本批量复制并规范命名视频文件

《通过Python脚本批量复制并规范命名视频文件》本文介绍了如何通过Python脚本批量复制并规范命名视频文件,实现自动补齐数字编号、保留原始文件、智能识别有效文件等功能,听过代码示例介绍的非常详细,... 目录一、问题场景:杂乱的视频文件名二、完整解决方案三、关键技术解析1. 智能路径处理2. 精准文件名

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

Python使用PIL库将PNG图片转换为ICO图标的示例代码

《Python使用PIL库将PNG图片转换为ICO图标的示例代码》在软件开发和网站设计中,ICO图标是一种常用的图像格式,特别适用于应用程序图标、网页收藏夹图标等场景,本文将介绍如何使用Python的... 目录引言准备工作代码解析实践操作结果展示结语引言在软件开发和网站设计中,ICO图标是一种常用的图像

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

使用Python实现表格字段智能去重

《使用Python实现表格字段智能去重》在数据分析和处理过程中,数据清洗是一个至关重要的步骤,其中字段去重是一个常见且关键的任务,下面我们看看如何使用Python进行表格字段智能去重吧... 目录一、引言二、数据重复问题的常见场景与影响三、python在数据清洗中的优势四、基于Python的表格字段智能去重

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用