使用Python规范化处理Nmap扫描结果文件
解析Nmap Grepable输出并生成端口服务字典
方法一:Python直接解析(推荐,无需额外调用外部命令)
不用生成output.txt再调用grep,直接处理nmap的输出结果更高效,还能避免文件IO和外部命令依赖。
完整代码示例
import subprocess import re target = "192.168.0.0/24" # 替换成你的目标IP/网段 # 用-oG - 让nmap直接输出到stdout,无需生成临时文件 nmap_scan_command = f"nmap -p- -sC -sV -oG - {target}" # 执行扫描并获取输出 result = subprocess.run(nmap_scan_command, shell=True, check=True, capture_output=True, text=True) # 初始化结果字典,结构:{IP: {端口号: (服务名, 版本信息)}} port_service_dict = {} # 匹配Host行的正则:捕获IP与端口列表部分 host_line_pattern = re.compile(r'Host: (\S+) .*? ((?:\d+/open/[^,]+,? )+)') # 匹配单个端口项的正则:捕获端口、协议、服务名、版本 port_item_pattern = re.compile(r'(\d+)/open/(\w+)//(.*?)//(.*?)/') # 逐行解析输出 for line in result.stdout.splitlines(): host_match = host_line_pattern.search(line) if host_match: ip = host_match.group(1) port_items_str = host_match.group(2) port_service_dict[ip] = {} # 拆分并解析每个端口项 for port_item in port_items_str.split(','): port_item = port_item.strip() if not port_item: continue port_match = port_item_pattern.search(port_item) if port_match: port = int(port_match.group(1)) service = port_match.group(3) or "unknown" version = port_match.group(4) or "unknown" port_service_dict[ip][port] = (service, version) # 打印结果示例 for ip, ports in port_service_dict.items(): print(f"IP: {ip}") for port, (service, version) in ports.items(): print(f" 端口 {port}: {service} - {version}")
代码说明
- 用
-oG -替代文件输出,直接获取扫描结果,减少中间环节 - 正则精准匹配nmap Grepable格式的结构,兼容多IP扫描场景
- 嵌套字典结构清晰,方便后续批量处理或导出数据
方法二:命令行一行处理(输出结构化文本)
如果坚持用命令行工具解析output.txt,可以用awk一行提取结构化信息,输出格式为IP:端口:服务:版本,之后可轻松导入Python生成字典:
awk '/Host:/ && /open/ {ip=$2; split($0, parts, /Host: [^ ]+ /); ports=parts[2]; gsub(/Ignored State:.*/, "", ports); split(ports, port_list, /, /); for (i in port_list) {split(port_list[i], p, /\//); if (p[2] == "open") print ip ":" p[1] ":" p[4] ":" p[6]}}' output.txt
命令说明
- 过滤出包含Host和open状态的有效行
- 拆分并提取IP、端口、服务名、版本信息
- 输出标准化字符串,便于后续脚本解析
内容的提问来源于stack exchange,提问作者chrysst
相关产品推荐
相关产品推荐

