// PEN Landing — Vulnerabilidades & Soluciones sections. // All evidence panes are now illustrative (not raw terminal output) so a // non-technical reader gets it at a glance. const { useState: useStateV, useEffect: useEffectV } = React; // ════════════════════════════════════════════════════════════════════ // Evidence renderers — one per attack // ════════════════════════════════════════════════════════════════════ function VulnEvidence({ example, severity }) { if (!example) return null; const wrap = (inner, cap) =>
{inner} {cap &&
{cap}
}
; switch (example.type) { case "email":return wrap(, example.caption); case "slides":return wrap(, example.caption); case "doors":return wrap(, example.caption); case "passwords":return wrap(, example.caption); case "network":return wrap(, example.caption); case "backup":return wrap(, example.caption); default:return null; } } // ── 1. Phishing email mock (kept, with highlight + caption) ────────── function EvEmail({ e }) { return (
De: {e.from} ⚠ dominio falso
Asunto: {e.subject}
{e.body.split("\n").map((l, i) =>
{l || "\u00A0"}
)}
▸ Remitente: no verificado ▸ Urgencia: sospechosa
); } // ── 2. Ransomware — auto-cycling 4-scene slideshow ─────────────────── function EvSlides() { const [idx, setIdx] = useStateV(0); useEffectV(() => { const t = setInterval(() => setIdx((i) => (i + 1) % 4), 2200); return () => clearInterval(t); }, []); const scenes = [ { tag: "08:42", title: "Llega un correo", body: }, { tag: "08:43", title: "Empleado abre el PDF", body: }, { tag: "03:00", title: "Cifrado en silencio", body: }, { tag: "08:00", title: "Pide rescate", body: }]; return (
{scenes.map((s, i) =>
{s.tag} {s.title}
{s.body}
)}
{scenes.map((_, i) => )}
); } function RansomScene1() { return (
Cliente Acmeayer
Factura · pago pendiente08:42
Newsletter sector08:30
📎 factura-2025-Q1.pdf
); } function RansomScene2() { return (
▸ malware.exe · ejecutando en segundo plano
); } function RansomScene3() { return (
{["clientes.db", "facturas.xlsx", "nominas.pdf", "contratos.zip", "fotos/", "backup.bak"].map((f, i) =>
{f} .lockbit
)}
cifrando · 73%
); } function RansomScene4() { return (
!
TUS ARCHIVOS ESTÁN CIFRADOS
Paga 2.4 BTC en 48 horas o todo se pierde.
47:59:23
); } // ── 3. RDP / SSH — door metaphor: open server vs closed server ─────── function EvDoors() { return (
TU SERVIDOR HOY
Puerta abierta
Cualquier bot encuentra tu IP y prueba a entrar 24/7.
▸ 1.847 intentos hoy
CON PEN
Acceso solo por VPN
Cerrado a internet. Solo entra tu equipo, autenticado y verificado.
▸ 0 expuestos
); } // ── 4. Passwords — leaked-password notification cards ──────────────── function EvPasswords() { const rows = [ { who: "director@", service: "LinkedIn", year: "2021", pwd: "Verano2018!", changed: false }, { who: "ana@", service: "Adobe", year: "2019", pwd: "ana1234", changed: false }, { who: "compras@", service: "Dropbox", year: "2022", pwd: "Compras2020", changed: false }]; return (
▸ Filtraciones públicas encontradas 3 / 12 cuentas
{rows.map((r, i) =>
{r.who}tuempresa.es
{r.service} · {r.year}
contraseña filtrada
{r.pwd.slice(0, 3)}{"●".repeat(Math.max(0, r.pwd.length - 3))}
⚠ sin cambiar
)}
▸ 0 cuentas con verificación en dos pasos
); } // ── 5. Network — before/after, all-flat vs segmented ───────────────── function EvNetwork() { return (
ANTES · TODO EN UNA RED
internet
router
{["Wifi invitados", "Cámaras", "Impresora", "Contabilidad", "Servidor ERP", "Nóminas"].map((d, i) =>
{d}
)}
⚠ 1 infectado = todos infectados
CON PEN · SEGMENTADO + FIREWALL
internet
FORTIGATE · firewall
PÚBLICA Wifi · Cámaras
OFICINA Impresoras · PCs
CRÍTICA ERP · Nóminas
✓ Cada zona aislada
); } // ── 6. Backup — bad vs good cycle ───────────────────────────────────── function EvBackup() { return (
SIN PEN
datos
backup
  • Backup en la misma red
  • Última prueba: hace 14 meses
  • Restaurar = no se sabe si funciona
CON PEN · 3-2-1 VERIFICADO
datos
copia · local
copia · externa
copia · cloud
  • 3 copias · 2 sitios · 1 fuera
  • Restauración probada cada 30 días
  • Recuperas tu negocio en horas, no semanas
); } // ════════════════════════════════════════════════════════════════════ // Helpers // ════════════════════════════════════════════════════════════════════ function sevClass(sev) { const s = (sev || "").toLowerCase(); if (s.startsWith("crít") || s === "critical") return "crit"; if (s === "alto" || s === "high") return "warn"; return "info"; } // ════════════════════════════════════════════════════════════════════ // SectionVuln // ════════════════════════════════════════════════════════════════════ function SectionVuln({ copy }) { return (
{copy.eyebrow}

{copy.title}

{copy.sub}

{copy.items.map((v, i) => { const sev = sevClass(v.severity); const flip = i % 2 === 1; return (
0{i + 1} ● {v.severity}
{v.tag}

{v.title}

{v.body}

{v.stat} {v.statLabel}
); })}
); } // ════════════════════════════════════════════════════════════════════ // SectionSoluciones — card now has 3 layers: plain → benefit → caso // ════════════════════════════════════════════════════════════════════ // ──────────────────────────────────────────────────────────────────── // Animated SVG illustrations for solution steps (vector schematics) // ──────────────────────────────────────────────────────────────────── function VisualFirewall() { return ( {/* Firewall barrier in center */} {/* Glowing shield indicators */} {/* Traffic flow particles */} ); } function VisualAgent() { return ( {/* Laptop Keyboard / Base */} {/* Laptop Screen */} {/* Shield inside Screen */} {/* Radar pulse lines from screen */} ); } function VisualRadar() { return ( {/* Radar rings */} {/* Crosshairs */} {/* Radar Sweep line */} {/* Blinking target nodes */} ); } function VisualPhishing() { return ( {/* Valid Card (Verified User) */} {/* Spoofed Card (Blocked Impostor) */} ); } function VisualVPN() { return ( {/* Remote Laptop Outline */} {/* Secure Enterprise Cloud Database */} {/* Tunnel Pipe line */} ); } function VisualBackup() { return ( {/* Main Server Cylinder (Center) */} {/* Backup Dest 1: Local Copy (Top Left) */} {/* Backup Dest 2: External Copy (Bottom Left) */} {/* Backup Dest 3: Cloud Copy (Right) */} {/* Sync path arrows */} ); } function SolucionVisual({ index }) { switch (index) { case 0: return ; case 1: return ; case 2: return ; case 3: return ; case 4: return ; case 5: return ; default: return null; } } // ════════════════════════════════════════════════════════════════════ // SectionSoluciones — card now has 3 layers: plain → benefit → caso // ════════════════════════════════════════════════════════════════════ function SectionSoluciones({ copy }) { const [activeIndex, setActiveIndex] = useStateV(0); const isEn = copy.eyebrow.toLowerCase().includes("what"); const stepLabels = isEn ? ["Network", "Endpoints", "Support", "Identity", "Access", "Backups"] : ["Red", "Equipos", "Soporte", "Identidad", "Accesos", "Respaldos"]; const handlePrev = () => { setActiveIndex((prev) => (prev > 0 ? prev - 1 : 5)); }; const handleNext = () => { setActiveIndex((prev) => (prev < 5 ? prev + 1 : 0)); }; const activeItem = copy.items[activeIndex]; return (
{copy.eyebrow}

{copy.title}

{copy.sub}

{/* 1. Stepper / Sequence Timeline */}
{copy.items.map((item, idx) => { const isActive = idx === activeIndex; const isCompleted = idx < activeIndex; return (
setActiveIndex(idx)} >
{idx + 1}
{stepLabels[idx]}
); })}
{/* 2. Main Showcase Panel */}
{/* Left Column: Core Identity, Benefit, and Tech Features */}
{activeItem.cat}
0{activeIndex + 1} / 06

{activeItem.name}

{activeItem.model}

{activeItem.plain}

{activeItem.benefit}
CARACTERÍSTICAS CLAVE
    {activeItem.features.map((f, j) => (
  • {f}
  • ))}
{/* Right Column: Illustration, Case Report & Specs */}
CASO REAL / IMPACTO

"{activeItem.caso}"

RENDIMIENTO {activeItem.spec.l1}
INTEGRACIÓN {activeItem.spec.l2}
{/* 3. Navigation Controls */}
{copy.items.map((_, idx) => ( setActiveIndex(idx)} /> ))}
{/* Partners Strip */}
{copy.partnerStrip.label}
{(copy.partnerStrip.items || (copy.partnerStrip.groups ? copy.partnerStrip.groups.flatMap(g => g.items || []) : [])).map((p, i) => {p} )}
); } Object.assign(window, { SectionVuln, SectionSoluciones });