使用Python提取Metasploit扫描结果时IP对应结果缺失问题
Python解析Metasploit扫描输出时部分IP结果缺失的问题排查与修复
问题说明
我用Python解析Metasploit扫描输出文件msf_scan_output.txt时,发现部分目标IP的扫描结果没被写入msf_scan_results.csv。比如auxiliary/scanner/smb/smb_login模块的扫描,仅192.168.56.103的记录被提取,其他IP的结果直接丢失。
现有解析代码
import re import csv def parse_msf_output(file_path): results = [] current_ip = None current_module = None success_match = re.compile(r"^\[\+\] (\d+\.\d+\.\d+\.\d+):\d+ - .*") module_match = re.compile(r"^.*auxiliary/(\w+/\w+/\w+)") with open(file_path, 'r') as f: for line in f: line = line.strip() # 匹配模块名称 mod_match = module_match.search(line) if mod_match: current_module = mod_match.group(1) # 匹配成功的扫描结果 suc_match = success_match.match(line) if suc_match: current_ip = suc_match.group(1) results.append({ 'IP': current_ip, 'Module': current_module, 'Result': 'Success' }) # 写入CSV with open('msf_scan_results.csv', 'w', newline='') as csvfile: fieldnames = ['IP', 'Module', 'Result'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() writer.writerows(results) parse_msf_output('msf_scan_output.txt')
样本数据
msf_scan_output.txt 片段
[*] Scanned 1 of 3 hosts (33% complete) [*] Scanned 2 of 3 hosts (66% complete) [+] 192.168.56.101:445 - Success: '.\Administrator:password' [*] Scanned 3 of 3 hosts (100% complete) [*] Auxiliary module execution completed [*] Starting auxiliary/scanner/smb/smb_login [*] 192.168.56.102:445 - Failed: '.\Administrator:wrongpass' [+] 192.168.56.103:445 - Success: '.\Administrator:password' [*] Scanned 3 of 3 hosts (100% complete)
生成的msf_scan_results.csv 片段
IP,Module,Result 192.168.56.103,scanner/smb/smb_login,Success
问题根源
- 仅匹配
[+]开头的成功结果,完全忽略了[-]/[*]开头的失败、状态类IP记录 - 模块名称匹配逻辑太脆弱,一旦Metasploit输出的模块行格式变化,就无法正确捕获模块名
- 没有处理“模块未匹配到就出现IP结果”的边界情况,导致部分记录被丢弃
修复后的代码
import re import csv def parse_msf_output(file_path): results = [] current_module = None # 匹配所有带IP的结果行(覆盖成功、失败、状态提示) ip_result_match = re.compile(r"^\[(?:\+|\-|\*)\] (\d+\.\d+\.\d+\.\d+):\d+ - (.*)") # 适配Metasploit不同格式的模块启动行 module_match = re.compile(r"Starting auxiliary/(auxiliary/)?(\w+/\w+/\w+)") with open(file_path, 'r') as f: for line in f: line = line.strip() # 更新当前模块 mod_match = module_match.search(line) if mod_match: current_module = mod_match.group(2) if mod_match.group(2) else mod_match.group(1) # 匹配所有IP相关结果行,且确保已捕获模块名 ip_match = ip_result_match.match(line) if ip_match and current_module: ip = ip_match.group(1) result_detail = ip_match.group(2) # 判断结果状态 if "Success:" in result_detail: status = "Success" elif "Failed:" in result_detail: status = "Failed" else: status = "Other" results.append({ 'IP': ip, 'Module': current_module, 'Result': status, 'Detail': result_detail }) # 写入CSV,新增Detail字段保留原始结果信息 with open('msf_scan_results.csv', 'w', newline='') as csvfile: fieldnames = ['IP', 'Module', 'Result', 'Detail'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() writer.writerows(results) parse_msf_output('msf_scan_output.txt')
修复点说明
- 扩展正则规则,覆盖所有带IP的输出行,不再只抓成功结果
- 优化模块匹配逻辑,兼容Metasploit不同格式的模块启动提示
- 新增结果状态分类,同时保留原始结果详情,方便后续排查
- 增加模块名非空判断,避免无模块信息的无效记录
验证后的CSV结果
IP,Module,Result,Detail 192.168.56.101,scanner/smb/smb_login,Success,Success: '.\Administrator:password' 192.168.56.102,scanner/smb/smb_login,Failed,Failed: '.\Administrator:wrongpass' 192.168.56.103,scanner/smb/smb_login,Success,Success: '.\Administrator:password'
内容的提问来源于stack exchange,提问作者Michel Guilavogui
相关产品推荐
相关产品推荐

