Python-nmap 提供了便捷的網路掃描功能,讓開發者能以 Python 程式控制 Nmap 進行主機探測。同步掃描模式適合單一目標,程式會逐一完成每個掃描任務。而非同步掃描模式則允許多個掃描任務平行,有效提升掃描效率,適用於大規模網路掃描。除了使用 python-nmap 函式庫,開發者也可以透過 os 和 subprocess 模組直接執行 Nmap 指令,彈性運用 Nmap 的各種功能。更進一步,Nmap 指令碼引擎 (NSE) 提供豐富的指令碼,可針對特定服務和漏洞進行深入探測,提升網路安全分析能力。
非同步掃描實作
在下面的範例中,我們將展示如何使用 python-nmap 實作非同步掃描。
#!/usr/bin/env python3
import nmap
import threading
class NmapScannerAsync:
def __init__(self):
self.portScanner = nmap.PortScanner()
def nmapScanAsync(self, ip_address, port):
thread = threading.Thread(target=self.nmapScan, args=(ip_address, port))
thread.start()
def nmapScan(self, ip_address, port):
self.portScanner.scan(ip_address, port)
self.state = self.portScanner[ip_address]['tcp'][int(port)]['state']
print(" [+] Executing command: ", self.portScanner.command_line())
print(" [+] "+ ip_address + " tcp/" + port + " " + self.state)
def main():
ip_address = '45.33.32.156'
ports = ['21', '22', '23', '25', '80']
scanner = NmapScannerAsync()
for port in ports:
scanner.nmapScanAsync(ip_address, port)
if __name__ == "__main__":
main()
內容解密:
NmapScannerAsync類別:這個類別提供了非同步掃描的功能。nmapScanAsync方法:為每個埠建立一個新的執行緒,並在該執行緒中呼叫nmapScan方法進行掃描。nmapScan方法:與同步掃描中的nmapScan方法類別似,但現在是在單獨的執行緒中執行。
非同步掃描的優點
- 提高效率:非同步掃描允許同時掃描多個埠,大大提高了掃描效率。
- 靈活性:可以根據需要定義回呼函式,對掃描結果進行進一步處理。
使用python-nmap進行掃描模式分析
python-nmap是一個強大的Python函式庫,用於與Nmap掃描器進行互動,實作網路掃描和主機檢測。本文將探討如何使用python-nmap進行同步和非同步掃描,並解析掃描結果。
同步掃描模式
同步掃描是指一次執行一個掃描任務,直到完成後才開始下一個任務。以下是一個使用python-nmap進行同步掃描的範例:
import nmap
# 建立PortScanner物件
portScanner = nmap.PortScanner()
# 掃描特定主機的特定埠
open_ports_dict = portScanner.scan('45.33.32.156', arguments="-O -v")
# 解析掃描結果
if open_ports_dict is not None:
open_ports_dict = open_ports_dict.get("scan").get('45.33.32.156').get("tcp")
print("開放埠描述")
port_list = open_ports_dict.keys()
for port in port_list:
print(port, "
---
\t-->", open_ports_dict.get(port)['name'])
print("\n
---
-
---
-
---
---
作業系統詳細資訊
---
-
---
-
---
-
---
-
---
--\n")
print("被掃描主機的詳細資訊:\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['cpe'])
print("作業系統家族是:\t\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['osfamily'])
print("作業系統型別是:\t\t\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['type'])
print("作業系統版本是:\t\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['osgen'])
print("作業系統供應商是:\t\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['vendor'])
print("偵測準確度是:\t\t", portScanner['45.33.32.156']['osmatch'][0]['osclass'][0]['accuracy'])
內容解密:
- 建立PortScanner物件:使用
nmap.PortScanner()建立一個PortScanner物件,用於執行Nmap掃描。 - 掃描特定主機的特定埠:呼叫
portScanner.scan()方法,傳入目標主機IP和掃描引數(此例中為-O -v,用於偵測作業系統和詳細輸出)。 - 解析掃描結果:從
scan()方法的回傳值中提取TCP埠資訊和作業系統資訊,並進行列印輸出。 - 輸出開放埠和作業系統資訊:遍歷開放的TCP埠,列印埠號和對應的服務名稱。同時,輸出偵測到的作業系統詳細資訊,包括作業系統家族、型別、版本、供應商和偵測準確度。
非同步掃描模式
非同步掃描允許多個掃描任務平行執行,提高了掃描效率。以下是一個使用python-nmap進行非同步掃描的範例:
import nmap
# 建立PortScannerAsync物件
portScannerAsync = nmap.PortScannerAsync()
# 定義回呼函式
def callback_result(host, scan_result):
print(host, scan_result)
# 執行非同步掃描
portScannerAsync.scan(hosts='scanme.nmap.org', arguments='-p 21', callback=callback_result)
portScannerAsync.scan(hosts='scanme.nmap.org', arguments='-p 22', callback=callback_result)
portScannerAsync.scan(hosts='scanme.nmap.org', arguments='-p 23', callback=callback_result)
portScannerAsync.scan(hosts='scanme.nmap.org', arguments='-p 80', callback=callback_result)
# 等待掃描完成
while portScannerAsync.still_scanning():
print("掃描中 >>>")
portScannerAsync.wait(5)
內容解密:
- 建立PortScannerAsync物件:使用
nmap.PortScannerAsync()建立一個PortScannerAsync物件,用於執行非同步Nmap掃描。 - 定義回呼函式:定義一個
callback_result()函式,用於在每次掃描完成時被呼叫,列印掃描結果。 - 執行非同步掃描:呼叫
portScannerAsync.scan()方法,傳入目標主機、掃描引數和回呼函式,執行非同步掃描。 - 等待掃描完成:使用
while迴圈和still_scanning()方法等待所有掃描任務完成,並定期列印掃描進度。
重點解析
- 同步與非同步掃描:python-nmap支援同步和非同步兩種掃描模式。同步掃描適用於簡單的掃描任務,而非同步掃描則能提高複雜掃描任務的效率。
- 掃描結果解析:無論是同步還是非同步掃描,python-nmap都提供了豐富的API來解析掃描結果,包括開放埠資訊和作業系統詳細資訊。
- 許可權需求:某些Nmap掃描功能(如作業系統偵測)需要root許可權,因此在執行相關指令碼時可能需要使用
sudo。
使用 Python-nmap 進行非同步掃描與 Nmap 指令執行
在前面的章節中,我們已經瞭解如何使用 python-nmap 進行基本的連線埠掃描。在本章節中,我們將進一步探討如何使用 python-nmap 進行非同步掃描,以及如何利用 os 和 subprocess 模組執行 Nmap 指令。
非同步掃描的實作
非同步掃描允許我們在掃描多個連線埠時,不必等待前一個掃描完成即可開始下一個掃描。這種方式可以大幅提高掃描的效率。以下是一個使用 python-nmap 進行非同步掃描的範例:
#!/usr/bin/env python3
import nmap
import argparse
def callbackResult(host, scan_result):
port_state = scan_result['scan'][host]['tcp']
print("Command line:"+ scan_result['nmap']['command_line'])
for key, value in port_state.items():
print('Port {0} --> {1}'.format(key, value))
class NmapScannerAsync:
def __init__(self):
self.portScannerAsync = nmap.PortScannerAsync()
def scanning(self):
while self.portScannerAsync.still_scanning():
print("Scanning >>>")
self.portScannerAsync.wait(5)
def nmapScanAsync(self, hostname, port):
try:
print("Checking port "+ port +" ..........")
self.portScannerAsync.scan(hostname, arguments="-A -sV -p"+port ,callback=callbackResult)
self.scanning()
except Exception as exception:
print("Error to connect with " + hostname + " for port scanning",str(exception))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Asynchronous Nmap scanner')
parser.add_argument("--host", dest="host", help="target IP / domain", required=True)
parser.add_argument("-ports", dest="ports", help="Please, specify the target port(s) separated by comma[80,8080 by default]", default="80,8080")
parsed_args = parser.parse_args()
port_list = parsed_args.ports.split(',')
host = parsed_args.host
for port in port_list:
NmapScannerAsync().nmapScanAsync(host, port)
內容解密:
callbackResult函式:當 Nmap 完成掃描後會呼叫此函式,顯示執行的指令和每個連線埠的狀態。NmapScannerAsync類別:負責初始化非同步掃描器並執行掃描。__init__方法:初始化nmap.PortScannerAsync()物件。scanning方法:持續檢查掃描是否完成,若未完成則等待。nmapScanAsync方法:對指定的主機和連線埠執行非同步掃描。
- 主程式:解析命令列引數,呼叫
nmapScanAsync方法對每個指定的連線埠進行掃描。
使用 os 和 subprocess 模組執行 Nmap
除了使用 python-nmap 外,我們還可以直接利用 os 和 subprocess 模組執行 Nmap 指令。
使用 os 模組
import os
nmap_command = "nmap -sT 127.0.0.1"
os.system(nmap_command)
內容解密:
os.system方法:執行指定的 Nmap 指令,並將結果直接輸出到控制檯。
使用 subprocess 模組
from subprocess import Popen, PIPE
process = Popen(['nmap','-O','127.0.0.1'], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
print(stdout.decode())
內容解密:
Popen方法:建立一個新的程式執行 Nmap 指令,並捕捉其輸出。communicate方法:等待程式完成並取得其輸出結果。stdout.decode():將輸出的位元組解碼為字串並列印出來。
發現服務與漏洞:Nmap 指令碼的應用
在前面的章節中,我們已經瞭解如何使用 os 和 subprocess 模組來執行 Nmap 命令,並取得關於目標主機的作業系統資訊。現在,我們將進一步探討如何使用 Nmap 指令碼來發現服務和漏洞。
使用 Nmap 指令碼發現服務
Nmap 的強大之處在於其指令碼引擎(NSE),允許使用者執行特定的測試,以收集目標主機的資訊。這些指令碼可以用於檢查服務的狀態、提取服務資訊,甚至檢測特定的漏洞,如 ShellShock、Poodle 或 HeartBleed。
Nmap 提供了多種型別的指令碼,包括:
- Auth:執行所有可用的身份驗證指令碼
- Default:執行預設的基本指令碼
- Discovery:從目標主機檢索資訊
- External:使用外部資源的指令碼
- Intrusive:被視為對目標主機具有侵入性的指令碼
- Malware:檢查是否存在惡意程式碼或後門開啟的連線
- Safe:執行非侵入性的指令碼
- Vuln:檢測最知名的漏洞
- All:執行所有可用的 NSE 指令碼
在 Unix 系統中,這些指令碼通常位於 /usr/share/nmap/scripts 目錄下。
執行 Nmap 指令碼
要執行 Nmap 指令碼,需要在 Nmap 命令中使用 --script 選項。例如,使用 banner 指令碼來取得服務資訊:
$ sudo nmap -sSV --script banner scanme.nmap.org
內容解密:
-sSV引數用於進行服務版本掃描。--script banner指定了要執行的指令碼名稱。scanme.nmap.org是掃描的目標主機。
輸出結果將顯示開放的埠,以及每個埠對應的服務版本和作業系統資訊。
探索服務和漏洞
另一個有用的指令碼是 discovery,它允許我們取得更多關於目標主機上執行服務的資訊:
$ sudo nmap --script discovery scanme.nmap.org
內容解密:
--script discovery指定了要執行的discovery指令碼。- 輸出結果中包含了 DNS 暴力破解(dns-brute)的結果,用於取得子網域名稱及其 IP 地址。
此外,我們還可以使用 Nmap 指令碼來取得 SSH 埠上的公鑰和加密演算法資訊:
$ sudo nmap -sSV -p22 --script ssh-hostkey scanme.nmap.org
內容解密:
-p22指定了要掃描的埠號(此處為 SSH 埠 22)。--script ssh-hostkey指定了要執行的指令碼,用於取得 SSH 主機金鑰。
輸出結果將顯示 SSH 服務的版本、支援的加密演算法以及公鑰資訊。