espilon-source/tools/C3PO/templates/honeypot.html
Eun0us 79c2a4d4bf c3po: full server rewrite with modular routes and honeypot dashboard
Replace monolithic CLI and web server with route-based Flask API.
New routes: api_commands, api_build, api_can, api_monitor, api_ota,
api_tunnel. Add honeypot security dashboard with real-time SSE,
MITRE ATT&CK mapping, kill chain analysis.

New TUI with commander/help modules. Add session management,
tunnel proxy core, CAN bus data store. Docker support.
2026-02-28 20:12:27 +01:00

252 lines
14 KiB
HTML

{% extends "base.html" %}
{% block title %}Honeypot - ESPILON{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ url_for('honeypot.static', filename='hp/css/honeypot.css') }}">
{% endblock %}
{% block content %}
<div class="page hp-page">
<!-- Toast Container (HP's own toast system) -->
<div class="toast-container" id="toast-container"></div>
<!-- Sidebar Overlay (mobile) -->
<div class="sidebar-overlay" id="sidebar-overlay" data-action="toggle-sidebar"></div>
<!-- Alert Banner -->
<div class="alert-banner" id="alert-banner" data-action="scroll-alerts" role="alert">
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" transform="scale(0.7) translate(1,1)"/><line x1="8" y1="7" x2="8" y2="10"/><circle cx="8" cy="13" r="0.5"/></svg>
<span class="alert-banner-text" id="alert-banner-text">ALERTS ACTIVE</span>
<span class="alert-banner-count" id="alert-banner-count">0</span>
<button class="alert-banner-dismiss" data-action="dismiss-banner">&times;</button>
</div>
<!-- HP Header (KPIs + Controls) -->
<header class="hp-header">
<div class="hp-header-kpis">
<div class="hp-header-kpi">
<span class="hp-header-kpi-val text-accent" id="kpi-events">0</span>
<span class="hp-header-kpi-label">Events</span>
</div>
<div class="hp-header-kpi">
<span class="hp-header-kpi-val text-crit" id="kpi-critical">0</span>
<span class="hp-header-kpi-label">Critical</span>
</div>
<div class="hp-header-kpi">
<span class="hp-header-kpi-val" style="color:var(--warn)" id="kpi-attackers">0</span>
<span class="hp-header-kpi-label">Attackers</span>
</div>
<div class="hp-header-kpi">
<span class="hp-header-kpi-val" style="color:var(--warn)" id="kpi-alerts">0</span>
<span class="hp-header-kpi-label">Alerts</span>
</div>
</div>
<div class="hp-header-controls">
<select class="hp-select" id="device-select">
<option value="">All Devices</option>
</select>
<button class="icon-btn" id="sound-btn" data-action="toggle-sound" title="Toggle alert sounds">
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 5L6 9H2v6h4l5 4V5z" transform="scale(0.8)"/></svg>
</button>
<button class="icon-btn" id="notif-btn" data-action="toggle-notif" title="Toggle browser notifications" style="opacity:0.4">
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9" transform="scale(0.58) translate(0,2)"/><path d="M13.73 21a2 2 0 01-3.46 0" transform="scale(0.58) translate(0,2)"/></svg>
</button>
<select class="hp-select" id="sse-sev-filter" title="SSE minimum severity" style="width:auto;min-width:70px;font-size:11px;padding:2px 6px">
<option value="LOW">All</option>
<option value="MEDIUM" selected>Med+</option>
<option value="HIGH">High+</option>
<option value="CRITICAL">Crit</option>
</select>
<div class="conn-indicator">
<span class="conn-dot" id="conn-dot"></span>
<span class="conn-label" id="conn-label">SSE</span>
</div>
</div>
</header>
<!-- Sub-Nav Bar (6 tabs) -->
<nav class="hp-nav">
<div class="hp-nav-tabs" id="nav-tabs">
<button class="nav-btn active" data-action="tab" data-tab="overview" id="tab-overview">Overview</button>
<button class="nav-btn" data-action="tab" data-tab="timeline" id="tab-timeline">Events <span class="nav-badge" id="nav-badge-events" style="display:none">0</span></button>
<button class="nav-btn" data-action="tab" data-tab="sessions" id="tab-sessions">Sessions</button>
<button class="nav-btn" data-action="tab" data-tab="credentials" id="tab-credentials">Credentials</button>
<button class="nav-btn" data-action="tab" data-tab="killchain" id="tab-killchain">Kill Chain</button>
<button class="nav-btn" data-action="tab" data-tab="mitre" id="tab-mitre">MITRE</button>
</div>
<button class="icon-btn hp-nav-hamburger" id="nav-hamburger" data-action="toggle-nav" aria-label="Toggle navigation">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="5" x2="13" y2="5"/><line x1="3" y1="8" x2="13" y2="8"/><line x1="3" y1="11" x2="13" y2="11"/></svg>
</button>
<div class="hp-nav-actions">
<button class="btn btn-success btn-sm" data-action="start-all">Start All</button>
<button class="btn btn-danger btn-sm" data-action="stop-all">Stop All</button>
<button class="btn btn-sm" data-action="refresh-status" title="Refresh">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 11-2.12-9.36L23 10"/></svg>
</button>
<button class="icon-btn" data-action="toggle-sidebar" title="Toggle sidebar" id="sidebar-toggle-btn" style="display:none">
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="10" height="12" rx="1"/><line x1="7" y1="3" x2="7" y2="15"/></svg>
</button>
</div>
</nav>
<!-- Main Content -->
<div class="hp-layout">
<div class="hp-main">
<!-- Search Bar (visible on Events tab) -->
<div class="hp-search-bar" id="search-bar">
<svg class="hp-search-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<div class="hp-search-wrap">
<input class="hp-search-input" id="search-input" type="text" placeholder="Search events... (/ to focus)">
<button class="hp-search-clear" id="search-clear" aria-label="Clear search">&times;</button>
</div>
<button class="btn btn-sm" id="filter-toggle" data-action="toggle-filters">Filters</button>
</div>
<!-- Filter Panel -->
<div class="filter-panel" id="filter-panel">
<select class="hp-select" id="f-type">
<option value="">All Types</option>
<option>WIFI_DEAUTH</option><option>WIFI_PROBE</option><option>WIFI_EVIL_TWIN</option>
<option>WIFI_BEACON_FLOOD</option><option>WIFI_EAPOL</option><option>ARP_SPOOF</option>
<option>PORT_SCAN</option><option>ICMP_SWEEP</option><option>SYN_FLOOD</option>
<option>UDP_FLOOD</option><option>SVC_CONNECT</option><option>SVC_AUTH_ATTEMPT</option>
<option>SVC_COMMAND</option><option>SVC_HTTP_REQUEST</option><option>SVC_MQTT_MSG</option>
</select>
<select class="hp-select" id="f-sev">
<option value="">All Severity</option>
<option>LOW</option><option>MEDIUM</option><option>HIGH</option><option>CRITICAL</option>
</select>
<select class="hp-select" id="f-service">
<option value="">All Services</option>
<option>telnet</option><option>ssh</option><option>ftp</option><option>http</option>
<option>mqtt</option><option>dns</option><option>snmp</option><option>tftp</option>
<option>coap</option><option>redis</option><option>rtsp</option><option>mysql</option>
<option>modbus</option><option>upnp</option><option>sip</option>
</select>
<input class="hp-input" id="f-ip" type="text" placeholder="Source IP" style="width:9rem">
</div>
<!-- Main List -->
<div class="hp-main-content" id="main-list"></div>
</div>
<!-- Right Sidebar -->
<div class="hp-sidebar" id="sidebar">
<div class="sb-section">
<div class="sb-header" data-action="toggle-section">
<span>Severity</span>
<svg class="sb-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
</div>
<div class="sb-body" id="sev-stats"></div>
</div>
<div class="sb-section">
<div class="sb-header" data-action="toggle-section">
<span>Layers</span>
<svg class="sb-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
</div>
<div class="sb-body"><div class="layer-grid" id="layer-stats"></div></div>
</div>
<div class="sb-section">
<div class="sb-header" data-action="toggle-section">
<span>Top Attackers</span>
<svg class="sb-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
</div>
<div class="sb-body sb-body-scroll" id="attackers-list"></div>
</div>
<div class="sb-section" id="alerts-panel">
<div class="sb-header" data-action="toggle-section">
<span>Alerts <span id="alert-badge" class="nav-badge" style="display:none">0</span></span>
<svg class="sb-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
</div>
<div class="sb-body sb-body-scroll-sm" id="alerts-list"></div>
</div>
<div class="sb-section">
<div class="sb-header" data-action="toggle-section">
<span>Commands</span>
<svg class="sb-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"/></svg>
</div>
<div class="sb-body sb-body-scroll-sm" id="cmd-history"></div>
</div>
<div class="sb-section">
<div class="sb-header">
<span>Export</span>
<div style="display:flex;gap:4px">
<button class="btn btn-sm" data-action="export-csv">CSV</button>
<button class="btn btn-sm" data-action="export-json">JSON</button>
</div>
</div>
</div>
</div>
</div>
<!-- HP Status Footer (inline, not fixed) -->
<div class="hp-statusbar">
<div class="hp-statusbar-left">
<span class="conn-dot" id="status-conn-dot"></span>
<span id="status-conn-text">Disconnected</span>
<span class="hp-statusbar-sep">|</span>
<span id="status-refresh">--</span>
<span class="hp-statusbar-sep">|</span>
<span id="status-device">No device</span>
</div>
<div class="hp-statusbar-right">
<span id="status-rate">0 evt/min</span>
<span class="hp-statusbar-sep">|</span>
<span id="status-db-count">0 stored</span>
</div>
</div>
<!-- Detail Panel (slide-out) -->
<div class="detail-panel" id="detail-panel">
<div class="detail-hdr">
<h3>Event Detail</h3>
<button class="detail-close" data-action="close-detail" aria-label="Close detail panel">&times;</button>
</div>
<div class="detail-body" id="detail-body"></div>
</div>
<!-- Attacker Modal -->
<div class="modal-overlay" id="attacker-modal" role="dialog" aria-modal="true">
<div class="modal-content">
<div class="modal-hdr">
<h2 id="modal-title">Attacker Profile</h2>
<button class="modal-close" data-action="close-modal" aria-label="Close modal">&times;</button>
</div>
<div class="modal-body" id="modal-body"></div>
</div>
</div>
<!-- Session Replay Modal -->
<div class="replay-overlay" id="replay-modal" role="dialog" aria-modal="true">
<div class="replay-content">
<div class="replay-hdr">
<div class="replay-hdr-info">
<h3 id="replay-title">Session Replay</h3>
<span id="replay-meta"></span>
</div>
<button class="replay-close" data-action="close-replay" aria-label="Close replay">&times;</button>
</div>
<div class="replay-controls">
<button class="replay-btn" id="replay-play-btn" data-action="replay-play">Play</button>
<button class="replay-btn" data-action="replay-step">Step</button>
<button class="replay-btn" data-action="replay-reset">Reset</button>
<select class="replay-speed" id="replay-speed">
<option value="500">0.5x</option>
<option value="250" selected>1x</option>
<option value="100">2x</option>
<option value="50">5x</option>
</select>
<div class="replay-progress" data-action="replay-seek">
<div class="replay-progress-fill" id="replay-progress"></div>
</div>
<span class="replay-counter" id="replay-counter">0/0</span>
</div>
<div class="replay-terminal" id="replay-terminal"></div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script type="module" src="{{ url_for('honeypot.static', filename='hp/js/app.js') }}"></script>
{% endblock %}