手把手教你写Nmap自动化扫描工具:从手动扫到一键批量扫描
在网络安全测试、运维巡检场景中,Nmap(网络映射器)是必备工具------小到探测单台主机存活,大到批量扫描端口、识别操作系统和服务漏洞,都能轻松搞定。但手动输入Nmap命令不仅繁琐,还容易因参数记错导致扫描失败;批量扫描时重复操作更是效率低下。
本人在应用Nmap扫描系统的常用命令格式进行整理,将基于Python编写一款跨平台Nmap自动化扫描工具,把存活主机探测、全端口扫描、OS识别、漏洞检测等常用操作封装成可视化菜单,新手也能一键使用,大幅提升扫描效率。
一、前置准备:环境搭建
在使用工具前,需先完成基础环境配置,确保Python和Nmap能正常运行。
1. 安装Nmap(核心依赖)
Nmap是扫描的核心,需先安装并配置环境变量:
-
Windows :访问Nmap官网下载页,下载最新版安装包,安装时勾选"Add Nmap to the system PATH for all users"(添加到环境变量)。
-
Linux(Ubuntu/Debian) :执行命令
sudo apt-get install nmap。 -
macOS :执行命令
brew install nmap(需先安装Homebrew)。
验证安装:打开终端/CMD,输入 nmap -v,若输出Nmap版本信息则安装成功。
2. Python环境(工具运行载体)
需安装Python 3.6+版本(推荐3.8+),无需额外安装第三方库(工具仅使用Python内置模块:subprocess、os、sys、re、typing)。
二、工具核心功能:解决哪些痛点?
手动使用Nmap时,我们常遇到这些问题:
-
每次扫描都要手写长命令,比如
nmap -sn 192.168.1.0/24,参数多易出错; -
存活主机探测后,需手动提取IP再进行端口扫描,步骤割裂;
-
不同扫描场景(全端口、常用端口、OS探测)需重复输入相似命令;
-
跨平台(Windows/Linux)时,命令行工具(如grep)不兼容,解析结果麻烦。
本工具针对这些痛点,封装了6大核心功能:
| 功能编号 | 功能名称 | 适用场景 | 核心Nmap参数 |
|---|---|---|---|
| 1 | 存活主机探测 | 快速定位网段内在线设备 | -sn(Ping扫描)、-oG(输出gnmap格式) |
| 2 | 全端口扫描 | 深度检测主机开放端口(0-65535) | -sS(SYN扫描)、-p 0-65535 |
| 3 | 常用端口扫描 | 快速检测高频端口(如80、443、22) | 默认扫描Top 100常用端口 |
| 4 | 操作系统探测 | 识别主机操作系统类型(Windows/Linux) | -O(OS检测) |
| 5 | 服务版本检测 | 识别端口对应服务及版本(如Apache 2.4.49) | -sV(版本探测) |
| 6 | SMB Ghost漏洞扫描 | 检测永恒之蓝等SMB漏洞(445端口) | --script smb-ghost |
三、核心代码解析:从原理到实现
工具的核心逻辑是"封装Nmap命令+解析扫描结果+可视化菜单",以下拆解关键模块,让你不仅会用,还懂原理。
1. 环境检查模块:确保Nmap可用
工具运行前首先检查Nmap是否安装并加入环境变量,避免后续执行命令报错:
Python
import subprocess
import sys
def check_nmap_installed() -> bool:
"""检查 Nmap 是否安装并加入环境变量"""
try:
# 执行 nmap -v 检测是否存在
result = subprocess.run(
["nmap", "-v"],
capture_output=True,
text=True,
timeout=5
)
return result.returncode == 0
except (subprocess.TimeoutExpired, FileNotFoundError):
return False
# 主程序入口检查
if __name__ == "__main__":
if not check_nmap_installed():
print("❌ 错误:未检测到 Nmap,请先安装并加入环境变量!")
sys.exit(1)
原理 :通过subprocess.run执行nmap -v命令,若返回码为0则说明Nmap可用;若触发"文件未找到"异常,说明Nmap未安装或未配置环境变量。
2. 命令执行模块:统一管理Nmap调用
所有Nmap命令都通过该模块执行,实现"实时输出日志+错误处理+结果返回",避免重复写子进程调用代码:
Python
def execute_command(cmd: List[str], desc: str) -> bool:
"""执行系统命令并输出日志"""
print(f"\n=== 开始执行:{desc} ===")
print(f"执行命令:{' '.join(cmd)}")
try:
# 实时输出日志(避免卡顿)
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1
)
# 逐行打印Nmap扫描日志
for line in iter(process.stdout.readline, ''):
print(line.strip())
process.wait()
return process.returncode == 0
except Exception as e:
print(f"执行异常:{str(e)}")
return False
亮点:
-
实时流式输出扫描日志,避免大扫描任务无响应;
-
统一捕获异常,返回执行结果(成功/失败);
-
兼容Windows/Linux的子进程调用方式。
3. 存活主机探测:跨平台解析结果
手动扫描存活主机后,Windows没有grep/cut命令,解析结果很麻烦。工具内置正则解析gnmap格式文件,提取存活IP并写入文件:
Python
import re
import os
def discover_live_hosts(network: str = "192.168.1.0/24") -> bool:
"""探测存活主机(跨平台版)"""
# 步骤1:执行Nmap存活扫描,输出到gnmap文件
cmd = ["nmap", "-sn", "-v", "-T4", "-oG", "Discovery.gnmap", network]
if not execute_command(cmd, "存活主机探测"):
return False
# 步骤2:解析gnmap文件,提取存活IP
live_hosts = []
try:
with open("Discovery.gnmap", "r", encoding="utf-8") as f:
for line in f:
# 匹配gnmap格式中"Status: Up"的行,提取IP
if "Status: Up" in line:
ip_match = re.search(r"Host: (\d+\.\d+\.\d+\.\d+)", line)
if ip_match:
live_hosts.append(ip_match.group(1))
except Exception as e:
print(f"解析失败:{str(e)}")
return False
# 步骤3:写入存活主机列表
if live_hosts:
with open("liveHosts.txt", "w", encoding="utf-8") as f:
f.write("\n".join(live_hosts))
print(f"✅ 发现 {len(live_hosts)} 台存活主机,已写入liveHosts.txt")
return True
else:
print("❌ 未发现存活主机")
return False
关键解析:
-
-sn:Nmap Ping扫描(不扫描端口,仅探测存活); -
-oG:输出"可 grep"的gnmap格式,方便解析; -
正则
Host: (\d+.\d+.\d+.\d+):精准匹配IP地址,跨平台无需依赖外部命令。
4. 可视化主菜单:新手友好
将所有功能封装成菜单,无需记命令,输入编号即可执行:
Python
def main_menu():
"""主菜单"""
print("=" * 50)
print(" Nmap 自动化扫描工具")
print("=" * 50)
print("1. 探测存活主机(生成 liveHosts.txt)")
print("2. 全端口扫描(基于 liveHosts.txt)")
print("3. 常用端口扫描(基于 liveHosts.txt)")
print("4. 操作系统探测(基于 liveHosts.txt)")
print("5. 服务版本检测(基于 liveHosts.txt)")
print("6. SMB Ghost 漏洞扫描")
print("0. 退出程序")
print("=" * 50)
# 主循环
while True:
main_menu()
choice = input("请输入操作编号:").strip()
if choice == "0":
print("👋 程序退出!")
break
# 执行对应功能(省略分支逻辑)
四、工具使用教程:一步到位
1. 完整代码获取
将本文所有代码整合,保存为nmap_auto_scan.py(也可直接用文章开头的完整代码)。
2. 运行工具
打开终端/CMD,进入代码所在目录,执行:
Python
python nmap_auto_scan.py
若提示"Nmap检测成功",则进入主菜单。
3. 功能使用示例
示例1:探测存活主机
-
输入编号
1,按提示输入扫描网段(默认192.168.1.0/24); -
工具自动执行Nmap存活扫描,解析结果后生成
liveHosts.txt; -
查看文件,即可看到网段内所有在线主机的IP。
示例2:全端口扫描
-
确保已生成
liveHosts.txt(先执行示例1); -
输入编号
2,工具自动扫描存活主机的0-65535端口; -
扫描结果保存为
FullTCP,可打开查看开放端口、端口状态等。
示例3:SMB Ghost漏洞扫描
-
输入编号
6,输入目标网段(如192.168.1.0/24); -
工具扫描445端口,检测是否存在SMB Ghost漏洞;
-
实时查看扫描日志,识别漏洞主机。
4. 结果文件说明
工具运行后会生成多个结果文件,用途如下:
| 文件名 | 用途 |
|---|---|
| liveHosts.txt | 存活主机IP列表 |
| Discovery.gnmap | 存活探测原始结果 |
| FullTCP | 全端口扫描结果 |
| TopTCP | 常用端口扫描结果 |
| OSDetect | 操作系统探测结果 |
| ServiceDetect | 服务版本检测结果 |
五、扩展与优化:让工具更强大
基础版本满足日常使用,你还可以根据需求扩展功能:
1. 增加多线程扫描
默认Nmap扫描是单线程,可通过-min-parallelism参数增加并行度,或用Python多线程同时扫描多个网段。
2. 支持更多漏洞扫描
比如添加Heartbleed(心脏滴血)、Log4j漏洞扫描:
Python
def scan_log4j(network: str = DEFAULT_NETWORK) -> bool:
"""Log4j漏洞扫描"""
cmd = [
"nmap", "-p", "80,443,8080",
"--script", "log4j-scan",
network
]
return execute_command(cmd, "Log4j漏洞扫描")
3. 结果可视化
将扫描结果解析为Excel/HTML格式,用pandas生成报表,或用matplotlib绘制端口开放率图表。
4. 增加参数自定义
比如允许用户自定义扫描速度(-T0~-T5)、超时时间、是否跳过Ping等:
Python
# 新增参数输入
scan_speed = input("请输入扫描速度(0-5,默认4):").strip() or "4"
cmd = ["nmap", "-sS", "-T" + scan_speed, "-p", "0-65535", ...]
5. 错误重试机制
对扫描失败的主机,增加自动重试逻辑:
Python
def scan_with_retry(cmd: List[str], desc: str, retry: int = 2) -> bool:
"""带重试的命令执行"""
for i in range(retry + 1):
if execute_command(cmd, desc):
return True
print(f"第{i+1}次执行失败,重试中...")
return False
六、重要注意事项
-
合法授权:扫描他人网络/主机需获得书面授权,未经授权的扫描可能违反《网络安全法》,承担法律责任;
-
扫描速度 :避免使用
-T5(最快速度)扫描公网,可能导致目标网络拥塞,建议内网用-T4,公网用-T2; -
权限问题 :Linux下执行SYN扫描(
-sS)需要root权限,需加sudo运行工具(sudo python nmap_auto_scan.py); -
跨平台兼容:Windows下Nmap的部分脚本可能失效,建议优先在Linux/macOS环境使用;
-
结果解读:Nmap的OS探测、版本检测并非100%准确,需结合其他工具验证。
七、总结
本文通过Python封装Nmap命令,实现了"一键式"网络扫描工具,解决了手动扫描的繁琐问题。工具不仅兼容Windows/Linux/macOS,还提供了可视化菜单、跨平台结果解析、详细日志输出等功能,新手也能快速上手。
无论是运维人员做网络巡检,还是安全测试人员做漏洞扫描,这款工具都能大幅提升效率。你可以基于基础版本,根据自身需求扩展功能,打造属于自己的专属Nmap扫描工具。
最后再次强调:网络扫描需遵守法律法规,仅在授权范围内使用工具,共同维护网络安全!