Files
suanli-juzhen/04_暴力破解/scripts/scan_to_brute.py
卡若 048cc32afc 🎯 初始提交:分布式算力矩阵 v1.0
- 6 大模块:扫描/账号管理/节点部署/暴力破解/算力调度/监控运维
- SKILL 总控 + 子模块 SKILL
- 排除大文件(>5MB)与敏感凭证

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-15 22:46:54 +08:00

208 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()