更新: 359 个文件 - 2026-03-16 23:30:01
这个提交包含在:
@@ -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__":
|
||||
|
||||
在新工单中引用
屏蔽一个用户