source: templates/dashboard.html@ e4c61dd

Last change on this file since e4c61dd was 640ed89, checked in by istevanoska <ilinastevanoska@…>, 7 months ago

Initial commit

  • Property mode set to 100644
File size: 22.4 KB
Line 
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Sysmon Monitoring Dashboard</title>
7 <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
8 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
9 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
10 <style>
11 body {
12 background-color: #f5f7fa;
13 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
14 }
15 .stat-card {
16 transition: all 0.3s;
17 border: none;
18 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
19 }
20 .stat-card:hover {
21 transform: translateY(-5px);
22 box-shadow: 0 4px 8px rgba(0,0,0,0.15);
23 }
24 .computer-card {
25 cursor: pointer;
26 transition: all 0.3s;
27 border-left: 4px solid #28a745;
28 }
29 .computer-card:hover {
30 background-color: #f8f9fa;
31 transform: translateX(5px);
32 }
33 .computer-card.offline {
34 border-left-color: #dc3545;
35 opacity: 0.7;
36 }
37 .event-badge {
38 font-size: 0.75rem;
39 padding: 0.25rem 0.5rem;
40 }
41 .event-row {
42 transition: background-color 0.2s;
43 }
44 .event-row:hover {
45 background-color: #f0f0f0;
46 }
47 .modal-xl {
48 max-width: 95%;
49 }
50 .event-type-1 { color: #007bff; } /* Process */
51 .event-type-3 { color: #17a2b8; } /* Network */
52 .event-type-11 { color: #ffc107; } /* File Create */
53 .event-type-22 { color: #28a745; } /* DNS */
54 .event-type-23 { color: #dc3545; } /* File Delete */
55 .filter-btn {
56 margin: 2px;
57 font-size: 0.85rem;
58 }
59 .details-cell {
60 max-width: 300px;
61 overflow: hidden;
62 text-overflow: ellipsis;
63 white-space: nowrap;
64 }
65 .status-online { color: #28a745; font-weight: bold; }
66 .status-offline { color: #dc3545; }
67 .loading {
68 text-align: center;
69 padding: 20px;
70 color: #666;
71 }
72 .event-details-popup {
73 font-size: 0.9rem;
74 background: #f8f9fa;
75 padding: 10px;
76 border-radius: 5px;
77 margin-top: 10px;
78 }
79 .quick-stats {
80 background: white;
81 padding: 15px;
82 border-radius: 8px;
83 margin-bottom: 20px;
84 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
85 }
86 .quick-stat-item {
87 display: inline-block;
88 margin-right: 30px;
89 }
90 .quick-stat-item i {
91 margin-right: 5px;
92 }
93 </style>
94</head>
95<body>
96 <nav class="navbar navbar-dark bg-dark">
97 <div class="container-fluid">
98 <span class="navbar-brand mb-0 h1">
99 <i class="fas fa-shield-alt"></i> Sysmon Monitoring Dashboard
100 </span>
101 <span class="navbar-text" id="currentTime"></span>
102 </div>
103 </nav>
104
105 <div class="container-fluid mt-4">
106 <!-- Stats Cards -->
107 <div class="row mb-4">
108 <div class="col-md-3">
109 <div class="card stat-card bg-primary text-white">
110 <div class="card-body">
111 <h6 class="card-title"><i class="fas fa-calendar-check"></i> Total Events</h6>
112 <h2 id="totalEvents">0</h2>
113 <p class="card-text mb-0">All collected events</p>
114 </div>
115 </div>
116 </div>
117 <div class="col-md-3">
118 <div class="card stat-card bg-success text-white">
119 <div class="card-body">
120 <h6 class="card-title"><i class="fas fa-laptop"></i> Computers</h6>
121 <h2><span id="onlineComputers">0</span>/<span id="totalComputers">0</span></h2>
122 <p class="card-text mb-0">Online/Total</p>
123 </div>
124 </div>
125 </div>
126 <div class="col-md-3">
127 <div class="card stat-card bg-warning text-white">
128 <div class="card-body">
129 <h6 class="card-title"><i class="fas fa-exclamation-triangle"></i> Active Threats</h6>
130 <h2 id="activeThreats">0</h2>
131 <p class="card-text mb-0">Require attention</p>
132 </div>
133 </div>
134 </div>
135 <div class="col-md-3">
136 <div class="card stat-card bg-info text-white">
137 <div class="card-body">
138 <h6 class="card-title"><i class="fas fa-sync-alt"></i> Last Update</h6>
139 <h5 id="lastUpdate">Just now</h5>
140 <p class="card-text mb-0">Auto-refresh: 30s</p>
141 </div>
142 </div>
143 </div>
144 </div>
145
146 <!-- Computers List -->
147 <div class="row">
148 <div class="col-md-12">
149 <div class="card">
150 <div class="card-header bg-dark text-white">
151 <h5 class="mb-0"><i class="fas fa-desktop"></i> Connected Computers - Click for Details</h5>
152 </div>
153 <div class="card-body">
154 <div id="computersList" class="row">
155 <div class="col-12 loading">
156 <i class="fas fa-spinner fa-spin"></i> Loading computers...
157 </div>
158 </div>
159 </div>
160 </div>
161 </div>
162 </div>
163 </div>
164
165 <!-- Computer Details Modal -->
166 <div class="modal fade" id="computerDetailsModal" tabindex="-1">
167 <div class="modal-dialog modal-xl">
168 <div class="modal-content">
169 <div class="modal-header bg-dark text-white">
170 <h5 class="modal-title">
171 <i class="fas fa-laptop"></i>
172 <span id="modalComputerName">Computer Details</span>
173 </h5>
174 <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
175 </div>
176 <div class="modal-body">
177 <!-- Quick Stats -->
178 <div class="quick-stats">
179 <div class="row">
180 <div class="col-md-3 quick-stat-item">
181 <i class="fas fa-list text-primary"></i>
182 <strong>Total Events:</strong> <span id="detailTotalEvents">0</span>
183 </div>
184 <div class="col-md-3 quick-stat-item">
185 <i class="fas fa-network-wired text-info"></i>
186 <strong>Network:</strong> <span id="detailNetworkEvents">0</span>
187 </div>
188 <div class="col-md-3 quick-stat-item">
189 <i class="fas fa-globe text-success"></i>
190 <strong>DNS:</strong> <span id="detailDnsEvents">0</span>
191 </div>
192 <div class="col-md-3 quick-stat-item">
193 <i class="fas fa-file text-warning"></i>
194 <strong>Files:</strong> <span id="detailFileEvents">0</span>
195 </div>
196 </div>
197 </div>
198
199 <!-- Event Type Filters -->
200 <div class="mb-3">
201 <strong>Filter by Event Type:</strong><br>
202 <button class="btn btn-sm btn-outline-primary filter-btn" onclick="filterEvents('all')">
203 <i class="fas fa-list"></i> All
204 </button>
205 <button class="btn btn-sm btn-outline-info filter-btn" onclick="filterEvents('Process Creation')">
206 <i class="fas fa-cogs"></i> Process Creation
207 </button>
208 <button class="btn btn-sm btn-outline-success filter-btn" onclick="filterEvents('DNS Query')">
209 <i class="fas fa-globe"></i> DNS Queries
210 </button>
211 <button class="btn btn-sm btn-outline-warning filter-btn" onclick="filterEvents('Network Connection')">
212 <i class="fas fa-network-wired"></i> Network
213 </button>
214 <button class="btn btn-sm btn-outline-danger filter-btn" onclick="filterEvents('File Create')">
215 <i class="fas fa-file-medical"></i> File Create
216 </button>
217 <button class="btn btn-sm btn-outline-secondary filter-btn" onclick="filterEvents('File Delete')">
218 <i class="fas fa-trash"></i> File Delete
219 </button>
220 </div>
221
222 <!-- Events Table -->
223 <div class="table-responsive">
224 <table class="table table-sm table-hover">
225 <thead class="table-dark">
226 <tr>
227 <th width="100">Time</th>
228 <th width="150">Event Type</th>
229 <th width="150">Process</th>
230 <th>Details</th>
231 <th width="80">Action</th>
232 </tr>
233 </thead>
234 <tbody id="computerEventsTable">
235 <tr>
236 <td colspan="5" class="text-center">
237 <i class="fas fa-spinner fa-spin"></i> Loading events...
238 </td>
239 </tr>
240 </tbody>
241 </table>
242 </div>
243 </div>
244 </div>
245 </div>
246 </div>
247
248 <!-- Event Details Modal -->
249 <div class="modal fade" id="eventDetailsModal" tabindex="-1">
250 <div class="modal-dialog modal-lg">
251 <div class="modal-content">
252 <div class="modal-header bg-info text-white">
253 <h5 class="modal-title"><i class="fas fa-info-circle"></i> Event Details</h5>
254 <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
255 </div>
256 <div class="modal-body">
257 <div id="eventDetailsContent"></div>
258 </div>
259 </div>
260 </div>
261 </div>
262
263 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
264 <script>
265 let allEvents = [];
266 let currentFilter = 'all';
267 let selectedComputer = '';
268
269 function updateTime() {
270 $('#currentTime').text(new Date().toLocaleString());
271 }
272
273 function loadStats() {
274 $.get('/api/stats', function(data) {
275 $('#totalEvents').text(data.total_events.toLocaleString());
276 $('#totalComputers').text(data.total_computers);
277 $('#onlineComputers').text(data.online_computers);
278 $('#activeThreats').text(data.active_threats);
279 $('#lastUpdate').text(new Date().toLocaleTimeString());
280 });
281 }
282
283 function loadComputers() {
284 $.get('/api/computers', function(data) {
285 let html = '';
286
287 if (data.computers.length === 0) {
288 html = '<div class="col-12 text-center text-muted">No computers connected yet</div>';
289 } else {
290 data.computers.forEach(comp => {
291 const statusClass = comp.status === 'online' ? 'status-online' : 'status-offline';
292 const statusIcon = comp.status === 'online' ? 'fa-check-circle' : 'fa-times-circle';
293 const cardClass = comp.status === 'online' ? '' : 'offline';
294 const lastSeen = new Date(comp.last_seen).toLocaleString();
295
296 html += `
297 <div class="col-md-4 mb-3">
298 <div class="card computer-card ${cardClass}" onclick="showComputerDetails('${comp.computer_name}')">
299 <div class="card-body">
300 <h5 class="card-title">
301 <i class="fas fa-laptop"></i> ${comp.computer_name}
302 </h5>
303 <p class="mb-1">
304 <i class="fas fa-user"></i> <strong>User:</strong> ${comp.user || 'N/A'}
305 </p>
306 <p class="mb-1">
307 <i class="fas fa-network-wired"></i> <strong>IP:</strong> ${comp.ip_address || 'N/A'}
308 </p>
309 <p class="mb-1">
310 <i class="fas fa-desktop"></i> <strong>OS:</strong> ${comp.os || 'N/A'}
311 </p>
312 <p class="mb-1">
313 <i class="fas ${statusIcon} ${statusClass}"></i>
314 <strong>Status:</strong>
315 <span class="${statusClass}">${comp.status.toUpperCase()}</span>
316 </p>
317 <p class="mb-1">
318 <i class="fas fa-calendar"></i> <strong>Last Seen:</strong> ${lastSeen}
319 </p>
320 <p class="mb-0">
321 <span class="badge bg-primary">${comp.event_count || 0} events</span>
322 </p>
323 </div>
324 </div>
325 </div>
326 `;
327 });
328 }
329
330 $('#computersList').html(html);
331 });
332 }
333
334 function showComputerDetails(computerName) {
335 selectedComputer = computerName;
336 $('#modalComputerName').text(computerName);
337 $('#computerDetailsModal').modal('show');
338 loadComputerEvents(computerName);
339 }
340
341 function loadComputerEvents(computerName) {
342 $('#computerEventsTable').html('<tr><td colspan="5" class="text-center"><i class="fas fa-spinner fa-spin"></i> Loading events...</td></tr>');
343
344 $.get('/api/events?limit=200', function(data) {
345 // Filter events for this computer
346 allEvents = data.events.filter(e => e.computer === computerName);
347
348 // Calculate stats
349 const totalEvents = allEvents.length;
350 const networkEvents = allEvents.filter(e => e.event_type === 'Network Connection').length;
351 const dnsEvents = allEvents.filter(e => e.event_type === 'DNS Query').length;
352 const fileEvents = allEvents.filter(e => e.event_type === 'File Create' || e.event_type === 'File Delete').length;
353
354 $('#detailTotalEvents').text(totalEvents);
355 $('#detailNetworkEvents').text(networkEvents);
356 $('#detailDnsEvents').text(dnsEvents);
357 $('#detailFileEvents').text(fileEvents);
358
359 // Display events
360 filterEvents('all');
361 });
362 }
363
364 function filterEvents(eventType) {
365 currentFilter = eventType;
366
367 let filteredEvents = allEvents;
368 if (eventType !== 'all') {
369 filteredEvents = allEvents.filter(e => e.event_type === eventType);
370 }
371
372 if (filteredEvents.length === 0) {
373 $('#computerEventsTable').html('<tr><td colspan="5" class="text-center text-muted">No events found</td></tr>');
374 return;
375 }
376
377 let html = '';
378 filteredEvents.forEach(event => {
379 const time = new Date(event.timestamp).toLocaleTimeString();
380 const processName = event.process_name ? event.process_name.split('\\').pop() : 'N/A';
381
382 let details = '';
383 let icon = 'fa-list';
384
385 // Determine details based on event type
386 if (event.event_type === 'DNS Query') {
387 details = `<i class="fas fa-globe text-success"></i> <strong>${event.dns_query || 'N/A'}</strong>`;
388 if (event.dns_results) {
389 details += ` → ${event.dns_results}`;
390 }
391 icon = 'fa-globe';
392 } else if (event.event_type === 'Network Connection') {
393 details = `<i class="fas fa-network-wired text-info"></i> ${event.dest_ip || 'N/A'}:${event.dest_port || '?'}`;
394 if (event.source_ip) {
395 details = `${event.source_ip} → ` + details;
396 }
397 icon = 'fa-network-wired';
398 } else if (event.event_type === 'File Create') {
399 const fileName = event.file_path ? event.file_path.split('\\').pop() : 'N/A';
400 details = `<i class="fas fa-file-medical text-warning"></i> <strong>${fileName}</strong>`;
401 icon = 'fa-file-medical';
402 } else if (event.event_type === 'File Delete') {
403 const fileName = event.file_path ? event.file_path.split('\\').pop() : 'N/A';
404 details = `<i class="fas fa-trash text-danger"></i> <strong>${fileName}</strong>`;
405 icon = 'fa-trash';
406 } else if (event.event_type === 'Process Creation') {
407 details = `<i class="fas fa-cogs text-primary"></i> ${event.command_line || processName}`;
408 icon = 'fa-cogs';
409 } else if (event.registry_key) {
410 const regKey = event.registry_key.split('\\').pop();
411 details = `<i class="fas fa-edit text-secondary"></i> Registry: ${regKey}`;
412 icon = 'fa-edit';
413 } else {
414 details = event.description || 'N/A';
415 }
416
417 html += `
418 <tr class="event-row">
419 <td><small>${time}</small></td>
420 <td>
421 <i class="fas ${icon}"></i>
422 <span class="badge event-badge bg-secondary">${event.event_type}</span>
423 </td>
424 <td><small>${processName}</small></td>
425 <td class="details-cell">${details}</td>
426 <td>
427 <button class="btn btn-sm btn-outline-info" onclick='showEventDetails(${JSON.stringify(event).replace(/'/g, "&apos;")})'>
428 <i class="fas fa-eye"></i>
429 </button>
430 </td>
431 </tr>
432 `;
433 });
434
435 $('#computerEventsTable').html(html);
436 }
437
438 function showEventDetails(event) {
439 let html = '<div class="event-details-popup">';
440
441 html += `<h6><i class="fas fa-info-circle"></i> Event ID: ${event.event_id} - ${event.event_type}</h6>`;
442 html += `<p><strong>Time:</strong> ${new Date(event.timestamp).toLocaleString()}</p>`;
443 html += `<p><strong>Computer:</strong> ${event.computer}</p>`;
444
445 if (event.process_name) {
446 html += `<p><strong>Process:</strong> ${event.process_name}</p>`;
447 }
448
449 if (event.command_line) {
450 html += `<p><strong>Command Line:</strong><br><code style="font-size: 0.85rem;">${event.command_line}</code></p>`;
451 }
452
453 if (event.user) {
454 html += `<p><strong>User:</strong> ${event.user}</p>`;
455 }
456
457 if (event.parent_process) {
458 html += `<p><strong>Parent Process:</strong> ${event.parent_process}</p>`;
459 }
460
461 if (event.dns_query) {
462 html += `<p><strong>DNS Query:</strong> ${event.dns_query}</p>`;
463 if (event.dns_results) {
464 html += `<p><strong>DNS Results:</strong> ${event.dns_results}</p>`;
465 }
466 }
467
468 if (event.source_ip || event.dest_ip) {
469 html += `<p><strong>Network:</strong> ${event.source_ip || 'N/A'} → ${event.dest_ip || 'N/A'}:${event.dest_port || '?'}</p>`;
470 }
471
472 if (event.file_path) {
473 html += `<p><strong>File Path:</strong><br><code style="font-size: 0.85rem;">${event.file_path}</code></p>`;
474 }
475
476 if (event.hash) {
477 html += `<p><strong>Hash:</strong><br><code style="font-size: 0.75rem;">${event.hash}</code></p>`;
478 }
479
480 if (event.registry_key) {
481 html += `<p><strong>Registry Key:</strong><br><code style="font-size: 0.85rem;">${event.registry_key}</code></p>`;
482 if (event.registry_value) {
483 html += `<p><strong>Registry Value:</strong> ${event.registry_value}</p>`;
484 }
485 }
486
487 if (event.description) {
488 html += `<p><strong>Description:</strong> ${event.description}</p>`;
489 }
490
491 html += '</div>';
492
493 $('#eventDetailsContent').html(html);
494 $('#eventDetailsModal').modal('show');
495 }
496
497 // Initial load
498 $(document).ready(function() {
499 updateTime();
500 loadStats();
501 loadComputers();
502
503 // Auto-refresh
504 setInterval(function() {
505 loadStats();
506 loadComputers();
507 if (selectedComputer) {
508 loadComputerEvents(selectedComputer);
509 }
510 }, 30000);
511
512 setInterval(updateTime, 1000);
513 });
514 </script>
515</body>
516</html>
Note: See TracBrowser for help on using the repository browser.