#!/usr/bin/env python3 """ 扫描结果 → 暴力破解 桥接工具 ================================ 从 01_扫描模块 的输出结果中提取 SSH 开放端口的 IP, 生成暴力破解器可用的目标列表。 支持的输入格式: - 01_扫描模块 mumayi_full_scan.py 输出的 JSON - nmap XML 输出 - masscan JSON 输出 - 纯文本 IP 列表 用法: # 从扫描JSON导入 python3 scan_to_brute.py --input ../01_扫描模块/results/scan_results.json --output targets.txt # 从nmap XML导入 python3 scan_to_brute.py --input scan.xml --format nmap --output targets.txt # 从CSV导入(指定IP列和端口列) python3 scan_to_brute.py --input hosts.csv --format csv --ip-col ip --port-col port --output targets.txt # 直接对接暴力破解 python3 scan_to_brute.py --input scan.json --pipe | python3 ssh_bruter.py --targets /dev/stdin """ import json import csv import sys import argparse import xml.etree.ElementTree as ET from pathlib import Path # SSH 相关端口 SSH_PORTS = {22, 2222, 22222, 10022, 20022, 222, 2022} def extract_from_json(filepath): """从JSON扫描结果提取SSH目标""" targets = [] with open(filepath, "r", encoding="utf-8") as f: data = json.load(f) if isinstance(data, list): for item in data: ip = item.get("ip") or item.get("host") or item.get("address") if not ip: continue # 查找SSH端口 open_ports = item.get("open_ports") or item.get("ports") or [] ssh_ports = [] for p in open_ports: if isinstance(p, dict): port_num = p.get("port", 0) service = p.get("service", "").lower() if port_num in SSH_PORTS or "ssh" in service: ssh_ports.append(port_num) elif isinstance(p, int): if p in SSH_PORTS: ssh_ports.append(p) if ssh_ports: for port in ssh_ports: targets.append(f"{ip}:{port}") # 如果没发现SSH端口但有该IP,默认加22 elif item.get("ssh") or item.get("has_ssh"): targets.append(f"{ip}:22") elif isinstance(data, dict): # 键值对格式 {ip: {ports: [...]}} for ip, info in data.items(): if isinstance(info, dict): ports = info.get("ports") or info.get("open_ports") or [] for p in ports: port_num = p if isinstance(p, int) else p.get("port", 0) if port_num in SSH_PORTS: targets.append(f"{ip}:{port_num}") return targets def extract_from_nmap_xml(filepath): """从nmap XML输出提取SSH目标""" targets = [] tree = ET.parse(filepath) root = tree.getroot() for host in root.findall(".//host"): addr_elem = host.find("address[@addrtype='ipv4']") if addr_elem is None: continue ip = addr_elem.get("addr") for port in host.findall(".//port"): portid = int(port.get("portid", 0)) state = port.find("state") service = port.find("service") if state is not None and state.get("state") == "open": svc_name = service.get("name", "") if service is not None else "" if portid in SSH_PORTS or "ssh" in svc_name.lower(): targets.append(f"{ip}:{portid}") return targets def extract_from_masscan(filepath): """从masscan JSON输出提取SSH目标""" targets = [] with open(filepath, "r") as f: # masscan JSON格式可能不完全标准 content = f.read().strip() if content.endswith(","): content = content[:-1] if not content.startswith("["): content = "[" + content + "]" data = json.loads(content) for item in data: ip = item.get("ip") ports = item.get("ports", []) for p in ports: port_num = p.get("port", 0) if port_num in SSH_PORTS: targets.append(f"{ip}:{port_num}") return targets def extract_from_csv(filepath, ip_col="ip", port_col="port"): """从CSV提取SSH目标""" targets = [] with open(filepath, "r", encoding="utf-8") as f: reader = csv.DictReader(f) for row in reader: ip = row.get(ip_col, "").strip() port = row.get(port_col, "22").strip() if ip: port_num = int(port) if port.isdigit() else 22 if port_num in SSH_PORTS: targets.append(f"{ip}:{port_num}") return targets def extract_from_text(filepath): """从纯文本提取(每行一个IP或IP:port)""" targets = [] with open(filepath, "r") as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if ":" in line: targets.append(line) else: targets.append(f"{line}:22") return targets def main(): parser = argparse.ArgumentParser(description="扫描结果转暴力破解目标列表") parser.add_argument("--input", "-i", required=True, help="输入文件路径") parser.add_argument("--format", "-f", choices=["json", "nmap", "masscan", "csv", "text"], default="json", help="输入格式 (默认 json)") parser.add_argument("--output", "-o", help="输出文件路径") parser.add_argument("--ip-col", default="ip", help="CSV中IP列名") parser.add_argument("--port-col", default="port", help="CSV中端口列名") parser.add_argument("--pipe", action="store_true", help="输出到stdout(管道模式)") args = parser.parse_args() # 提取目标 fmt = args.format if fmt == "json": targets = extract_from_json(args.input) elif fmt == "nmap": targets = extract_from_nmap_xml(args.input) elif fmt == "masscan": targets = extract_from_masscan(args.input) elif fmt == "csv": targets = extract_from_csv(args.input, args.ip_col, args.port_col) elif fmt == "text": targets = extract_from_text(args.input) else: targets = extract_from_json(args.input) # 去重 targets = list(dict.fromkeys(targets)) print(f"[*] 提取到 {len(targets)} 个SSH目标", file=sys.stderr) # 输出 if args.pipe or not args.output: for t in targets: print(t) else: with open(args.output, "w") as f: for t in targets: f.write(t + "\n") print(f"[+] 已保存到 {args.output}", file=sys.stderr) if __name__ == "__main__": main()