更新: 359 个文件 - 2026-03-16 23:30:01

这个提交包含在:
hao
2026-03-16 23:30:01 -07:00
父节点 527990f535
当前提交 2974cd9ad9
修改 359 个文件,包含 6332 行新增673 行删除

查看文件

@@ -30,13 +30,22 @@ import socket
import ssl
import warnings
from dataclasses import asdict, dataclass, field
from pathlib import Path
from typing import Dict, List, Optional, Set
import sys
warnings.filterwarnings("ignore", message="urllib3 v2 only supports OpenSSL")
import requests
SCRIPTS_DIR = Path(__file__).resolve().parents[2] / "scripts"
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from tool_contract import add_common_args, emit_report, make_report, write_evidence # noqa: E402
DEFAULT_PORTS = [80, 443, 8080, 8443]
@@ -226,6 +235,7 @@ def main() -> int:
action="store_true",
help="确认目标属于自有资产或已明确授权",
)
add_common_args(parser, include_network=False)
args = parser.parse_args()
if not args.ack_authorized:
@@ -267,11 +277,25 @@ def main() -> int:
"related_hosts": sorted(related_hosts),
}
if args.json:
print(json.dumps(report, indent=2, ensure_ascii=True))
else:
print(render_text(report))
return 0
evidence_refs = []
ref = write_evidence(args, "site-scope-map.json", report)
if ref:
evidence_refs.append(ref)
payload = make_report(
tool="site-scope-mapper",
mode="single-target-scope-map",
target=args.target,
status="verified" if report["http"] or report["tls"] else "needs-review",
severity="low",
payload_or_probe=report,
request_summary={"ports": ports, "target_type": target_type},
evidence_refs=evidence_refs,
destructive_risk="low",
args=args,
)
if args.json and args.format == "text":
args.format = "json"
return emit_report(args, payload, render_text(report).splitlines())
if __name__ == "__main__":

查看文件

@@ -0,0 +1,96 @@
#!/usr/bin/env python3
"""
Misconfiguration Lab Tool
LAB ONLY | AUTHORIZED TARGETS ONLY
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
from typing import Any, Dict, List
from urllib.parse import urljoin
import requests
SCRIPTS_DIR = Path(__file__).resolve().parents[3] / "scripts"
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from tool_contract import add_common_args, emit_report, ensure_authorized, make_report, parse_headers, write_evidence # noqa: E402
DEFAULT_PATHS = [
"/.env",
"/server-status",
"/actuator/health",
"/swagger-ui.html",
"/phpinfo.php",
"/admin/",
"/debug",
]
def probe(target: str, timeout: float, headers: Dict[str, str]) -> List[Dict[str, Any]]:
results = []
for path in DEFAULT_PATHS:
url = urljoin(target if target.endswith("/") else target + "/", path.lstrip("/"))
try:
response = requests.get(url, timeout=timeout, headers=headers, verify=False)
results.append(
{
"path": path,
"url": url,
"status_code": response.status_code,
"server": response.headers.get("Server"),
"content_type": response.headers.get("Content-Type"),
"body_excerpt": response.text[:300],
}
)
except Exception as exc:
results.append({"path": path, "url": url, "error": str(exc)})
return results
def main() -> int:
parser = argparse.ArgumentParser(description="Misconfiguration Lab Tool")
parser.add_argument("--target", required=True, help="目标 URL")
parser.add_argument("--timeout", type=float, default=8.0, help="请求超时时间")
add_common_args(parser)
args = parser.parse_args()
ensure_authorized(args, parser)
headers = parse_headers(args.header)
results = probe(args.target, args.timeout, headers)
evidence_refs = []
ref = write_evidence(args, "misconfig-lab.json", {"results": results})
if ref:
evidence_refs.append(ref)
suspicious = [item for item in results if item.get("status_code") in {200, 401, 403}]
report = make_report(
tool="misconfig-lab",
mode="misconfiguration-surface-check",
target=args.target,
status="verified" if suspicious else "needs-review",
severity="medium" if suspicious else "info",
payload_or_probe={"results": results, "suspicious": suspicious},
request_summary={"timeout": args.timeout, "paths": DEFAULT_PATHS},
evidence_refs=evidence_refs,
destructive_risk="low",
args=args,
)
text_lines = [
"=" * 60,
"Misconfiguration Lab Tool",
"=" * 60,
f"Target: {args.target}",
f"Paths Checked: {len(DEFAULT_PATHS)}",
f"Suspicious Responses: {len(suspicious)}",
]
return emit_report(args, report, text_lines)
if __name__ == "__main__":
raise SystemExit(main())

查看文件

@@ -27,6 +27,14 @@ import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List, Dict, Tuple, Optional
import sys
from pathlib import Path
SCRIPTS_DIR = Path(__file__).resolve().parents[2] / "scripts"
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from tool_contract import add_common_args, emit_report, ensure_authorized, make_report, write_evidence # noqa: E402
class Colors:
@@ -229,37 +237,54 @@ def main():
parser.add_argument("-t", "--threads", type=int, default=100, help="线程数")
parser.add_argument("--timeout", type=float, default=1.0, help="超时时间")
parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
add_common_args(parser, include_network=False)
args = parser.parse_args()
ensure_authorized(args, parser)
scanner = PortScanner(threads=args.threads, timeout=args.timeout)
if args.format != "text":
scanner.print_result = lambda *_args, **_kwargs: None # type: ignore[assignment]
if args.top_ports:
ports = scanner.top_ports[: args.top_ports]
else:
ports = scanner.parse_ports(args.ports)
print(f"\n{Colors.BOLD}{'=' * 60}{Colors.END}")
print(f"{Colors.BOLD}Port Scanner{Colors.END}")
print(f"{Colors.BOLD}{'=' * 60}{Colors.END}\n")
scanner.print_result("INFO", f"目标: {args.host}")
scanner.print_result("INFO", f"端口: {len(ports)}")
scanner.print_result("INFO", f"线程: {args.threads}")
results = scanner.scan_host(args.host, ports, args.verbose)
print(f"\n{Colors.BOLD}{'=' * 60}{Colors.END}")
if results:
scanner.print_result("SUCCESS", f"发现 {len(results)} 个开放端口:")
print(f"\n{'PORT':<10} {'SERVICE':<15} {'BANNER'}")
print("-" * 60)
for r in sorted(results, key=lambda x: x["port"]):
banner = r["banner"][:40] if r["banner"] else r["service"]
print(f"{r['port']:<10} {r['service']:<15} {banner}")
else:
scanner.print_result("INFO", "未发现开放端口")
print(f"{Colors.BOLD}{'=' * 60}{Colors.END}\n")
evidence_refs = []
ref = write_evidence(args, "port-scan-results.json", {"results": results, "ports": ports})
if ref:
evidence_refs.append(ref)
status = "verified" if results else "needs-review"
severity = "medium" if results else "info"
report = make_report(
tool="port-scanner",
mode="minimal-port-scan",
target=args.host,
status=status,
severity=severity,
payload_or_probe={"ports": ports, "open_ports": results},
request_summary={"threads": args.threads, "timeout": args.timeout},
evidence_refs=evidence_refs,
destructive_risk="low",
args=args,
)
text_lines = [
"=" * 60,
"Port Scanner",
"=" * 60,
f"Target: {args.host}",
f"Ports Checked: {len(ports)}",
f"Open Ports: {len(results)}",
f"Status: {status}",
]
emit_report(args, report, text_lines)
if __name__ == "__main__":

查看文件

@@ -26,6 +26,14 @@ import re
from typing import Dict, List, Tuple, Optional
from datetime import datetime
import sys
from pathlib import Path
SCRIPTS_DIR = Path(__file__).resolve().parents[2] / "scripts"
if str(SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(SCRIPTS_DIR))
from tool_contract import add_common_args, emit_report, ensure_authorized, make_report, write_evidence # noqa: E402
class Colors:
@@ -271,74 +279,45 @@ def main():
parser.add_argument("-u", "--url", required=True, help="目标 URL 或主机名")
parser.add_argument("-p", "--port", type=int, default=443, help="端口 (默认: 443)")
parser.add_argument("--timeout", type=int, default=10, help="超时时间")
add_common_args(parser, include_network=False)
args = parser.parse_args()
ensure_authorized(args, parser)
hostname = args.url.replace("https://", "").replace("http://", "").split("/")[0]
scanner = TLSScanner(timeout=args.timeout)
print(f"\n{Colors.BOLD}{'=' * 60}{Colors.END}")
print(f"{Colors.BOLD}TLS Scanner{Colors.END}")
print(f"{Colors.BOLD}{'=' * 60}{Colors.END}\n")
scanner.print_result("INFO", f"目标: {hostname}:{args.port}")
print(f"\n{Colors.CYAN}[*] 扫描协议支持...{Colors.END}")
results = scanner.scan(hostname, args.port)
print(f"\n{Colors.CYAN}协议支持:{Colors.END}")
for proto, supported in results["protocols"].items():
status = (
f"{Colors.GREEN}支持{Colors.END}"
if supported
else f"{Colors.RED}不支持{Colors.END}"
)
if supported and proto in ["SSLv2", "SSLv3"]:
status = f"{Colors.RED}支持 (不安全){Colors.END}"
elif supported and proto in ["TLSv1.0", "TLSv1.1"]:
status = f"{Colors.YELLOW}支持 (过时){Colors.END}"
print(f" {proto:<10} {status}")
if results["cipher"]:
print(f"\n{Colors.CYAN}当前密码套件:{Colors.END}")
cipher_name, cipher_proto, cipher_bits = results["cipher"]
print(f" 名称: {cipher_name}")
print(f" 协议: {cipher_proto}")
print(f" 密钥长度: {cipher_bits} bits")
if results["certificate"]:
print(f"\n{Colors.CYAN}证书信息:{Colors.END}")
cert = results["certificate"]
print(f" 主题: {cert['subject'].get('commonName', 'N/A')}")
print(f" 颁发者: {cert['issuer'].get('commonName', 'N/A')}")
print(f" 有效期: {cert['not_before']} - {cert['not_after']}")
print(f"\n{Colors.CYAN}HSTS:{Colors.END}")
if results["hsts"]["enabled"]:
print(f" 状态: {Colors.GREEN}已启用{Colors.END}")
print(f" Max-Age: {results['hsts']['max_age']}")
print(
f" IncludeSubDomains: {'' if results['hsts']['include_subdomains'] else ''}"
)
print(f" Preload: {'' if results['hsts']['preload'] else ''}")
else:
print(f" 状态: {Colors.RED}未启用{Colors.END}")
print(f"\n{Colors.CYAN}安全问题:{Colors.END}")
if results["issues"]:
for issue in sorted(results["issues"], key=lambda x: x["severity"]):
color = (
Colors.RED
if issue["severity"] in ["CRITICAL", "HIGH"]
else Colors.YELLOW
)
print(f" {color}[{issue['severity']}]{Colors.END} {issue['issue']}")
print(f" 建议: {issue['recommendation']}")
else:
print(f" {Colors.GREEN}未发现安全问题{Colors.END}")
print(f"\n{Colors.BOLD}{'=' * 60}{Colors.END}\n")
evidence_refs = []
ref = write_evidence(args, "tls-results.json", results)
if ref:
evidence_refs.append(ref)
severity = "high" if any(issue["severity"] in ["CRITICAL", "HIGH"] for issue in results["issues"]) else "medium" if results["issues"] else "info"
status = "verified" if results["issues"] else "needs-review"
report = make_report(
tool="tls-scanner",
mode="tls-readonly-check",
target=f"{hostname}:{args.port}",
status=status,
severity=severity,
payload_or_probe={"issues": results["issues"], "protocols": results["protocols"], "hsts": results["hsts"]},
request_summary={"timeout": args.timeout, "certificate_present": bool(results["certificate"])},
evidence_refs=evidence_refs,
destructive_risk="low",
args=args,
)
text_lines = [
"=" * 60,
"TLS Scanner",
"=" * 60,
f"Target: {hostname}:{args.port}",
f"Issues: {len(results['issues'])}",
f"HSTS Enabled: {'yes' if results['hsts']['enabled'] else 'no'}",
f"Status: {status}",
]
emit_report(args, report, text_lines)
if __name__ == "__main__":