#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Windows安全审计报表生成工具
自动分析Windows安全日志,生成HTML格式的安全审计报表
“gbfvzhsybvtybsibvuipqfnnvlkashfgiawug”
"""

import os
import sys
import subprocess
import json
from datetime import datetime
from collections import defaultdict, Counter
import webbrowser

def run_powershell(command):
    """执行PowerShell命令并返回结果"""
    try:
        result = subprocess.run(
            ['powershell', '-Command', command],
            capture_output=True,
            text=True,
            encoding='gbk',  # Windows中文系统使用gbk编码
            errors='ignore'  # 忽略编码错误
        )
        return result.stdout
    except Exception as e:
        print(f"执行PowerShell命令失败: {e}")
        return ""

def get_failed_logins(max_events=1000):
    """获取登录失败事件 (事件ID 4625)"""
    print("正在分析登录失败事件...")
    
    ps_script = f"""
    $events = Get-EventLog -LogName Security -InstanceId 4625 -Newest {max_events} -ErrorAction SilentlyContinue
    $events | ForEach-Object {{
        [PSCustomObject]@{{
            Time = $_.TimeGenerated.ToString("yyyy-MM-dd HH:mm:ss")
            User = $_.ReplacementStrings[5]
            SourceIP = $_.ReplacementStrings[19]
            LogonType = $_.ReplacementStrings[10]
            SubStatus = $_.ReplacementStrings[9]
        }}
    }} | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_account_lockouts(max_events=50):
    """获取账户锁定事件 (事件ID 4740)"""
    print("正在分析账户锁定事件...")
    
    ps_script = f"""
    $events = Get-EventLog -LogName Security -InstanceId 4740 -Newest {max_events} -ErrorAction SilentlyContinue
    $events | ForEach-Object {{
        [PSCustomObject]@{{
            Time = $_.TimeGenerated.ToString("yyyy-MM-dd HH:mm:ss")
            LockedAccount = $_.ReplacementStrings[0]
            CallerComputer = $_.ReplacementStrings[1]
        }}
    }} | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_successful_logins(max_events=500):
    """获取成功登录事件 (事件ID 4624, 登录类型3和10)"""
    print("正在分析成功登录事件...")
    
    ps_script = f"""
    $events = Get-EventLog -LogName Security -InstanceId 4624 -Newest {max_events} -ErrorAction SilentlyContinue | 
        Where-Object {{ $_.ReplacementStrings[8] -eq "10" -or $_.ReplacementStrings[8] -eq "3" }}
    $events | ForEach-Object {{
        [PSCustomObject]@{{
            Time = $_.TimeGenerated.ToString("yyyy-MM-dd HH:mm:ss")
            User = $_.ReplacementStrings[5]
            SourceIP = $_.ReplacementStrings[18]
            LogonType = $_.ReplacementStrings[8]
        }}
    }} | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_network_adapters():
    """获取所有网络适配器信息"""
    print("正在检查网络适配器...")
    
    ps_script = """
    Get-NetAdapter | ForEach-Object {
        [PSCustomObject]@{
            Name = $_.Name
            Status = $_.Status
            InterfaceDescription = $_.InterfaceDescription
            MacAddress = $_.MacAddress
            LinkSpeed = $_.LinkSpeed
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_ip_configuration():
    """获取IP配置信息"""
    print("正在检查IP配置...")
    
    ps_script = """
    Get-NetIPAddress | Where-Object {$_.AddressFamily -eq "IPv4"} | ForEach-Object {
        [PSCustomObject]@{
            InterfaceAlias = $_.InterfaceAlias
            IPAddress = $_.IPAddress
            PrefixLength = $_.PrefixLength
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_suspicious_routes():
    """获取可疑的路由(192.168段)"""
    print("正在检查路由表...")
    
    ps_script = """
    Get-NetRoute | Where-Object {$_.DestinationPrefix -like "192.168.*"} | ForEach-Object {
        [PSCustomObject]@{
            DestinationPrefix = $_.DestinationPrefix
            NextHop = $_.NextHop
            InterfaceAlias = $_.InterfaceAlias
            RouteMetric = $_.RouteMetric
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_active_connections():
    """获取活动的网络连接"""
    print("正在检查活动连接...")
    
    ps_script = """
    $connections = Get-NetTCPConnection | Where-Object {$_.State -ne "Bound"} | Select-Object -First 100
    $result = @()
    foreach ($conn in $connections) {
        try {
            $process = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
            $result += [PSCustomObject]@{
                LocalAddress = $conn.LocalAddress
                LocalPort = $conn.LocalPort
                RemoteAddress = $conn.RemoteAddress
                RemotePort = $conn.RemotePort
                State = $conn.State
                ProcessName = if ($process) { $process.ProcessName } else { "Unknown" }
                ProcessId = $conn.OwningProcess
                ProcessPath = if ($process) { $process.Path } else { "" }
            }
        } catch {}
    }
    $result | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_listening_processes():
    """获取监听端口的进程"""
    print("正在检查监听进程...")
    
    ps_script = """
    $listeners = Get-NetTCPConnection | Where-Object {$_.State -eq "Listen"}
    $result = @()
    foreach ($listener in $listeners) {
        try {
            $process = Get-Process -Id $listener.OwningProcess -ErrorAction SilentlyContinue
            if ($process) {
                $result += [PSCustomObject]@{
                    LocalPort = $listener.LocalPort
                    ProcessName = $process.ProcessName
                    ProcessId = $process.Id
                    ProcessPath = $process.Path
                }
            }
        } catch {}
    }
    $result | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_vpn_connections():
    """获取VPN连接信息"""
    print("正在检查VPN连接...")
    
    ps_script = """
    try {
        $vpns = Get-VpnConnection -ErrorAction SilentlyContinue
        $vpns | ForEach-Object {
            [PSCustomObject]@{
                Name = $_.Name
                ServerAddress = $_.ServerAddress
                ConnectionStatus = $_.ConnectionStatus
                TunnelType = $_.TunnelType
            }
        } | ConvertTo-Json
    } catch {
        @() | ConvertTo-Json
    }
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_virtual_adapters():
    """获取虚拟网络适配器"""
    print("正在检查虚拟网络适配器...")
    
    ps_script = """
    Get-NetAdapter | Where-Object {
        $_.InterfaceDescription -match "Virtual|VMware|VirtualBox|Hyper-V|vEthernet|TAP|OpenVPN|WireGuard|Tunnel"
    } | ForEach-Object {
        [PSCustomObject]@{
            Name = $_.Name
            Status = $_.Status
            InterfaceDescription = $_.InterfaceDescription
            MacAddress = $_.MacAddress
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_suspicious_tasks():
    """获取可疑的计划任务"""
    print("正在检查计划任务...")
    
    ps_script = """
    Get-ScheduledTask | Where-Object {
        $_.State -eq "Ready" -and 
        ($_.Actions.Execute -match "powershell|cmd|wscript|cscript" -or
         $_.Actions.Arguments -match "192.168|tunnel|proxy")
    } | Select-Object -First 20 | ForEach-Object {
        [PSCustomObject]@{
            TaskName = $_.TaskName
            State = $_.State
            TaskPath = $_.TaskPath
            Author = $_.Author
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def get_local_accounts():
    """获取本地账户信息"""
    print("正在检查本地账户...")
    
    ps_script = """
    Get-LocalUser | ForEach-Object {
        [PSCustomObject]@{
            Name = $_.Name
            Enabled = $_.Enabled
            PasswordRequired = $_.PasswordRequired
            PasswordLastSet = if ($_.PasswordLastSet) { $_.PasswordLastSet.ToString("yyyy-MM-dd HH:mm:ss") } else { "从未设置" }
            LastLogon = if ($_.LastLogon) { $_.LastLogon.ToString("yyyy-MM-dd HH:mm:ss") } else { "从未登录" }
            Description = $_.Description
        }
    } | ConvertTo-Json
    """
    
    output = run_powershell(ps_script)
    if output:
        try:
            data = json.loads(output)
            if isinstance(data, dict):
                data = [data]
            return data
        except:
            return []
    return []

def check_rdp_security_settings():
    """检查RDP安全设置"""
    print("正在检查远程桌面安全配置...")
    
    settings = {}
    
    # 检查NLA（网络级别身份验证）
    ps_nla = "(Get-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp' -Name 'UserAuthentication' -ErrorAction SilentlyContinue).UserAuthentication"
    nla_result = run_powershell(ps_nla).strip()
    settings['nla_enabled'] = nla_result == '1'
    
    # 检查RDP端口
    ps_port = "(Get-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp' -Name 'PortNumber' -ErrorAction SilentlyContinue).PortNumber"
    port_result = run_powershell(ps_port).strip()
    settings['rdp_port'] = port_result if port_result else '3389'
    
    # 检查是否启用远程桌面
    ps_enabled = "(Get-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server' -Name 'fDenyTSConnections' -ErrorAction SilentlyContinue).fDenyTSConnections"
    enabled_result = run_powershell(ps_enabled).strip()
    settings['rdp_enabled'] = enabled_result == '0'
    
    # 检查账户锁定策略
    ps_lockout = "net accounts | Select-String -Pattern 'Lockout threshold|Lockout duration|Lockout observation window'"
    lockout_result = run_powershell(ps_lockout)
    settings['lockout_policy'] = lockout_result
    
    # 检查是否只允许微软账户
    ps_ms_only = "(Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System' -Name 'NoConnectedUser' -ErrorAction SilentlyContinue).NoConnectedUser"
    ms_only_result = run_powershell(ps_ms_only).strip()
    settings['ms_account_only'] = ms_only_result == '3'
    
    return settings

def get_arp_cache():
    """获取ARP缓存"""
    print("正在检查ARP缓存...")
    
    output = run_powershell("arp -a")
    arp_entries = []
    
    for line in output.split('\n'):
        if '192.168.' in line:
            parts = line.split()
            if len(parts) >= 2:
                arp_entries.append({
                    'ip': parts[0],
                    'mac': parts[1] if len(parts) > 1 else '',
                    'type': parts[2] if len(parts) > 2 else ''
                })
    
    return arp_entries

def analyze_failed_logins(failed_logins):
    """分析失败登录数据"""
    ip_stats = defaultdict(lambda: {'count': 0, 'first_time': None, 'last_time': None})
    user_stats = Counter()
    hourly_stats = Counter()
    
    for event in failed_logins:
        source_ip = event.get('SourceIP', '-')
        user = event.get('User', '-')
        time_str = event.get('Time', '')
        
        # IP统计
        if source_ip and source_ip != '-':
            ip_stats[source_ip]['count'] += 1
            if not ip_stats[source_ip]['first_time']:
                ip_stats[source_ip]['first_time'] = time_str
            ip_stats[source_ip]['last_time'] = time_str
        
        # 用户统计
        if user and user != '-':
            user_stats[user] += 1
        
        # 小时统计
        if time_str:
            hour = time_str[:13] + ':00'  # 取到小时
            hourly_stats[hour] += 1
    
    # 转换为排序列表
    ip_list = [
        {
            'ip': ip,
            'count': data['count'],
            'first_time': data['first_time'],
            'last_time': data['last_time']
        }
        for ip, data in ip_stats.items()
    ]
    ip_list.sort(key=lambda x: x['count'], reverse=True)
    
    user_list = [{'user': user, 'count': count} for user, count in user_stats.most_common()]
    
    hourly_list = [{'hour': hour, 'count': count} for hour, count in sorted(hourly_stats.items())]
    
    return ip_list, user_list, hourly_list

def generate_html_report(failed_logins, lockouts, successful_logins, network_data, output_path):
    """生成HTML报表"""
    
    # 获取系统信息
    computer_name = os.environ.get('COMPUTERNAME', 'Unknown')
    report_date = datetime.now().strftime('%Y年%m月%d日 %H:%M:%S')
    
    # 分析数据
    ip_stats, user_stats, hourly_stats = analyze_failed_logins(failed_logins)
    
    # 解包网络数据
    adapters = network_data.get('adapters', [])
    ip_config = network_data.get('ip_config', [])
    routes = network_data.get('routes', [])
    connections = network_data.get('connections', [])
    listeners = network_data.get('listeners', [])
    vpns = network_data.get('vpns', [])
    virtual_adapters = network_data.get('virtual_adapters', [])
    suspicious_tasks = network_data.get('suspicious_tasks', [])
    arp_cache = network_data.get('arp_cache', [])
    local_accounts = network_data.get('local_accounts', [])
    rdp_settings = network_data.get('rdp_settings', {})
    
    # 分析可疑连接
    suspicious_connections = [c for c in connections if '192.168.' in c.get('RemoteAddress', '')]
    
    # 生成HTML
    html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>安全审计报表 - {report_date}</title>
    <style>
        body {{
            font-family: 'Microsoft YaHei', 'Segoe UI', Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: #333;
        }}
        .container {{
            max-width: 1400px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
            box-shadow: 0 10px 40px rgba(0,0,0,0.2);
        }}
        h1 {{
            color: #e74c3c;
            text-align: center;
            margin-bottom: 10px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
        }}
        .subtitle {{
            text-align: center;
            color: #7f8c8d;
            margin-bottom: 30px;
            font-size: 1.1em;
        }}
        .alert {{
            background: #fff3cd;
            border-left: 5px solid #ffc107;
            padding: 15px;
            margin: 20px 0;
            border-radius: 5px;
        }}
        .danger {{
            background: #f8d7da;
            border-left: 5px solid #dc3545;
        }}
        .success {{
            background: #d4edda;
            border-left: 5px solid #28a745;
        }}
        .info {{
            background: #d1ecf1;
            border-left: 5px solid #17a2b8;
        }}
        .summary-box {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin: 30px 0;
        }}
        .summary-item {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 10px;
            text-align: center;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            transition: transform 0.3s;
        }}
        .summary-item:hover {{
            transform: translateY(-5px);
        }}
        .summary-number {{
            font-size: 3em;
            font-weight: bold;
            margin: 10px 0;
        }}
        .summary-label {{
            font-size: 1.1em;
            opacity: 0.9;
        }}
        table {{
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }}
        th {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 12px;
            text-align: left;
            font-weight: 600;
        }}
        td {{
            padding: 10px;
            border-bottom: 1px solid #ddd;
        }}
        tr:hover {{
            background: #f5f5f5;
        }}
        tr:nth-child(even) {{
            background: #f9f9f9;
        }}
        .section {{
            margin: 40px 0;
        }}
        .section-title {{
            color: #2c3e50;
            border-bottom: 3px solid #667eea;
            padding-bottom: 10px;
            margin: 30px 0 20px 0;
            font-size: 1.8em;
        }}
        .high-risk {{
            color: #e74c3c;
            font-weight: bold;
        }}
        .medium-risk {{
            color: #f39c12;
            font-weight: bold;
        }}
        .low-risk {{
            color: #27ae60;
        }}
        .footer {{
            text-align: center;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 2px solid #ddd;
            color: #7f8c8d;
        }}
        .recommendations {{
            background: #e8f5e9;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
        }}
        .recommendations h3 {{
            color: #2e7d32;
            margin-top: 0;
        }}
        .recommendations ul {{
            line-height: 1.8;
        }}
        .recommendations li {{
            margin: 10px 0;
        }}
        .timestamp {{
            font-family: 'Courier New', monospace;
            background: #f0f0f0;
            padding: 2px 6px;
            border-radius: 3px;
        }}
        pre {{
            background: #2c3e50;
            color: #ecf0f1;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
        }}
    </style>
</head>
<body>
    <div class="container">
        <h1>🛡️ Windows 安全审计报表</h1>
        <div class="subtitle">
            <strong>主机名:</strong> {computer_name} | 
            <strong>生成时间:</strong> {report_date}
        </div>

        <div class="alert danger">
            <h3>⚠️ 安全警报</h3>
            <p>检测到大量登录失败尝试,您的系统可能正在遭受暴力破解攻击!</p>
            {f'<p><strong>⚠️ 检测到 {len(suspicious_connections)} 个可疑的192.168网段连接!</strong></p>' if suspicious_connections else ''}
            {f'<p><strong>🔍 检测到 {len(virtual_adapters)} 个虚拟网络适配器</strong></p>' if virtual_adapters else ''}
            {f'<p><strong>🔌 检测到 {len(vpns)} 个VPN连接</strong></p>' if vpns else ''}
        </div>

        <!-- 摘要统计 -->
        <div class="summary-box">
            <div class="summary-item">
                <div class="summary-label">登录失败总次数</div>
                <div class="summary-number">{len(failed_logins)}</div>
            </div>
            <div class="summary-item">
                <div class="summary-label">攻击来源IP数量</div>
                <div class="summary-number">{len(ip_stats)}</div>
            </div>
            <div class="summary-item">
                <div class="summary-label">账户锁定次数</div>
                <div class="summary-number">{len(lockouts)}</div>
            </div>
            <div class="summary-item">
                <div class="summary-label">受攻击账户数</div>
                <div class="summary-number">{len(user_stats)}</div>
            </div>
        </div>

        <!-- 攻击来源IP统计 -->
        <div class="section">
            <h2 class="section-title">🌐 攻击来源IP统计 (Top 20)</h2>
            <table>
                <thead>
                    <tr>
                        <th>排名</th>
                        <th>IP地址</th>
                        <th>失败次数</th>
                        <th>首次攻击时间</th>
                        <th>最后攻击时间</th>
                        <th>风险等级</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    # IP统计表格
    for i, ip_data in enumerate(ip_stats[:20], 1):
        count = ip_data['count']
        risk_class = 'high-risk' if count > 100 else ('medium-risk' if count > 50 else 'low-risk')
        risk_text = '高危' if count > 100 else ('中危' if count > 50 else '低危')
        
        html += f"""                    <tr>
                        <td>{i}</td>
                        <td><span class="timestamp">{ip_data['ip']}</span></td>
                        <td class="{risk_class}">{count}</td>
                        <td>{ip_data['first_time']}</td>
                        <td>{ip_data['last_time']}</td>
                        <td class="{risk_class}">{risk_text}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
        </div>

        <!-- 受攻击账户统计 -->
        <div class="section">
            <h2 class="section-title">👤 受攻击账户统计</h2>
            <table>
                <thead>
                    <tr>
                        <th>排名</th>
                        <th>账户名</th>
                        <th>失败次数</th>
                        <th>风险等级</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    # 用户统计表格
    for i, user_data in enumerate(user_stats, 1):
        count = user_data['count']
        risk_class = 'high-risk' if count > 100 else ('medium-risk' if count > 50 else 'low-risk')
        risk_text = '高危' if count > 100 else ('中危' if count > 50 else '低危')
        
        html += f"""                    <tr>
                        <td>{i}</td>
                        <td><strong>{user_data['user']}</strong></td>
                        <td class="{risk_class}">{count}</td>
                        <td class="{risk_class}">{risk_text}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
        </div>

        <!-- 按小时攻击频率 -->
        <div class="section">
            <h2 class="section-title">📊 攻击时间分布</h2>
            <table>
                <thead>
                    <tr>
                        <th>时间段</th>
                        <th>失败次数</th>
                        <th>攻击强度</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    # 时间分布表格
    for hour_data in hourly_stats:
        count = hour_data['count']
        intensity = '⚠️ 高强度' if count > 50 else ('⚡ 中强度' if count > 20 else '💤 低强度')
        
        html += f"""                    <tr>
                        <td><span class="timestamp">{hour_data['hour']}</span></td>
                        <td>{count}</td>
                        <td>{intensity}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
        </div>

        <!-- 账户锁定事件 -->
        <div class="section">
            <h2 class="section-title">🔒 账户锁定事件</h2>
"""
    
    if lockouts:
        html += """            <table>
                <thead>
                    <tr>
                        <th>锁定时间</th>
                        <th>被锁定账户</th>
                        <th>来源计算机</th>
                    </tr>
                </thead>
                <tbody>
"""
        for lockout in lockouts:
            html += f"""                    <tr>
                        <td>{lockout.get('Time', '')}</td>
                        <td><strong class="high-risk">{lockout.get('LockedAccount', '')}</strong></td>
                        <td>{lockout.get('CallerComputer', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    else:
        html += """            <p class="alert success">✅ 未检测到账户锁定事件</p>
"""
    
    html += """        </div>

        <!-- 最近成功登录 -->
        <div class="section">
            <h2 class="section-title">✅ 最近成功登录记录 (Top 30)</h2>
            <table>
                <thead>
                    <tr>
                        <th>登录时间</th>
                        <th>用户名</th>
                        <th>来源IP</th>
                        <th>登录类型</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    logon_type_map = {'2': '交互式登录', '3': '网络登录', '10': '远程桌面'}
    
    for login in successful_logins[:30]:
        logon_type = login.get('LogonType', '')
        logon_type_text = logon_type_map.get(logon_type, logon_type)
        
        html += f"""                    <tr>
                        <td>{login.get('Time', '')}</td>
                        <td>{login.get('User', '')}</td>
                        <td><span class="timestamp">{login.get('SourceIP', '')}</span></td>
                        <td>{logon_type_text}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
        </div>

        <!-- 远程桌面安全配置 -->
        <div class="section">
            <h2 class="section-title">🔐 远程桌面安全配置检查</h2>
"""
    
    # RDP配置检查
    rdp_enabled = rdp_settings.get('rdp_enabled', False)
    nla_enabled = rdp_settings.get('nla_enabled', False)
    rdp_port = rdp_settings.get('rdp_port', '3389')
    ms_account_only = rdp_settings.get('ms_account_only', False)
    
    if rdp_enabled:
        html += """            <div class="alert danger">
                <h4>⚠️ 远程桌面服务已启用</h4>
                <p>系统当前允许远程桌面连接,请确保已配置适当的安全措施</p>
            </div>
"""
    
    html += """            <table>
                <thead>
                    <tr>
                        <th>安全项目</th>
                        <th>当前状态</th>
                        <th>建议状态</th>
                        <th>风险等级</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    # 远程桌面状态
    rdp_status_text = "✅ 已启用" if rdp_enabled else "❌ 已禁用"
    rdp_risk = "medium-risk" if rdp_enabled else "low-risk"
    html += f"""                    <tr>
                        <td><strong>远程桌面服务</strong></td>
                        <td class="{rdp_risk}">{rdp_status_text}</td>
                        <td>根据需求启用</td>
                        <td class="{rdp_risk}">{'中' if rdp_enabled else '低'}</td>
                    </tr>
"""
    
    # NLA状态
    nla_status_text = "✅ 已启用" if nla_enabled else "❌ 未启用"
    nla_risk = "low-risk" if nla_enabled else "high-risk"
    html += f"""                    <tr>
                        <td><strong>网络级别身份验证(NLA)</strong></td>
                        <td class="{nla_risk}">{nla_status_text}</td>
                        <td>✅ 必须启用</td>
                        <td class="{nla_risk}">{'低' if nla_enabled else '高危'}</td>
                    </tr>
"""
    
    # RDP端口
    port_is_default = rdp_port == '3389'
    port_risk = "medium-risk" if port_is_default else "low-risk"
    html += f"""                    <tr>
                        <td><strong>RDP端口</strong></td>
                        <td class="{port_risk}">{rdp_port}</td>
                        <td>建议修改默认端口</td>
                        <td class="{port_risk}">{'中' if port_is_default else '低'}</td>
                    </tr>
"""
    
    # 微软账户强制验证
    ms_status_text = "✅ 已强制" if ms_account_only else "❌ 未强制"
    ms_risk = "low-risk" if ms_account_only else "high-risk"
    html += f"""                    <tr>
                        <td><strong>强制微软账户登录</strong></td>
                        <td class="{ms_risk}">{ms_status_text}</td>
                        <td>✅ 建议启用</td>
                        <td class="{ms_risk}">{'低' if ms_account_only else '高危'}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
"""
    
    # 显示账户锁定策略
    lockout_policy = rdp_settings.get('lockout_policy', '')
    if lockout_policy:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">🔒 账户锁定策略</h3>
            <pre>{lockout_policy}</pre>
"""
    
    # 配置建议
    if not nla_enabled or not ms_account_only or port_is_default:
        html += """            <div class="alert danger">
                <h4>🚨 紧急安全建议</h4>
                <ul>
"""
        if not nla_enabled:
            html += """                    <li><strong>必须启用网络级别身份验证(NLA)</strong> - 这可以防止未经身份验证的攻击者连接到RDP服务</li>
"""
        if not ms_account_only:
            html += """                    <li><strong>建议强制使用微软账户登录</strong> - 微软账户支持多因素认证,比本地账户更安全</li>
"""
        if port_is_default:
            html += """                    <li><strong>修改默认RDP端口</strong> - 将3389改为其他端口可以减少自动化攻击</li>
"""
        html += """                </ul>
            </div>
"""
    
    html += """        </div>

        <!-- 本地账户信息 -->
        <div class="section">
            <h2 class="section-title">👥 本地账户信息</h2>
"""
    
    if local_accounts:
        enabled_accounts = [acc for acc in local_accounts if acc.get('Enabled')]
        html += f"""            <div class="alert {'danger' if len(enabled_accounts) > 2 else 'info'}">
                <p><strong>检测到 {len(local_accounts)} 个本地账户,其中 {len(enabled_accounts)} 个已启用</strong></p>
                <p>建议: 仅保留必要的本地账户,禁用或删除不需要的账户,优先使用微软账户登录</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>账户名</th>
                        <th>状态</th>
                        <th>需要密码</th>
                        <th>密码最后设置</th>
                        <th>最后登录</th>
                        <th>描述</th>
                    </tr>
                </thead>
                <tbody>
"""
        for account in local_accounts:
            enabled = account.get('Enabled')
            status_class = 'medium-risk' if enabled else 'low-risk'
            status_text = '✅ 已启用' if enabled else '❌ 已禁用'
            pwd_required = account.get('PasswordRequired')
            pwd_class = 'low-risk' if pwd_required else 'high-risk'
            pwd_text = '✅ 是' if pwd_required else '❌ 否'
            
            html += f"""                    <tr>
                        <td><strong>{account.get('Name', '')}</strong></td>
                        <td class="{status_class}">{status_text}</td>
                        <td class="{pwd_class}">{pwd_text}</td>
                        <td>{account.get('PasswordLastSet', '')}</td>
                        <td>{account.get('LastLogon', '')}</td>
                        <td>{account.get('Description', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    html += """        </div>

        <!-- 网络异常检查 -->
        <div class="section">
            <h2 class="section-title">🔍 网络异常深度检查</h2>
            
            <!-- 网络适配器 -->
            <h3 style="color:#2c3e50;margin-top:30px;">📡 网络适配器</h3>
"""
    
    if adapters:
        html += """            <table>
                <thead>
                    <tr>
                        <th>适配器名称</th>
                        <th>状态</th>
                        <th>描述</th>
                        <th>MAC地址</th>
                        <th>速度</th>
                    </tr>
                </thead>
                <tbody>
"""
        for adapter in adapters:
            status_class = 'low-risk' if adapter.get('Status') == 'Up' else ''
            html += f"""                    <tr>
                        <td><strong>{adapter.get('Name', '')}</strong></td>
                        <td class="{status_class}">{adapter.get('Status', '')}</td>
                        <td>{adapter.get('InterfaceDescription', '')}</td>
                        <td><span class="timestamp">{adapter.get('MacAddress', '')}</span></td>
                        <td>{adapter.get('LinkSpeed', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # 虚拟适配器
    if virtual_adapters:
        html += f"""            <div class="alert danger">
                <h4>⚠️ 检测到 {len(virtual_adapters)} 个虚拟网络适配器</h4>
                <p>这些可能是VPN、虚拟机或隧道服务创建的网络接口</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>适配器名称</th>
                        <th>状态</th>
                        <th>描述</th>
                        <th>MAC地址</th>
                    </tr>
                </thead>
                <tbody>
"""
        for vadapter in virtual_adapters:
            html += f"""                    <tr>
                        <td><strong class="high-risk">{vadapter.get('Name', '')}</strong></td>
                        <td>{vadapter.get('Status', '')}</td>
                        <td>{vadapter.get('InterfaceDescription', '')}</td>
                        <td><span class="timestamp">{vadapter.get('MacAddress', '')}</span></td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # IP配置
    html += """            <h3 style="color:#2c3e50;margin-top:30px;">🌐 IP配置</h3>
            <table>
                <thead>
                    <tr>
                        <th>网络接口</th>
                        <th>IP地址</th>
                        <th>子网掩码长度</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    for ip in ip_config:
        ip_addr = ip.get('IPAddress', '')
        ip_class = 'medium-risk' if '192.168.' in ip_addr else ''
        html += f"""                    <tr>
                        <td>{ip.get('InterfaceAlias', '')}</td>
                        <td class="{ip_class}"><span class="timestamp">{ip_addr}</span></td>
                        <td>{ip.get('PrefixLength', '')}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
"""
    
    # 路由表
    if routes:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">🛣️ 可疑路由 (192.168段)</h3>
            <div class="alert danger">
                <p><strong>⚠️ 检测到 {len(routes)} 条192.168网段路由!</strong></p>
                <p>如果您的网络中不应该有这个网段,这可能是异常情况</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>目标网络</th>
                        <th>下一跳</th>
                        <th>网络接口</th>
                        <th>路由优先级</th>
                    </tr>
                </thead>
                <tbody>
"""
        for route in routes:
            html += f"""                    <tr>
                        <td><span class="timestamp high-risk">{route.get('DestinationPrefix', '')}</span></td>
                        <td><span class="timestamp">{route.get('NextHop', '')}</span></td>
                        <td>{route.get('InterfaceAlias', '')}</td>
                        <td>{route.get('RouteMetric', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # VPN连接
    if vpns:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">🔐 VPN连接</h3>
            <div class="alert info">
                <p><strong>检测到 {len(vpns)} 个VPN连接配置</strong></p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>VPN名称</th>
                        <th>服务器地址</th>
                        <th>连接状态</th>
                        <th>隧道类型</th>
                    </tr>
                </thead>
                <tbody>
"""
        for vpn in vpns:
            status_class = 'low-risk' if vpn.get('ConnectionStatus') == 'Connected' else ''
            html += f"""                    <tr>
                        <td><strong>{vpn.get('Name', '')}</strong></td>
                        <td><span class="timestamp">{vpn.get('ServerAddress', '')}</span></td>
                        <td class="{status_class}">{vpn.get('ConnectionStatus', '')}</td>
                        <td>{vpn.get('TunnelType', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # 可疑连接
    if suspicious_connections:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">⚠️ 可疑网络连接 (192.168段)</h3>
            <div class="alert danger">
                <p><strong>🚨 检测到 {len(suspicious_connections)} 个到192.168网段的活动连接!</strong></p>
                <p>如果您的网络中不使用该网段,这些连接可能是异常的</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>本地地址:端口</th>
                        <th>远程地址:端口</th>
                        <th>状态</th>
                        <th>进程名</th>
                        <th>进程ID</th>
                        <th>进程路径</th>
                    </tr>
                </thead>
                <tbody>
"""
        for conn in suspicious_connections[:50]:  # 限制显示50条
            html += f"""                    <tr>
                        <td><span class="timestamp">{conn.get('LocalAddress', '')}:{conn.get('LocalPort', '')}</span></td>
                        <td><span class="timestamp high-risk">{conn.get('RemoteAddress', '')}:{conn.get('RemotePort', '')}</span></td>
                        <td>{conn.get('State', '')}</td>
                        <td><strong>{conn.get('ProcessName', '')}</strong></td>
                        <td>{conn.get('ProcessId', '')}</td>
                        <td style="font-size:0.85em;">{conn.get('ProcessPath', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # 监听端口
    html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">👂 监听端口 (Top 30)</h3>
            <table>
                <thead>
                    <tr>
                        <th>端口</th>
                        <th>进程名</th>
                        <th>进程ID</th>
                        <th>进程路径</th>
                    </tr>
                </thead>
                <tbody>
"""
    
    for listener in listeners[:30]:
        port = listener.get('LocalPort', 0)
        port_class = 'high-risk' if port in [3389, 22, 23, 445, 135] else ('medium-risk' if port < 1024 else '')
        html += f"""                    <tr>
                        <td class="{port_class}"><strong>{port}</strong></td>
                        <td>{listener.get('ProcessName', '')}</td>
                        <td>{listener.get('ProcessId', '')}</td>
                        <td style="font-size:0.85em;">{listener.get('ProcessPath', '')}</td>
                    </tr>
"""
    
    html += """                </tbody>
            </table>
"""
    
    # ARP缓存
    if arp_cache:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">📋 ARP缓存 (192.168段)</h3>
            <table>
                <thead>
                    <tr>
                        <th>IP地址</th>
                        <th>MAC地址</th>
                        <th>类型</th>
                    </tr>
                </thead>
                <tbody>
"""
        for arp in arp_cache:
            html += f"""                    <tr>
                        <td><span class="timestamp high-risk">{arp.get('ip', '')}</span></td>
                        <td><span class="timestamp">{arp.get('mac', '')}</span></td>
                        <td>{arp.get('type', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    # 可疑计划任务
    if suspicious_tasks:
        html += f"""            <h3 style="color:#2c3e50;margin-top:30px;">⏰ 可疑计划任务</h3>
            <div class="alert danger">
                <p><strong>⚠️ 检测到 {len(suspicious_tasks)} 个可疑的计划任务!</strong></p>
                <p>这些任务可能包含脚本执行或网络活动</p>
            </div>
            <table>
                <thead>
                    <tr>
                        <th>任务名称</th>
                        <th>状态</th>
                        <th>路径</th>
                        <th>作者</th>
                    </tr>
                </thead>
                <tbody>
"""
        for task in suspicious_tasks:
            html += f"""                    <tr>
                        <td><strong class="high-risk">{task.get('TaskName', '')}</strong></td>
                        <td>{task.get('State', '')}</td>
                        <td style="font-size:0.85em;">{task.get('TaskPath', '')}</td>
                        <td>{task.get('Author', '')}</td>
                    </tr>
"""
        html += """                </tbody>
            </table>
"""
    
    html += """        </div>

        <!-- 安全建议 -->
        <div class="recommendations">
            <h3>🛡️ 安全加固建议</h3>
            <ul>
                <li><strong>立即封锁高危IP:</strong> 使用防火墙规则阻止上述高危IP地址的访问</li>
                <li><strong>强制使用微软账户:</strong> 配置系统仅允许微软账户远程登录,禁用本地账户远程访问</li>
                <li><strong>启用多因素认证(MFA):</strong> 为微软账户配置双因素认证,大幅提升安全性</li>
                <li><strong>修改管理员密码:</strong> 立即修改Administrator等高权限账户的密码,使用强密码(至少16位,包含大小写字母、数字和特殊字符)</li>
                <li><strong>启用网络级别身份验证(NLA):</strong> 必须在远程桌面设置中启用NLA,防止未授权连接</li>
                <li><strong>启用账户锁定策略:</strong> 设置5次失败登录后锁定账户30分钟</li>
                <li><strong>禁用不必要的账户:</strong> 禁用或重命名Administrator账户,使用自定义管理员账户</li>
                <li><strong>限制远程访问:</strong> 仅允许特定IP访问远程桌面服务,考虑使用VPN</li>
                <li><strong>更改默认端口:</strong> 将RDP默认端口3389修改为其他端口(如33890)</li>
                <li><strong>定期审计日志:</strong> 建立日志监控机制,及时发现异常行为</li>
                <li><strong>部署入侵检测系统:</strong> 考虑部署IDS/IPS系统进行实时监控</li>
                <li><strong>限制本地账户使用:</strong> 通过组策略禁止本地账户通过网络和RDP登录</li>
            </ul>
        </div>

        <!-- 快速响应命令 -->
        <div class="section">
            <h2 class="section-title">⚡ 快速响应命令</h2>
            <div class="alert info">
"""
    
    if ip_stats:
        top_ip = ip_stats[0]['ip']
        html += f"""                <h4>1. 封锁高危IP地址 (最高危IP: {top_ip}):</h4>
                <pre>New-NetFirewallRule -DisplayName "Block_{top_ip}" -Direction Inbound -RemoteAddress {top_ip} -Action Block</pre>
"""
    
    html += """                
                <h4>2. 启用网络级别身份验证(NLA):</h4>
                <pre>Set-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp' -Name 'UserAuthentication' -Value 1</pre>
                
                <h4>3. 强制仅允许微软账户登录(推荐):</h4>
                <pre># 方法1: 通过组策略禁止本地账户网络登录
# 打开 gpedit.msc
# 计算机配置 > Windows设置 > 安全设置 > 本地策略 > 用户权限分配
# "拒绝从网络访问此计算机" 添加本地账户

# 方法2: 禁用本地账户(保留一个紧急账户)
Get-LocalUser | Where-Object {$_.Name -ne 'Administrator' -and $_.Enabled -eq $true} | Disable-LocalUser

# 方法3: 通过注册表限制(需要Windows 10专业版或企业版)
Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System' -Name 'NoConnectedUser' -Value 3 -Type DWord</pre>
                
                <h4>4. 修改RDP默认端口(例如改为33890):</h4>
                <pre>Set-ItemProperty -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp' -Name 'PortNumber' -Value 33890
Restart-Service TermService -Force
New-NetFirewallRule -DisplayName "RDP-Custom-Port" -Direction Inbound -Protocol TCP -LocalPort 33890 -Action Allow</pre>
                
                <h4>5. 配置账户锁定策略:</h4>
                <pre>net accounts /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30</pre>
                
                <h4>6. 仅允许特定IP访问RDP:</h4>
                <pre># 先删除默认允许规则
Disable-NetFirewallRule -DisplayName "Remote Desktop*"
# 添加特定IP允许规则(替换为您的IP)
New-NetFirewallRule -DisplayName "RDP-Allowed-IP" -Direction Inbound -Protocol TCP -LocalPort 3389 -RemoteAddress "您的IP地址" -Action Allow</pre>
                
                <h4>7. 修改管理员密码:</h4>
                <pre>net user Administrator *</pre>
                
                <h4>8. 查看当前活动的远程会话:</h4>
                <pre>qwinsta
# 断开可疑会话
logoff &lt;会话ID&gt;</pre>

                <h4>9. 启用Windows Defender防火墙日志:</h4>
                <pre>Set-NetFirewallProfile -Profile Domain,Public,Private -LogAllowed True -LogBlocked True -LogMaxSizeKilobytes 32767</pre>
            </div>
        </div>

        <div class="footer">
            <p><strong>报表生成时间:</strong> {report_date}</p>
            <p><strong>报表位置:</strong> {output_path}</p>
            <p>本报表由 Windows Security Audit Tool (Python版) 自动生成</p>
            <p style="color:#e74c3c;margin-top:15px;"><strong>⚠️ 机密文档 - 请妥善保管</strong></p>
        </div>
    </div>
</body>
</html>
"""
    
    return html

def save_csv_data(failed_logins, lockouts, successful_logins, csv_folder):
    """保存CSV格式的详细数据"""
    import csv
    
    os.makedirs(csv_folder, exist_ok=True)
    
    # 保存失败登录
    if failed_logins:
        with open(os.path.join(csv_folder, 'FailedLogins.csv'), 'w', newline='', encoding='utf-8-sig') as f:
            writer = csv.DictWriter(f, fieldnames=['Time', 'User', 'SourceIP', 'LogonType', 'SubStatus'])
            writer.writeheader()
            writer.writerows(failed_logins)
    
    # 保存账户锁定
    if lockouts:
        with open(os.path.join(csv_folder, 'AccountLockouts.csv'), 'w', newline='', encoding='utf-8-sig') as f:
            writer = csv.DictWriter(f, fieldnames=['Time', 'LockedAccount', 'CallerComputer'])
            writer.writeheader()
            writer.writerows(lockouts)
    
    # 保存成功登录
    if successful_logins:
        with open(os.path.join(csv_folder, 'SuccessfulLogins.csv'), 'w', newline='', encoding='utf-8-sig') as f:
            writer = csv.DictWriter(f, fieldnames=['Time', 'User', 'SourceIP', 'LogonType'])
            writer.writeheader()
            writer.writerows(successful_logins)
    
    # 保存IP统计
    ip_stats, user_stats, hourly_stats = analyze_failed_logins(failed_logins)
    
    with open(os.path.join(csv_folder, 'IPStatistics.csv'), 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=['ip', 'count', 'first_time', 'last_time'])
        writer.writeheader()
        writer.writerows(ip_stats)
    
    with open(os.path.join(csv_folder, 'UserStatistics.csv'), 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=['user', 'count'])
        writer.writeheader()
        writer.writerows(user_stats)
    
    with open(os.path.join(csv_folder, 'HourlyStatistics.csv'), 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.DictWriter(f, fieldnames=['hour', 'count'])
        writer.writeheader()
        writer.writerows(hourly_stats)

def main():
    """主函数"""
    print("=" * 60)
    print("        Windows 安全审计报表生成工具 (Python版)")
    print("=" * 60)
    print()
    
    # 设置输出目录
    report_folder = r"C:\SecurityAudit\Reports"
    timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
    report_filename = f"SecurityReport_{timestamp}.html"
    report_path = os.path.join(report_folder, report_filename)
    
    # 创建报表目录
    os.makedirs(report_folder, exist_ok=True)
    print(f"✓ 已创建报表目录: {report_folder}")
    print(f"✓ 报表将保存至: {report_path}")
    print()
    
    # 收集数据
    failed_logins = get_failed_logins(1000)
    lockouts = get_account_lockouts(50)
    successful_logins = get_successful_logins(500)
    
    # 收集网络信息
    print("\n" + "="*60)
    print("开始网络异常检查...")
    print("="*60)
    
    network_data = {
        'adapters': get_network_adapters(),
        'ip_config': get_ip_configuration(),
        'routes': get_suspicious_routes(),
        'connections': get_active_connections(),
        'listeners': get_listening_processes(),
        'vpns': get_vpn_connections(),
        'virtual_adapters': get_virtual_adapters(),
        'suspicious_tasks': get_suspicious_tasks(),
        'arp_cache': get_arp_cache(),
        'local_accounts': get_local_accounts(),
        'rdp_settings': check_rdp_security_settings()
    }
    
    print(f"\n数据收集完成:")
    print(f"  - 登录失败事件: {len(failed_logins)} 条")
    print(f"  - 账户锁定事件: {len(lockouts)} 条")
    print(f"  - 成功登录事件: {len(successful_logins)} 条")
    print(f"  - 网络适配器: {len(network_data['adapters'])} 个")
    print(f"  - 虚拟适配器: {len(network_data['virtual_adapters'])} 个")
    print(f"  - 可疑路由: {len(network_data['routes'])} 条")
    print(f"  - 活动连接: {len(network_data['connections'])} 个")
    print(f"  - 监听端口: {len(network_data['listeners'])} 个")
    print(f"  - VPN连接: {len(network_data['vpns'])} 个")
    print(f"  - 可疑任务: {len(network_data['suspicious_tasks'])} 个")
    print(f"  - ARP缓存(192.168): {len(network_data['arp_cache'])} 条")
    print(f"  - 本地账户: {len(network_data['local_accounts'])} 个")
    
    rdp_settings = network_data['rdp_settings']
    print(f"\nRDP安全配置:")
    print(f"  - 远程桌面: {'已启用' if rdp_settings.get('rdp_enabled') else '已禁用'}")
    print(f"  - NLA(网络级别验证): {'已启用 ✓' if rdp_settings.get('nla_enabled') else '未启用 ✗'}")
    print(f"  - RDP端口: {rdp_settings.get('rdp_port', '未知')}")
    print(f"  - 强制微软账户: {'已启用 ✓' if rdp_settings.get('ms_account_only') else '未启用 ✗'}")
    print()
    
    # 生成HTML报表
    print("正在生成HTML报表...")
    html_content = generate_html_report(failed_logins, lockouts, successful_logins, network_data, report_path)
    
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write(html_content)
    
    print(f"✓ HTML报表已生成")
    
    # 保存CSV数据
    csv_folder = os.path.join(report_folder, f"CSV_{timestamp}")
    print(f"\n正在导出CSV数据...")
    save_csv_data(failed_logins, lockouts, successful_logins, csv_folder)
    print(f"✓ CSV数据已导出至: {csv_folder}")
    
    # 打开报表
    print("\n正在打开报表...")
    try:
        webbrowser.open(f"file:///{report_path}")
    except:
        print(f"无法自动打开浏览器,请手动打开: {report_path}")
    
    print("\n" + "=" * 60)
    print("               报表生成完成!")
    print("=" * 60)
    print(f"\n📄 报表文件: {report_path}")
    print(f"📊 CSV数据: {csv_folder}")
    print(f"\n⚠️  请立即采取安全措施!")
    print()

if __name__ == "__main__":
    main()
