欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python-nmap實(shí)現(xiàn)python利用nmap進(jìn)行掃描分析

 更新時(shí)間:2024年12月31日 08:31:23   作者:smileleooo  
Nmap是一個(gè)非常用的網(wǎng)絡(luò)/端口掃描工具,如果想將nmap集成進(jìn)你的工具里,可以使用python-nmap這個(gè)python庫(kù),它提供了一個(gè)簡(jiǎn)單的接口來(lái)使用nmap進(jìn)行掃描,下面我們來(lái)看看python-nmap的具體應(yīng)用吧

前言

Nmap是一個(gè)非常用的網(wǎng)絡(luò)/端口掃描工具,如果想將nmap集成進(jìn)你的工具里??梢允褂胮ython-nmap這個(gè)python庫(kù),它提供了一個(gè)簡(jiǎn)單的接口來(lái)使用nmap進(jìn)行掃描。

python-nmap的基本使用

在安裝這個(gè)模塊之前,請(qǐng)?zhí)崆鞍惭b好nmap工具,python-nmap模塊自身不提供任何掃描功能,只是提供一個(gè)接口來(lái)使用namp。

pip install python-nmap

目前最新版本是0.7.1支持python3,python2的版本詳細(xì)參考:https://pypi.org/project/python-nmap/

PortScanner掃描

python-nmap其中的一個(gè)核心類是PortScanner,它負(fù)責(zé)與nmap掃描器進(jìn)行交互,用于執(zhí)行掃描并管理掃描結(jié)果。

首先需要?jiǎng)?chuàng)建一個(gè)PortScanner實(shí)例:

import nmap
nm = nmap.PortScanner()

執(zhí)行掃描:

使用 scan() 方法執(zhí)行網(wǎng)絡(luò)掃描??梢灾付繕?biāo)主機(jī)、端口范圍、掃描類型等參數(shù)。

def scan(  # NOQA: CFQ001, C901
    self, hosts="127.0.0.1", ports=None, arguments="-sV", sudo=False, timeout=0
):
    """
    :param hosts: 主機(jī)字符串,如 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 參數(shù)字符串 '-sU -sX -sC'
    :param sudo: 如果為 True,則使用 sudo 啟動(dòng) nmap
    :param timeout: 整數(shù),如果大于零,將在指定秒數(shù)后終止掃描,否則將無(wú)限期等待
    :returns: 掃描結(jié)果作為字典
    """

例如掃描主機(jī)和端口,scan() 返回一個(gè)字典作為掃描結(jié)果。

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

獲取掃描結(jié)果:

PortScanner封裝了一系列方法,可以方便的獲取掃描結(jié)果中我們想要的數(shù)據(jù),而不需要去手動(dòng)的解析上面返回的這一長(zhǎng)串字典數(shù)據(jù)。

1、all_hosts() 獲取所有掃描的主機(jī)

all_hosts = nm.all_hosts()

返回一個(gè)排序后的列表,包含所有掃描的ip地址。

['192.168.88.150']

2、command_line() 獲取當(dāng)前用于掃描的nmap命令

command_line = nm.command_line()

返回當(dāng)前的掃描命令,這里的參數(shù)列表中的 -oX - 它會(huì)讓nmap的把xml格式作為標(biāo)準(zhǔn)輸出。

nmap -oX - -p 22 -sV 192.168.88.150

3、scaninfo() 獲取當(dāng)前掃描信息

scaninfo = nm.scaninfo()

返回一個(gè)當(dāng)前掃描信息的字典。

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

4、scanstats() 獲取掃描統(tǒng)計(jì)信息

scan_stats = nm.scanstats()

返回一個(gè)當(dāng)前描統(tǒng)計(jì)信息的字典,包括掃描時(shí)間等。

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

5、has_host() 檢查特定主機(jī)是否被掃描

has_host = nm.has_host("192.168.88.150")

如果有掃描結(jié)果返回True,否則返回False。

6、以 CSV 格式獲取掃描結(jié)果

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

寫一個(gè)小案例,掃描一個(gè)網(wǎng)段內(nèi)的所有存活主機(jī)。

import nmap

nm = nmap.PortScanner()
nm.scan(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}')

除了上述PortScanner類提供的幾個(gè)基本方法,其實(shí)還可以更加靈活的運(yùn)用。

PortScannerAsync異步掃描

對(duì)于需要同時(shí)掃描多個(gè)主機(jī)或端口范圍的情況,使用PortScanner同步掃描,并不是一個(gè)好辦法。好在python-nmap提供了一個(gè)異步掃描的方案,PortScannerAsync使用多進(jìn)程技術(shù)異步掃描,避免同步掃描可能導(dǎo)致的阻塞,提高了掃描效率。

首先需要?jiǎng)?chuàng)建一個(gè)PortScannerAsync實(shí)例:

import nmap
nm_async = nmap.PortScannerAsync()

同樣是使用 scan() 方法執(zhí)行掃描:

def scan(  # NOQA: CFQ002
    self,
    hosts="127.0.0.1",
    ports=None,
    arguments="-sV",
    callback=None,
    sudo=False,
    timeout=0,
):
    """
	:param hosts: 主機(jī)字符串,格式與 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 的參數(shù)字符串,例如 '-sU -sX -sC'。
	:param callback: 回調(diào)函數(shù),該函數(shù)以(主機(jī),掃描數(shù)據(jù))作為參數(shù)。
	:param sudo: 如果為真,則使用 sudo 啟動(dòng) nmap。
	:param timeout: 整數(shù),如果大于零,將會(huì)在指定秒數(shù)之后終止掃描,否則將無(wú)限期等待。
	"""

和PortScanner的scan()很類似,但是多了一個(gè)callback參數(shù),需要傳一個(gè)回調(diào)函數(shù),用于掃描結(jié)束后的結(jié)果處理。

import nmap

# 定義回調(diào)函數(shù)(掃描結(jié)果處理)
def scan_callback(host, data):
	"""
	:param host: 掃描完主機(jī)ip地址
	:param data:掃描結(jié)果
	"""
    print(host, data)

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

if __name__ == '__main__':
	# 創(chuàng)建一個(gè)新的進(jìn)程掃描,避免主進(jìn)程阻塞
    nm_async.scan(hosts, ports, arguments, callback=scan_callback)

    while nm_async.still_scanning():
		# still_scanning判斷是否還在掃描
        print("scanning...")
        nm_async.wait(1)

使用異步掃描,類似于放到后臺(tái)掃描,避免了一直阻塞主進(jìn)程。當(dāng)然使用Process和PortScanner也可以實(shí)現(xiàn)一樣的效果,PortScannerAsync是python-nmap封裝好了,開箱即用。

python-nmap的源碼分析

python-nmap其實(shí)已經(jīng)比較完善了,但是如果想用做一些二次開發(fā),不妨來(lái)看看源碼,分析分析它的的工作流程。

這里主要看一下PortScanner和PortScannerAsync這兩類。其中PortScanner是python-nmap的核心類,scan方法又是PortScanner的核心方法,其實(shí)只要了解了scan方法就知道python-nmap的整個(gè)邏輯了。

PortScanner的全貌:

后面6個(gè)函數(shù)前面介紹過(guò),前面的幾個(gè)函數(shù)主要也是為scan函數(shù)服務(wù)的,重點(diǎn)看scan函數(shù)。

scan函數(shù)的邏輯并不復(fù)雜,簡(jiǎn)單說(shuō),接收用戶輸入,構(gòu)建完整的nmap命令行參數(shù)列表,交給nmap掃描, 獲取nmap掃描結(jié)果,解析掃描結(jié)果并返回。

scan函數(shù)簡(jiǎn)化后的代碼邏輯:

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

    # 對(duì)輸入?yún)?shù)(主機(jī)、端口、掃描參數(shù)等)進(jìn)行類型檢查和合法性驗(yàn)證
    if sys.version_info[0] == 2:
        ......
    else:
        ......

    # shlex模塊對(duì)主機(jī)和掃描參數(shù)進(jìn)行分割處理
    h_args = shlex.split(hosts)
    f_args = shlex.split(arguments)

    # 構(gòu)建完整的nmap命令行參數(shù)列表
    args = ([self._nmap_path, "-oX", "-"] + h_args + ["-p", ports] * (ports is not None) + f_args)

    # 啟動(dòng)nmap進(jìn)程
    p = subprocess.Popen(args, bufsize=100000, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
						stderr=subprocess.PIPE,)


    # 超時(shí)處理
    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)
  • 它首先對(duì)輸入?yún)?shù)(主機(jī)、端口、掃描參數(shù)等)進(jìn)行類型檢查和合法性驗(yàn)證,確保符合nmap命令的要求。
  • 然后,使用shlex模塊對(duì)主機(jī)和掃描參數(shù)進(jìn)行分割處理,構(gòu)建完整的nmap命令行參數(shù)列表。
  • 在執(zhí)行掃描過(guò)程中,通過(guò)subprocess.Popen啟動(dòng)nmap進(jìn)程,并根據(jù)設(shè)置的超時(shí)時(shí)間等待掃描完成或進(jìn)行超時(shí)處理。
  • 構(gòu)建nmap命令行參數(shù)列把XML格式作為標(biāo)準(zhǔn)輸出。所以定義一個(gè)analyse_nmap_xml_scan函數(shù)來(lái)解析nmap的xml輸出,該函數(shù)會(huì)將nmap生成的xml掃描結(jié)果解析為一個(gè)結(jié)構(gòu)化的Python字典。

掃描結(jié)果的解析與存儲(chǔ)也是重要一環(huán),它在analyse_nmap_xml_scan函數(shù)實(shí)現(xiàn)。

analyse_nmap_xml_scan函數(shù)簡(jiǎn)化后的代碼邏輯:

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字符串轉(zhuǎn)換為元素樹
    try:
        dom = ET.fromstring(self._nmap_last_output)
    except Exception:
        pass

    # 掃描結(jié)果存儲(chǔ)結(jié)構(gòu), get等方法拿到樹中的數(shù)據(jù)
    scan_result["nmap"] = {
        "command_line": dom.get("args"),
        "scaninfo": {
            "timestr": dom.find("runstats/finished").get("timestr"),
            ......
        },
    }

    return scan_result

在analyse_nmap_xml_scan函數(shù)中,它會(huì)從nmap_xml_output拿到nmap的xml結(jié)果輸出,再使用xml.etree.ElementTree模塊對(duì)nmap掃描生成的xml輸出進(jìn)行解析。使用fromstring方法將xml字符串轉(zhuǎn)換為可操作的元素樹,然后遍歷樹的各個(gè)元素,提取關(guān)鍵信息。

通過(guò)遍歷xml樹結(jié)構(gòu),提取諸如掃描命令行信息、掃描統(tǒng)計(jì)數(shù)據(jù)、主機(jī)詳細(xì)信息。對(duì)于每個(gè)主機(jī),分別解析其地址信息、主機(jī)名信息、端口信息以及腳本輸出信息,并將這些信息按照層次結(jié)構(gòu)存儲(chǔ)在scan_result字典中,也就是scan函數(shù)最后返回的內(nèi)容。

其實(shí)nmap提供5種不同的輸出格式,默認(rèn)的方式是interactive output發(fā)送給標(biāo)準(zhǔn)輸出。但-oX -會(huì)讓nmap輸出xml到標(biāo)準(zhǔn)輸出stdout,而xml輸出對(duì)于程序處理非常方便的。

PortScannerAsync類也很清晰,它使用PortScanner類進(jìn)行端口掃描,multiprocessing庫(kù)的Process類用于創(chuàng)建進(jìn)程,以此實(shí)現(xiàn)異步掃描。

PortScannerAsync類簡(jiǎn)化后的代碼邏輯:

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

    # 此函數(shù)在一個(gè)單獨(dú)的進(jìn)程中執(zhí)行掃描操作,并調(diào)用回調(diào)函數(shù)處理結(jié)果
    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()   #創(chuàng)建一個(gè)PortScanner實(shí)例,用于執(zhí)行掃描操作
        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(   # 創(chuàng)建一個(gè)新的進(jìn)程對(duì)象,將 __scan_progressive__ 函數(shù)作為目標(biāo)函數(shù)
            target=__scan_progressive__,
            args=(self, hosts, ports, arguments, callback, timeout),
        )
        self._process.daemon = True
        self._process.start()

        return

__scan_progressive__函數(shù),它是執(zhí)行掃描任務(wù)和調(diào)用回調(diào)函數(shù)的核心部分,調(diào)用 self._nm.scan 方法進(jìn)行掃描,調(diào)用 callback 函數(shù)以處理掃描結(jié)果。

scan函數(shù)會(huì)創(chuàng)建一個(gè)新的進(jìn)程并指定 _scan_progressive_ 函數(shù)作為目標(biāo)函數(shù),將自身實(shí)例、掃描參數(shù)和回調(diào)函數(shù)等傳遞給該函數(shù)。

在目標(biāo)函數(shù)中,針對(duì)每個(gè)發(fā)現(xiàn)的主機(jī),調(diào)用PortScanner實(shí)例的scan方法進(jìn)行掃描,并在掃描完成后調(diào)用用戶提供的回調(diào)函數(shù),將主機(jī)信息和掃描結(jié)果傳遞給回調(diào)函數(shù)進(jìn)行處理。

PortScannerAsync還提供了一些管理進(jìn)程的函數(shù),用于擴(kuò)展。

以上就是python利用nmap實(shí)現(xiàn)掃描分析的詳細(xì)內(nèi)容,更多關(guān)于python nmap的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • pycharm2020.2 配置使用的方法詳解

    pycharm2020.2 配置使用的方法詳解

    這篇文章主要介紹了pycharm2020.2 配置使用的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Python PyQt5運(yùn)行程序把輸出信息展示到GUI圖形界面上

    Python PyQt5運(yùn)行程序把輸出信息展示到GUI圖形界面上

    這篇文章主要介紹了Python PyQt5運(yùn)行程序把輸出信息展示到GUI圖形界面上,本文通過(guò)截圖實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • selenium攜帶cookies模擬登陸CSDN的實(shí)現(xiàn)

    selenium攜帶cookies模擬登陸CSDN的實(shí)現(xiàn)

    這篇文章主要介紹了selenium攜帶cookies模擬登陸CSDN的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Python實(shí)現(xiàn)基于Excel數(shù)據(jù)繪制棋盤圖

    Python實(shí)現(xiàn)基于Excel數(shù)據(jù)繪制棋盤圖

    這篇文章主要為大家介紹了如何根據(jù)可視化的需要,利用Python將Excel中的數(shù)據(jù)用棋盤圖的樣式來(lái)展示,文中的示例代碼簡(jiǎn)潔易懂,需要的可以參考一下
    2023-07-07
  • NLTK的安裝教程及安裝錯(cuò)誤解決方案

    NLTK的安裝教程及安裝錯(cuò)誤解決方案

    NLTK是一款用于自然語(yǔ)言處理的Python庫(kù),安裝過(guò)程簡(jiǎn)單易懂,只需要使用pip安裝即可。若安裝過(guò)程中出現(xiàn)錯(cuò)誤,可以通過(guò)更新pip、安裝必要的依賴項(xiàng)、更換鏡像源等方式解決。
    2023-04-04
  • Pycharm設(shè)置自動(dòng)代碼提示的超詳細(xì)圖文教程

    Pycharm設(shè)置自動(dòng)代碼提示的超詳細(xì)圖文教程

    有時(shí)候我們?cè)谑褂胮ycharm編寫python代碼的時(shí)候,發(fā)現(xiàn)沒有代碼提示,怎么解決呢?下面這篇文章主要給大家介紹了關(guān)于Pycharm設(shè)置自動(dòng)代碼提示的超詳細(xì)圖文教程,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 解決webdriver.Chrome()報(bào)錯(cuò):Message:''chromedriver'' executable needs to be in Path

    解決webdriver.Chrome()報(bào)錯(cuò):Message:''chromedriver'' executable n

    這篇文章主要介紹了解決webdriver.Chrome()報(bào)錯(cuò):Message:'chromedriver' executable needs to be in Path ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Python內(nèi)置模塊hashlib、hmac與uuid用法分析

    Python內(nèi)置模塊hashlib、hmac與uuid用法分析

    這篇文章主要介紹了Python內(nèi)置模塊hashlib、hmac與uuid用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了hashlib、hmac與uuid模塊的概念、功能及簡(jiǎn)單使用方法,需要的朋友可以參考下
    2018-02-02
  • Python實(shí)現(xiàn)對(duì)PPT文件進(jìn)行截圖操作的方法

    Python實(shí)現(xiàn)對(duì)PPT文件進(jìn)行截圖操作的方法

    這篇文章主要介紹了Python實(shí)現(xiàn)對(duì)PPT文件進(jìn)行截圖操作的方法,涉及Python操作幻燈片的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Python實(shí)現(xiàn)免費(fèi)音樂下載器

    Python實(shí)現(xiàn)免費(fèi)音樂下載器

    本文主要為大家介紹了通過(guò)Python實(shí)現(xiàn)的免費(fèi)音樂下載器,文中的示例代碼講解詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的小伙伴可以學(xué)習(xí)一下
    2021-12-12

最新評(píng)論