| <!DOCTYPE html> |
| <html lang="zh-CN"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>BAS AI Hacker演练报告</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .attack-card { |
| transition: all 0.3s ease; |
| transform-origin: center; |
| height: 120px; |
| overflow: hidden; |
| } |
| .attack-card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| .attack-card.active { |
| border-left-width: 4px; |
| transform: translateY(-5px); |
| } |
| .timeline-connector { |
| position: relative; |
| height: 4px; |
| background: linear-gradient(90deg, #e5e7eb, #9ca3af); |
| } |
| .timeline-connector::after { |
| content: ''; |
| position: absolute; |
| top: -4px; |
| width: 12px; |
| height: 12px; |
| border-radius: 50%; |
| background-color: #3b82f6; |
| transform: translateX(-50%); |
| } |
| .severity-badge { |
| font-size: 0.65rem; |
| padding: 0.15rem 0.4rem; |
| } |
| .severity-critical { |
| background-color: #fee2e2; |
| color: #dc2626; |
| } |
| .severity-high { |
| background-color: #fef3c7; |
| color: #d97706; |
| } |
| .severity-emergency { |
| background-color: #ffedd5; |
| color: #ea580c; |
| } |
| .defense-badge { |
| font-size: 0.7rem; |
| padding: 0.2rem 0.5rem; |
| } |
| .animate-pulse-slow { |
| animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
| } |
| @keyframes pulse { |
| 0%, 100% { |
| opacity: 1; |
| } |
| 50% { |
| opacity: 0.5; |
| } |
| } |
| .arrow { |
| display: inline-block; |
| width: 24px; |
| height: 24px; |
| text-align: center; |
| line-height: 24px; |
| color: #9ca3af; |
| } |
| .attacker-node { |
| background-color: #fee2e2; |
| border-left: 4px solid #dc2626; |
| height: 120px; |
| } |
| .attack-flow-container { |
| width: 100%; |
| overflow-x: auto; |
| padding-bottom: 1.5rem; |
| } |
| .attack-flow-container .flex { |
| min-width: max-content; |
| } |
| .attack-behavior { |
| display: -webkit-box; |
| -webkit-line-clamp: 2; |
| -webkit-box-orient: vertical; |
| overflow: hidden; |
| text-overflow: ellipsis; |
| font-size: 0.7rem; |
| line-height: 1.2; |
| color: #4b5563; |
| } |
| .stage-badge { |
| font-size: 0.6rem; |
| padding: 0.15rem 0.4rem; |
| background-color: #f3f4f6; |
| color: #6b7280; |
| } |
| .scroll-container { |
| scrollbar-width: thin; |
| scrollbar-color: #d1d5db #f3f4f6; |
| } |
| .scroll-container::-webkit-scrollbar { |
| height: 6px; |
| } |
| .scroll-container::-webkit-scrollbar-track { |
| background: #f3f4f6; |
| border-radius: 10px; |
| } |
| .scroll-container::-webkit-scrollbar-thumb { |
| background-color: #d1d5db; |
| border-radius: 10px; |
| } |
| .forensic-item { |
| position: relative; |
| padding-left: 1.5rem; |
| margin-bottom: 0.75rem; |
| } |
| .forensic-item:before { |
| content: ""; |
| position: absolute; |
| left: 0.5rem; |
| top: 0.5rem; |
| width: 6px; |
| height: 6px; |
| border-radius: 50%; |
| background-color: #3b82f6; |
| } |
| .forensic-item:after { |
| content: ""; |
| position: absolute; |
| left: 0.5rem; |
| top: 1.1rem; |
| bottom: -0.5rem; |
| width: 2px; |
| background-color: #e5e7eb; |
| } |
| .forensic-item:last-child:after { |
| display: none; |
| } |
| .alert-icon { |
| width: 2rem; |
| height: 2rem; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| border-radius: 50%; |
| flex-shrink: 0; |
| } |
| .alert-critical { |
| background-color: #fee2e2; |
| color: #dc2626; |
| } |
| .alert-high { |
| background-color: #fef3c7; |
| color: #d97706; |
| } |
| .alert-emergency { |
| background-color: #ffedd5; |
| color: #ea580c; |
| } |
| .timeline-marker { |
| width: 1rem; |
| height: 1rem; |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| position: relative; |
| z-index: 1; |
| } |
| .timeline-marker:after { |
| content: ""; |
| position: absolute; |
| left: 50%; |
| top: 50%; |
| transform: translate(-50%, -50%); |
| width: 0.5rem; |
| height: 0.5rem; |
| border-radius: 50%; |
| background-color: white; |
| } |
| .section-divider { |
| position: relative; |
| margin: 1.5rem 0; |
| } |
| .section-divider:before { |
| content: ""; |
| position: absolute; |
| left: 0; |
| right: 0; |
| top: 50%; |
| height: 1px; |
| background-color: #e5e7eb; |
| } |
| .section-divider span { |
| position: relative; |
| padding: 0 0.5rem; |
| background-color: white; |
| z-index: 1; |
| font-size: 0.75rem; |
| color: #6b7280; |
| } |
| .status-badge { |
| font-size: 0.6rem; |
| padding: 0.15rem 0.4rem; |
| border-radius: 4px; |
| margin-right: 0.25rem; |
| } |
| .intercepted { |
| background-color: #dcfce7; |
| color: #166534; |
| } |
| .not-intercepted { |
| background-color: #fee2e2; |
| color: #991b1b; |
| } |
| .alerted { |
| background-color: #fef3c7; |
| color: #92400e; |
| } |
| .not-alerted { |
| background-color: #e5e7eb; |
| color: #4b5563; |
| } |
| .status-tag { |
| position: absolute; |
| top: -8px; |
| right: 8px; |
| font-size: 0.6rem; |
| padding: 0.15rem 0.4rem; |
| border-radius: 4px; |
| z-index: 1; |
| box-shadow: 0 1px 2px rgba(0,0,0,0.1); |
| } |
| .status-tag-intercepted { |
| background-color: #dcfce7; |
| color: #166534; |
| border: 1px solid #bbf7d0; |
| } |
| .status-tag-not-intercepted { |
| background-color: #fee2e2; |
| color: #991b1b; |
| border: 1px solid #fecaca; |
| } |
| .status-tag-alerted { |
| background-color: #fef3c7; |
| color: #92400e; |
| border: 1px solid #fde68a; |
| } |
| .status-tag-not-alerted { |
| background-color: #e5e7eb; |
| color: #4b5563; |
| border: 1px solid #d1d5db; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50"> |
| <div class="container mx-auto px-4 py-8 max-w-full"> |
| <div class="text-center mb-10"> |
| <h1 class="text-3xl font-bold text-gray-800 mb-2">BAS AI Hacker演练报告</h1> |
| <p class="text-gray-600 max-w-3xl mx-auto">演练时间:2025-04-23 10:11 ~ 2025-04-23 11:10</p> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden mb-8"> |
| <div class="border-b border-gray-200 px-6 py-4 bg-gray-50"> |
| <h3 class="font-semibold text-gray-800">防御检测概览</h3> |
| </div> |
| <div id="defense-summary" class="p-6"> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> |
| <div class="bg-blue-50 p-4 rounded-lg"> |
| <div class="flex items-center"> |
| <div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center mr-4"> |
| <i class="fas fa-shield-alt text-blue-500"></i> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium text-gray-800">拦截率</h4> |
| <p class="text-2xl font-bold text-blue-600">90%</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-yellow-50 p-4 rounded-lg"> |
| <div class="flex items-center"> |
| <div class="w-12 h-12 rounded-full bg-yellow-100 flex items-center justify-center mr-4"> |
| <i class="fas fa-bell text-yellow-500"></i> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium text-gray-800">告警率</h4> |
| <p class="text-2xl font-bold text-yellow-600">80%</p> |
| </div> |
| </div> |
| </div> |
| <div class="bg-green-50 p-4 rounded-lg"> |
| <div class="flex items-center"> |
| <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mr-4"> |
| <i class="fas fa-search text-green-500"></i> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium text-gray-800">溯源率</h4> |
| <p class="text-2xl font-bold text-green-600">70%</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-sm border border-gray-200 p-6 mb-8"> |
| <div class="flex justify-between items-center mb-6"> |
| <div> |
| <h2 class="text-xl font-semibold text-gray-800">攻击流程时间线</h2> |
| <p class="text-gray-500 text-sm">点击任意攻击阶段查看详细取证证据</p> |
| </div> |
| <div class="flex items-center"> |
| <span class="text-xs text-gray-500 mr-2">滚动查看完整时间线</span> |
| <i class="fas fa-chevron-right text-gray-400 text-xs"></i> |
| </div> |
| </div> |
|
|
| <div class="relative"> |
| <div class="attack-flow-container scroll-container"> |
| <div class="flex space-x-4 items-center pb-2"> |
| |
| <div class="attack-card w-48 flex-shrink-0 bg-white rounded-lg border border-gray-200 overflow-hidden cursor-pointer transition-all duration-300 attacker-node"> |
| <div class="p-4"> |
| <div class="flex items-center justify-between mb-2"> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full bg-red-100 text-red-600 flex items-center justify-center mr-2"> |
| <i class="fas fa-user-secret"></i> |
| </div> |
| <span class="text-xs font-semibold text-gray-500">攻击源</span> |
| </div> |
| </div> |
| <h3 class="font-semibold text-gray-800 text-sm mb-1">BAS AI Hacker</h3> |
| <p class="text-xs text-gray-500">发起攻击</p> |
| </div> |
| </div> |
| |
| <div class="arrow"> |
| <i class="fas fa-arrow-right"></i> |
| </div> |
| |
| |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden"> |
| <div class="border-b border-gray-200 px-6 py-4 bg-gray-50"> |
| <h3 class="font-semibold text-gray-800">攻击阶段取证详情</h3> |
| </div> |
| <div id="attack-details" class="p-6"> |
| <div class="text-center py-12"> |
| <div class="mx-auto w-16 h-16 rounded-full bg-blue-50 flex items-center justify-center mb-4"> |
| <i class="fas fa-mouse-pointer text-blue-500 text-2xl"></i> |
| </div> |
| <h4 class="text-lg font-medium text-gray-700 mb-2">选择攻击阶段</h4> |
| <p class="text-gray-500 max-w-md mx-auto">点击时间线上的任意攻击卡片查看攻击行为和触发防御的详细取证信息</p> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| // Attack steps data in Chinese |
| const attackSteps = [ |
| { |
| id: 1, |
| title: "钓鱼邮件投递", |
| icon: "envelope", |
| color: "bg-red-100 text-red-600", |
| behavior: "伪造的'拥抱AI变革'通知邮件,包含伪装为files.zip的恶意文件,使用社会工程学诱导用户点击", |
| defenses: "邮件安全网关", |
| intercepted: true, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "critical", |
| message: "检测到伪造发件人 | 发件人: itsupport@fakecompany[.]com → 收件人: victim@corp.com | 包含恶意附件 (SHA256: a1b2c3...) | 识别为Emotet钓鱼模板" |
| } |
| ], |
| forensic: [ |
| "发件人IP: 192.168.1.45 (保加利亚)", |
| "附件SHA256: a1b2c3d4e5f6...", |
| "邮件头显示DKIM验证失败", |
| "匹配已知Emotet模板(相似度90%)" |
| ] |
| }, |
| { |
| id: 2, |
| title: "木马执行", |
| icon: "bug", |
| color: "bg-yellow-100 text-yellow-600", |
| behavior: "受害者下载恶意文件触发PowerShell脚本,下载Cobalt Strike DLL并注入到合法进程中", |
| defenses: "终端检测与响应(EDR)", |
| intercepted: false, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "high", |
| message: "可疑进程注入 | 进程: C:\\Windows\\System32\\explorer.exe → 加载模块: a09xdf.dll | DLL签名无效且匹配已知Cobalt Strike签名" |
| } |
| ], |
| forensic: [ |
| "进程树: files.zip → powershell.exe → explorer.exe", |
| "DLL内存分配模式匹配Cobalt Strike", |
| "网络连接尝试到185.123.32.1", |
| "注册表键修改: HKLM\\Software\\Microsoft\\Windows" |
| ] |
| }, |
| { |
| id: 3, |
| title: "C2通信建立", |
| icon: "satellite-dish", |
| color: "bg-green-100 text-green-600", |
| behavior: "通过CDN域名(api.cloudfront[.]com)进行HTTPS心跳通信,部署反向SSH隧道到内部跳板服务器", |
| defenses: "网络流量分析(NTA)", |
| intercepted: true, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "emergency", |
| message: "异常出站连接 | 目标IP: 54.231.1.1 (AWS新加坡) | 协议: HTTPS | 异常证书(CN=*.cloudfront[.]com但由通配符Let's Encrypt证书签发)" |
| } |
| ], |
| forensic: [ |
| "C2域名: api.cloudfront[.]com (解析到54.231.1.1)", |
| "HTTPS流量模式: 每17秒5KB", |
| "证书签发者: Let's Encrypt(对CDN不常见)", |
| "SSH隧道建立到10.8.8.12(内部跳板服务器)" |
| ] |
| }, |
| { |
| id: 4, |
| title: "凭证窃取", |
| icon: "user-secret", |
| color: "bg-blue-100 text-blue-600", |
| behavior: "使用Mimikatz提取Chrome浏览器cookie并伪造User-Agent(同步受害者浏览器指纹)", |
| defenses: "用户行为分析(UEBA)", |
| intercepted: false, |
| alerted: false, |
| alerts: [ |
| { |
| severity: "high", |
| message: "异常浏览器会话 | 用户: Victim_Account | 源IP: 172.16.1.23 → 设备指纹改变(新的VM特征/QEMU虚拟GPU)" |
| } |
| ], |
| forensic: [ |
| "内存中检测到Mimikatz进程(伪装为svchost.exe)", |
| "访问了Chrome cookie数据库", |
| "User-Agent更改为匹配受害者原始浏览器", |
| "来自172.16.1.23的新登录会话带有VM指纹" |
| ] |
| }, |
| { |
| id: 5, |
| title: "云文档渗透", |
| icon: "cloud", |
| color: "bg-purple-100 text-purple-600", |
| behavior: "劫持的Yuque API Token用于访问'生产环境操作手册',提取嵌入的SSH私钥(Base64编码)", |
| defenses: "数据防泄漏(DLP)", |
| intercepted: true, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "critical", |
| message: "敏感数据访问 | 用户: Victim_Account | 操作: 下载文档ID: YUQUE-1234 | 内容匹配关键词: 'prod_ssh_private_key'" |
| } |
| ], |
| forensic: [ |
| "API调用到yuque.com/v2/api/documents/YUQUE-1234", |
| "文档包含Base64编码的SSH密钥", |
| "密钥属于dba_admin@10.8.8.88", |
| "异常访问时间: 当地时间02:37 AM" |
| ] |
| }, |
| { |
| id: 6, |
| title: "生产环境入侵", |
| icon: "server", |
| color: "bg-pink-100 text-pink-600", |
| behavior: "使用来自跳板服务器的SSH证书登录MySQL数据库服务器(IP: 10.8.8.88, 账号: dba_admin)", |
| defenses: "主机入侵检测(HIDS)", |
| intercepted: false, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "emergency", |
| message: "异常时间SSH登录 | 账号: dba_admin | 源IP: 10.8.8.12 (测试环境跳板服务器) | 操作: 执行SHOW DATABASES" |
| } |
| ], |
| forensic: [ |
| "SSH登录时间: 03:12 AM 来自10.8.8.12", |
| "执行命令: SHOW DATABASES, SELECT * FROM users", |
| "会话时长: 8分钟23秒", |
| "异常查询模式(扫描所有表)" |
| ] |
| }, |
| { |
| id: 7, |
| title: "数据外泄", |
| icon: "file-export", |
| color: "bg-indigo-100 text-indigo-600", |
| behavior: "压缩并加密客户数据(文件名: taobaodata.tar.gz.enc)通过DNS隧道传输到alibaba-bas.com", |
| defenses: "全流量威胁分析", |
| intercepted: true, |
| alerted: true, |
| alerts: [ |
| { |
| severity: "critical", |
| message: "异常数据传输 | 协议: DNS TXT记录 | 目标域名: xyz.attacker[.]com | 数据量: 142MB (超过阈值500%)" |
| } |
| ], |
| forensic: [ |
| "创建数据文件: /tmp/taobaodata.tar.gz.enc", |
| "DNS查询到xyz.attacker[.]com (TXT记录)", |
| "数据传输速率: 每次查询18.5KB", |
| "总外泄数据: 142MB 通过8,234次DNS请求" |
| ] |
| } |
| ]; |
| |
| // Render attack cards |
| const timelineContainer = document.querySelector('.attack-flow-container .flex'); |
| |
| attackSteps.forEach((step, index) => { |
| const card = document.createElement('div'); |
| card.className = `attack-card w-48 flex-shrink-0 bg-white rounded-lg border border-gray-200 overflow-hidden cursor-pointer transition-all duration-300 relative ${index === 0 ? 'active border-l-4 border-red-500' : ''}`; |
| |
| // Add status tags for intercepted and alerted |
| const statusTags = ` |
| <div class="status-tag ${step.intercepted ? 'status-tag-intercepted' : 'status-tag-not-intercepted'}"> |
| ${step.intercepted ? '已拦截' : '未拦截'} |
| </div> |
| <div class="status-tag ${step.alerted ? 'status-tag-alerted' : 'status-tag-not-alerted'}" style="right: 8px; top: 14px;"> |
| ${step.alerted ? '已告警' : '未告警'} |
| </div> |
| `; |
| |
| card.innerHTML = ` |
| ${statusTags} |
| <div class="p-4"> |
| <div class="flex items-center justify-between mb-1"> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full ${step.color} flex items-center justify-center mr-2"> |
| <i class="fas fa-${step.icon}"></i> |
| </div> |
| <span class="stage-badge rounded-full">阶段 ${step.id}</span> |
| </div> |
| <span class="text-xs ${step.alerts[0].severity === 'critical' ? 'text-red-500' : step.alerts[0].severity === 'high' ? 'text-yellow-500' : 'text-orange-500'}"> |
| <i class="fas fa-${step.alerts[0].severity === 'critical' ? 'exclamation-triangle' : step.alerts[0].severity === 'high' ? 'exclamation-circle' : 'exclamation'}"></i> |
| </span> |
| </div> |
| <h3 class="font-semibold text-gray-800 text-sm mb-1">${step.title}</h3> |
| <p class="attack-behavior text-xs">${step.behavior}</p> |
| <div class="mt-2 flex justify-between items-center"> |
| <div class="flex"> |
| <span class="status-badge ${step.intercepted ? 'intercepted' : 'not-intercepted'}"> |
| ${step.intercepted ? '已拦截' : '未拦截'} |
| </span> |
| <span class="status-badge ${step.alerted ? 'alerted' : 'not-alerted'}"> |
| ${step.alerted ? '已告警' : '未告警'} |
| </span> |
| </div> |
| <span class="text-xs text-gray-500">${step.defenses}</span> |
| </div> |
| </div> |
| `; |
| |
| card.addEventListener('click', () => { |
| // Update active card |
| document.querySelectorAll('.attack-card').forEach(c => c.classList.remove('active', 'border-l-4', 'border-red-500', 'border-yellow-500', 'border-green-500', 'border-blue-500', 'border-purple-500', 'border-pink-500', 'border-indigo-500')); |
| card.classList.add('active', 'border-l-4'); |
| |
| // Add specific border color |
| if (step.color.includes('red')) card.classList.add('border-red-500'); |
| else if (step.color.includes('yellow')) card.classList.add('border-yellow-500'); |
| else if (step.color.includes('green')) card.classList.add('border-green-500'); |
| else if (step.color.includes('blue')) card.classList.add('border-blue-500'); |
| else if (step.color.includes('purple')) card.classList.add('border-purple-500'); |
| else if (step.color.includes('pink')) card.classList.add('border-pink-500'); |
| else if (step.color.includes('indigo')) card.classList.add('border-indigo-500'); |
| |
| // Update attack details |
| const detailsContainer = document.getElementById('attack-details'); |
| detailsContainer.innerHTML = ` |
| <div> |
| |
| <div class="flex items-center mb-6"> |
| <div class="w-12 h-12 rounded-full ${step.color} flex items-center justify-center mr-4"> |
| <i class="fas fa-${step.icon} text-xl"></i> |
| </div> |
| <div> |
| <h3 class="text-xl font-semibold text-gray-800">${step.title}</h3> |
| <p class="text-sm text-gray-500">攻击阶段 ${step.id} | ${step.id < 10 ? '0' + step.id : step.id}:00</p> |
| </div> |
| </div> |
| |
| |
| <div class="flex mb-6 space-x-4"> |
| <div class="flex-1 bg-white border ${step.intercepted ? 'border-green-200 bg-green-50' : 'border-red-200 bg-red-50'} rounded-lg p-4"> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full ${step.intercepted ? 'bg-green-100 text-green-600' : 'bg-red-100 text-red-600'} flex items-center justify-center mr-3"> |
| <i class="fas fa-${step.intercepted ? 'shield-alt' : 'shield-virus'}"></i> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium text-gray-700">拦截状态</h4> |
| <p class="text-sm ${step.intercepted ? 'text-green-600' : 'text-red-600'} font-medium">${step.intercepted ? '已成功拦截' : '未能拦截'}</p> |
| </div> |
| </div> |
| </div> |
| <div class="flex-1 bg-white border ${step.alerted ? 'border-yellow-200 bg-yellow-50' : 'border-gray-200 bg-gray-50'} rounded-lg p-4"> |
| <div class="flex items-center"> |
| <div class="w-8 h-8 rounded-full ${step.alerted ? 'bg-yellow-100 text-yellow-600' : 'bg-gray-100 text-gray-600'} flex items-center justify-center mr-3"> |
| <i class="fas fa-${step.alerted ? 'bell' : 'bell-slash'}"></i> |
| </div> |
| <div> |
| <h4 class="text-sm font-medium text-gray-700">告警状态</h4> |
| <p class="text-sm ${step.alerted ? 'text-yellow-600' : 'text-gray-600'} font-medium">${step.alerted ? '已触发告警' : '未触发告警'}</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-8"> |
| <div class="flex items-center mb-3"> |
| <div class="w-6 h-6 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center mr-2"> |
| <i class="fas fa-bolt text-xs"></i> |
| </div> |
| <h4 class="font-medium text-gray-700">攻击行为</h4> |
| </div> |
| <div class="bg-gray-50 p-4 rounded-lg text-sm text-gray-700 border border-gray-200"> |
| <div class="flex"> |
| <div class="timeline-marker ${step.color} mr-3 flex-shrink-0"> |
| </div> |
| <div>${step.behavior}</div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-8"> |
| <div class="flex items-center mb-3"> |
| <div class="w-6 h-6 rounded-full bg-green-100 text-green-600 flex items-center justify-center mr-2"> |
| <i class="fas fa-shield-alt text-xs"></i> |
| </div> |
| <h4 class="font-medium text-gray-700">触发防御</h4> |
| </div> |
| <div class="flex items-center bg-gray-50 p-4 rounded-lg border border-gray-200"> |
| <span class="defense-badge bg-white text-gray-800 rounded-full border border-gray-300 mr-3">${step.defenses}</span> |
| <span class="text-sm text-gray-600">检测到攻击行为并触发防御机制</span> |
| </div> |
| </div> |
| |
| |
| <div class="mb-8"> |
| <div class="flex items-center mb-3"> |
| <div class="w-6 h-6 rounded-full bg-red-100 text-red-600 flex items-center justify-center mr-2"> |
| <i class="fas fa-exclamation-triangle text-xs"></i> |
| </div> |
| <h4 class="font-medium text-gray-700">安全告警</h4> |
| </div> |
| <div class="space-y-3"> |
| ${step.alerts.map(alert => ` |
| <div class="p-4 rounded-lg border ${alert.severity === 'critical' ? 'border-red-200 bg-red-50' : alert.severity === 'high' ? 'border-yellow-200 bg-yellow-50' : 'border-orange-200 bg-orange-50'}"> |
| <div class="flex items-start"> |
| <div class="alert-icon ${alert.severity === 'critical' ? 'alert-critical' : alert.severity === 'high' ? 'alert-high' : 'alert-emergency'} mr-3"> |
| <i class="fas fa-${alert.severity === 'critical' ? 'exclamation-triangle' : alert.severity === 'high' ? 'exclamation-circle' : 'exclamation'} text-sm"></i> |
| </div> |
| <div> |
| <div class="text-sm font-medium text-gray-800 mb-1">${alert.severity === 'critical' ? '严重告警' : alert.severity === 'high' ? '高危告警' : '紧急告警'}</div> |
| <div class="text-xs text-gray-600">${alert.message}</div> |
| </div> |
| </div> |
| </div> |
| `).join('')} |
| </div> |
| </div> |
| |
| |
| <div> |
| <div class="flex items-center mb-3"> |
| <div class="w-6 h-6 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center mr-2"> |
| <i class="fas fa-search text-xs"></i> |
| </div> |
| <h4 class="font-medium text-gray-700">取证证据</h4> |
| </div> |
| <div class="bg-white border border-gray-200 rounded-lg overflow-hidden"> |
| <div class="p-4"> |
| ${step.forensic.map((item, idx) => ` |
| <div class="forensic-item"> |
| <div class="text-sm text-gray-700 pl-2">${item}</div> |
| </div> |
| `).join('')} |
| </div> |
| </div> |
| </div> |
| </div> |
| `; |
| }); |
| |
| // Add card and arrow to timeline |
| timelineContainer.appendChild(card); |
| |
| // Add arrow after each card except the last one |
| if (index < attackSteps.length - 1) { |
| const arrow = document.createElement('div'); |
| arrow.className = 'arrow'; |
| arrow.innerHTML = '<i class="fas fa-arrow-right"></i>'; |
| timelineContainer.appendChild(arrow); |
| } |
| }); |
| |
| // Auto-select first card on load |
| document.querySelectorAll('.attack-card')[1].click(); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=capta1n/bas10" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |