source: server_fix.py@ 505f39a

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

Initial commit

  • Property mode set to 100644
File size: 31.2 KB
Line 
1"""
2FIXED SYSMON SERVER - Corrected API endpoints and database
3"""
4
5from flask import Flask, request, jsonify, render_template, send_from_directory
6import sqlite3
7import json
8from datetime import datetime, timedelta
9import threading
10import time
11from collections import defaultdict
12import os
13import re
14
15app = Flask(__name__)
16
17def init_database():
18 """Inicializiraј ja bazata so site polinja"""
19 conn = sqlite3.connect('sysmon_server.db', check_same_thread=False)
20 cursor = conn.cursor()
21
22 # KREIRAJ NOVA BAZA - DELETE OLD ONE FIRST
23 cursor.execute("DROP TABLE IF EXISTS sysmon_events")
24 cursor.execute("DROP TABLE IF EXISTS windows_events")
25 cursor.execute("DROP TABLE IF EXISTS system_info")
26 cursor.execute("DROP TABLE IF EXISTS processes")
27 cursor.execute("DROP TABLE IF EXISTS threats")
28 cursor.execute("DROP TABLE IF EXISTS computers")
29
30 # Kreiraј tabela za eventi so site polinja
31 cursor.execute('''
32 CREATE TABLE sysmon_events (
33 id INTEGER PRIMARY KEY AUTOINCREMENT,
34 event_id INTEGER,
35 event_type TEXT,
36 timestamp TEXT,
37 computer TEXT,
38
39 -- Process Creation (Event ID 1)
40 process_name TEXT,
41 process_path TEXT,
42 command_line TEXT,
43 process_user TEXT,
44 parent_process TEXT,
45 parent_command TEXT,
46 current_directory TEXT,
47 hashes TEXT,
48
49 -- Network Connection (Event ID 3)
50 source_ip TEXT,
51 source_port INTEGER,
52 dest_ip TEXT,
53 dest_port INTEGER,
54 protocol TEXT,
55 network_initiated TEXT,
56
57 -- DNS Query (Event ID 22)
58 dns_query TEXT,
59 dns_results TEXT,
60 dns_status TEXT,
61 dns_process TEXT,
62
63 -- File Create (Event ID 11)
64 file_path TEXT,
65 file_hash TEXT,
66
67 -- DLL Loaded (Event ID 7)
68 dll_loaded TEXT,
69 dll_signed TEXT,
70
71 -- Raw data
72 raw_data TEXT,
73 received_at TEXT
74 )
75 ''')
76
77 # Kreiraј tabela za Windows events
78 cursor.execute('''
79 CREATE TABLE windows_events (
80 id INTEGER PRIMARY KEY AUTOINCREMENT,
81 event_id INTEGER,
82 log_name TEXT,
83 source TEXT,
84 timestamp TEXT,
85 computer TEXT,
86 level TEXT,
87 message TEXT,
88 user TEXT,
89 process_name TEXT,
90 process_path TEXT,
91 file_created TEXT,
92 file_deleted TEXT,
93 file_modified TEXT,
94 service_name TEXT,
95 service_action TEXT,
96 login_user TEXT,
97 login_ip TEXT,
98 login_type TEXT,
99 raw_data TEXT,
100 received_at TEXT
101 )
102 ''')
103
104 # Kreiraј tabela za system info
105 cursor.execute('''
106 CREATE TABLE system_info (
107 id INTEGER PRIMARY KEY AUTOINCREMENT,
108 computer TEXT,
109 user TEXT,
110 os TEXT,
111 cpu_usage REAL,
112 ram_usage REAL,
113 disk_usage REAL,
114 timestamp TEXT,
115 received_at TEXT
116 )
117 ''')
118
119 # Kreiraј tabela za procesi SO EXE_PATH
120 cursor.execute('''
121 CREATE TABLE processes (
122 id INTEGER PRIMARY KEY AUTOINCREMENT,
123 pid INTEGER,
124 name TEXT,
125 user TEXT,
126 cpu_percent REAL,
127 memory_mb REAL,
128 cmdline TEXT,
129 exe_path TEXT,
130 timestamp TEXT,
131 computer TEXT,
132 received_at TEXT
133 )
134 ''')
135
136 # Kreiraј tabela za threats
137 cursor.execute('''
138 CREATE TABLE threats (
139 id INTEGER PRIMARY KEY AUTOINCREMENT,
140 computer TEXT,
141 threat_type TEXT,
142 level TEXT,
143 description TEXT,
144 details TEXT,
145 timestamp TEXT,
146 resolved BOOLEAN DEFAULT 0
147 )
148 ''')
149
150 # Kreiraј tabela za computers
151 cursor.execute('''
152 CREATE TABLE computers (
153 id INTEGER PRIMARY KEY AUTOINCREMENT,
154 computer_name TEXT UNIQUE,
155 user TEXT,
156 ip_address TEXT,
157 os TEXT,
158 last_seen TEXT,
159 total_events INTEGER DEFAULT 0,
160 status TEXT DEFAULT 'online'
161 )
162 ''')
163
164 # Kreiraј indeksi
165 cursor.execute('CREATE INDEX idx_computer ON sysmon_events(computer)')
166 cursor.execute('CREATE INDEX idx_event_type ON sysmon_events(event_type)')
167 cursor.execute('CREATE INDEX idx_timestamp ON sysmon_events(timestamp)')
168 cursor.execute('CREATE INDEX idx_dns_query ON sysmon_events(dns_query)')
169 cursor.execute('CREATE INDEX idx_process_name ON sysmon_events(process_name)')
170
171 conn.commit()
172 conn.close()
173 print("✅ Database initialized successfully with ALL columns")
174
175def get_db_connection():
176 """Vrati database connection"""
177 conn = sqlite3.connect('sysmon_server.db', check_same_thread=False)
178 conn.row_factory = sqlite3.Row
179 return conn
180
181# Site drugi funkcii se isti kako predhodno...
182# (kopiraј gi site funkcii od prethodniot kod)
183
184# FIXED API ENDPOINTS - koristi gi tochnite endpoints
185@app.route('/api/detailed_events')
186def api_detailed_events():
187 """Vrati detalni eventi"""
188 conn = get_db_connection()
189 cursor = conn.cursor()
190
191 limit = request.args.get('limit', 50, type=int)
192
193 cursor.execute('SELECT * FROM sysmon_events ORDER BY timestamp DESC LIMIT ?', (limit,))
194 events = []
195
196 for row in cursor.fetchall():
197 event = dict(row)
198 event['display_text'] = format_event_for_display(row)
199 events.append(event)
200
201 conn.close()
202
203 return jsonify({
204 "events": events,
205 "count": len(events)
206 })
207
208@app.route('/api/dns_queries')
209def api_dns_queries():
210 """Vrati DNS queries"""
211 conn = get_db_connection()
212 cursor = conn.cursor()
213
214 limit = request.args.get('limit', 100, type=int)
215
216 cursor.execute('''
217 SELECT timestamp, computer, dns_query, dns_results, dns_process
218 FROM sysmon_events
219 WHERE dns_query != '' AND dns_query IS NOT NULL
220 ORDER BY timestamp DESC
221 LIMIT ?
222 ''', (limit,))
223
224 dns_queries = []
225 for row in cursor.fetchall():
226 query = dict(row)
227 dns_queries.append(query)
228
229 conn.close()
230
231 return jsonify({
232 "dns_queries": dns_queries,
233 "count": len(dns_queries)
234 })
235
236@app.route('/api/process_creations')
237def api_process_creations():
238 """Vrati process creations"""
239 conn = get_db_connection()
240 cursor = conn.cursor()
241
242 limit = request.args.get('limit', 100, type=int)
243
244 cursor.execute('''
245 SELECT timestamp, computer, process_name, command_line, process_user
246 FROM sysmon_events
247 WHERE event_id = 1 AND process_name != ''
248 ORDER BY timestamp DESC
249 LIMIT ?
250 ''', (limit,))
251
252 processes = []
253 for row in cursor.fetchall():
254 proc = dict(row)
255 processes.append(proc)
256
257 conn.close()
258
259 return jsonify({
260 "process_creations": processes,
261 "count": len(processes)
262 })
263
264@app.route('/api/network_connections')
265def api_network_connections():
266 """Vrati network connections"""
267 conn = get_db_connection()
268 cursor = conn.cursor()
269
270 limit = request.args.get('limit', 100, type=int)
271
272 cursor.execute('''
273 SELECT timestamp, computer, process_name, dest_ip, dest_port
274 FROM sysmon_events
275 WHERE event_id = 3 AND dest_ip != ''
276 ORDER BY timestamp DESC
277 LIMIT ?
278 ''', (limit,))
279
280 connections = []
281 for row in cursor.fetchall():
282 conn_data = dict(row)
283 connections.append(conn_data)
284
285 conn.close()
286
287 return jsonify({
288 "network_connections": connections,
289 "count": len(connections)
290 })
291
292@app.route('/api/stats')
293def api_stats():
294 """Vrati statistika"""
295 conn = get_db_connection()
296 cursor = conn.cursor()
297
298 cursor.execute("SELECT COUNT(*) FROM sysmon_events")
299 total_events = cursor.fetchone()[0]
300
301 cursor.execute("SELECT COUNT(DISTINCT computer) FROM sysmon_events")
302 total_computers = cursor.fetchone()[0]
303
304 cursor.execute("SELECT COUNT(*) FROM computers WHERE status = 'online'")
305 online_computers = cursor.fetchone()[0]
306
307 cursor.execute("SELECT COUNT(*) FROM sysmon_events WHERE dns_query != ''")
308 total_dns = cursor.fetchone()[0]
309
310 cursor.execute("SELECT COUNT(*) FROM sysmon_events WHERE event_id = 1")
311 total_processes = cursor.fetchone()[0]
312
313 cursor.execute("SELECT COUNT(*) FROM sysmon_events WHERE event_id = 3")
314 total_connections = cursor.fetchone()[0]
315
316 conn.close()
317
318 return jsonify({
319 "total_events": total_events,
320 "total_computers": total_computers,
321 "online_computers": online_computers,
322 "dns_queries": total_dns,
323 "process_creations": total_processes,
324 "network_connections": total_connections,
325 "timestamp": datetime.now().isoformat()
326 })
327
328@app.route('/api/computers')
329def api_computers():
330 """Return list of computers"""
331 conn = get_db_connection()
332 cursor = conn.cursor()
333
334 cursor.execute('''
335 SELECT c.*,
336 COUNT(e.id) as event_count,
337 MAX(e.timestamp) as last_event
338 FROM computers c
339 LEFT JOIN sysmon_events e ON c.computer_name = e.computer
340 GROUP BY c.computer_name
341 ORDER BY c.last_seen DESC
342 ''')
343
344 computers = []
345 for row in cursor.fetchall():
346 computer = dict(row)
347 computers.append(computer)
348
349 conn.close()
350
351 return jsonify({
352 "computers": computers,
353 "count": len(computers)
354 })
355
356@app.route('/api/dns')
357def api_dns():
358 """Return DNS queries"""
359 conn = get_db_connection()
360 cursor = conn.cursor()
361
362 limit = request.args.get('limit', 100, type=int)
363
364 cursor.execute('''
365 SELECT timestamp, computer, dns_query, dns_results, process_name
366 FROM sysmon_events
367 WHERE dns_query IS NOT NULL AND dns_query != ''
368 ORDER BY timestamp DESC
369 LIMIT ?
370 ''', (limit,))
371
372 dns_queries = [dict(row) for row in cursor.fetchall()]
373
374 # Get top queried domains
375 cursor.execute('''
376 SELECT dns_query, COUNT(*) as query_count
377 FROM sysmon_events
378 WHERE dns_query IS NOT NULL AND dns_query != ''
379 GROUP BY dns_query
380 ORDER BY query_count DESC
381 LIMIT 10
382 ''')
383
384 top_domains = [dict(row) for row in cursor.fetchall()]
385
386 conn.close()
387
388 return jsonify({
389 "dns_queries": dns_queries,
390 "top_domains": top_domains,
391 "count": len(dns_queries)
392 })
393
394@app.route('/ping', methods=['GET'])
395def ping():
396 """Ping endpoint"""
397 return jsonify({
398 "message": "pong",
399 "status": "ok",
400 "server": "Fixed Sysmon Server",
401 "time": datetime.now().isoformat()
402 }), 200
403
404@app.route('/')
405def dashboard():
406 """Dashboard so popraveni API endpoints"""
407 return render_template('dashboard_fixed.html')
408
409# HTML template so popraveni API calls
410dashboard_fixed_html = '''<!DOCTYPE html>
411<html lang="en">
412<head>
413 <meta charset="UTF-8">
414 <meta name="viewport" content="width=device-width, initial-scale=1.0">
415 <title>Sysmon Dashboard - Fixed</title>
416 <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
417 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
418 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
419 <style>
420 body { background-color: #f5f7fa; }
421 .card { margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,.05); }
422 .stat-card { border-left: 4px solid; }
423 .event-item { padding: 10px; border-left: 3px solid; margin-bottom: 5px; background: white; }
424 .event-dns { border-left-color: #3498db; }
425 .event-process { border-left-color: #2ecc71; }
426 .event-network { border-left-color: #e74c3c; }
427 .tab-content { padding-top: 20px; }
428 </style>
429</head>
430<body>
431 <nav class="navbar navbar-dark bg-dark">
432 <div class="container-fluid">
433 <span class="navbar-brand">
434 <i class="fas fa-shield-alt"></i> Sysmon Dashboard
435 </span>
436 <span class="navbar-text" id="currentTime"></span>
437 </div>
438 </nav>
439
440 <div class="container-fluid mt-3">
441 <!-- Stats -->
442 <div class="row mb-3">
443 <div class="col-md-2">
444 <div class="card stat-card border-left-primary">
445 <div class="card-body">
446 <h6>Total Events</h6>
447 <h3 id="totalEvents">0</h3>
448 </div>
449 </div>
450 </div>
451 <div class="col-md-2">
452 <div class="card stat-card border-left-success">
453 <div class="card-body">
454 <h6>Computers</h6>
455 <h3><span id="onlineComputers">0</span>/<span id="totalComputers">0</span></h3>
456 </div>
457 </div>
458 </div>
459 <div class="col-md-2">
460 <div class="card stat-card border-left-info">
461 <div class="card-body">
462 <h6>DNS Queries</h6>
463 <h3 id="dnsCount">0</h3>
464 </div>
465 </div>
466 </div>
467 <div class="col-md-2">
468 <div class="card stat-card border-left-warning">
469 <div class="card-body">
470 <h6>Processes</h6>
471 <h3 id="processCount">0</h3>
472 </div>
473 </div>
474 </div>
475 <div class="col-md-2">
476 <div class="card stat-card border-left-danger">
477 <div class="card-body">
478 <h6>Network</h6>
479 <h3 id="networkCount">0</h3>
480 </div>
481 </div>
482 </div>
483 <div class="col-md-2">
484 <div class="card stat-card border-left-secondary">
485 <div class="card-body">
486 <h6>Last Update</h6>
487 <h6 id="lastUpdate">Just now</h6>
488 </div>
489 </div>
490 </div>
491 </div>
492
493 <!-- Tabs -->
494 <ul class="nav nav-tabs">
495 <li class="nav-item">
496 <a class="nav-link active" data-bs-toggle="tab" href="#events">
497 <i class="fas fa-list"></i> All Events
498 </a>
499 </li>
500 <li class="nav-item">
501 <a class="nav-link" data-bs-toggle="tab" href="#dns">
502 <i class="fas fa-globe"></i> DNS
503 </a>
504 </li>
505 <li class="nav-item">
506 <a class="nav-link" data-bs-toggle="tab" href="#processes">
507 <i class="fas fa-cogs"></i> Processes
508 </a>
509 </li>
510 <li class="nav-item">
511 <a class="nav-link" data-bs-toggle="tab" href="#network">
512 <i class="fas fa-wifi"></i> Network
513 </a>
514 </li>
515 </ul>
516
517 <div class="tab-content">
518 <!-- Events Tab -->
519 <div id="events" class="tab-pane active">
520 <div class="card">
521 <div class="card-header">
522 <h5>Recent Events</h5>
523 </div>
524 <div class="card-body">
525 <div id="eventsList">Loading...</div>
526 </div>
527 </div>
528 </div>
529
530 <!-- DNS Tab -->
531 <div id="dns" class="tab-pane">
532 <div class="card">
533 <div class="card-header">
534 <h5>DNS Queries</h5>
535 </div>
536 <div class="card-body">
537 <table class="table table-sm">
538 <thead>
539 <tr>
540 <th>Time</th>
541 <th>Computer</th>
542 <th>Domain</th>
543 <th>Results</th>
544 <th>Process</th>
545 </tr>
546 </thead>
547 <tbody id="dnsTable">
548 </tbody>
549 </table>
550 </div>
551 </div>
552 </div>
553
554 <!-- Processes Tab -->
555 <div id="processes" class="tab-pane">
556 <div class="card">
557 <div class="card-header">
558 <h5>Process Executions</h5>
559 </div>
560 <div class="card-body">
561 <table class="table table-sm">
562 <thead>
563 <tr>
564 <th>Time</th>
565 <th>Computer</th>
566 <th>Process</th>
567 <th>User</th>
568 <th>Command</th>
569 </tr>
570 </thead>
571 <tbody id="processesTable">
572 </tbody>
573 </table>
574 </div>
575 </div>
576 </div>
577
578 <!-- Network Tab -->
579 <div id="network" class="tab-pane">
580 <div class="card">
581 <div class="card-header">
582 <h5>Network Connections</h5>
583 </div>
584 <div class="card-body">
585 <table class="table table-sm">
586 <thead>
587 <tr>
588 <th>Time</th>
589 <th>Computer</th>
590 <th>Process</th>
591 <th>Destination</th>
592 <th>Port</th>
593 </tr>
594 </thead>
595 <tbody id="networkTable">
596 </tbody>
597 </table>
598 </div>
599 </div>
600 </div>
601 </div>
602 </div>
603
604 <!-- Bootstrap JS -->
605 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
606
607 <script>
608 // Popraveni API endpoints
609 const API_ENDPOINTS = {
610 stats: '/api/stats',
611 events: '/api/detailed_events',
612 dns: '/api/dns_queries',
613 processes: '/api/process_creations',
614 network: '/api/network_connections',
615 computers: '/api/computers'
616 };
617
618 $(document).ready(function() {
619 updateTime();
620 loadAllData();
621 setInterval(loadAllData, 10000);
622 setInterval(updateTime, 1000);
623 });
624
625 function updateTime() {
626 $('#currentTime').text(new Date().toLocaleString());
627 }
628
629 function loadAllData() {
630 loadStats();
631 loadEvents();
632 loadDNS();
633 loadProcesses();
634 loadNetwork();
635 }
636
637 function loadStats() {
638 $.get(API_ENDPOINTS.stats, function(data) {
639 $('#totalEvents').text(data.total_events);
640 $('#totalComputers').text(data.total_computers);
641 $('#onlineComputers').text(data.online_computers);
642 $('#dnsCount').text(data.dns_queries);
643 $('#processCount').text(data.process_creations);
644 $('#networkCount').text(data.network_connections);
645 $('#lastUpdate').text(new Date().toLocaleTimeString());
646 });
647 }
648
649 function loadEvents() {
650 $.get(API_ENDPOINTS.events + '?limit=20', function(data) {
651 let html = '';
652 data.events.forEach(event => {
653 let badge = '';
654 let text = '';
655
656 if (event.event_id === 22 && event.dns_query) {
657 badge = '<span class="badge bg-info me-2">DNS</span>';
658 text = `Query: <strong>${event.dns_query}</strong> → ${event.dns_results || 'No results'} (Process: ${event.dns_process || 'Unknown'})`;
659 }
660 else if (event.event_id === 1 && event.process_name) {
661 badge = '<span class="badge bg-success me-2">PROCESS</span>';
662 const procName = event.process_name.split('\\').pop();
663 text = `Process: <strong>${procName}</strong> | User: ${event.process_user || 'Unknown'} | Cmd: ${event.command_line ? event.command_line.substring(0, 80) + '...' : 'N/A'}`;
664 }
665 else if (event.event_id === 3 && event.dest_ip) {
666 badge = '<span class="badge bg-danger me-2">NETWORK</span>';
667 const procName = event.process_name ? event.process_name.split('\\').pop() : 'Unknown';
668 text = `Connection: <strong>${procName}</strong> → ${event.dest_ip}:${event.dest_port}`;
669 }
670 else {
671 badge = `<span class="badge bg-secondary me-2">${event.event_type}</span>`;
672 text = event.event_type;
673 }
674
675 html += `
676 <div class="event-item">
677 <div class="small text-muted">${formatTime(event.timestamp)} | ${event.computer}</div>
678 <div>${badge} ${text}</div>
679 </div>
680 `;
681 });
682 $('#eventsList').html(html);
683 });
684 }
685
686 function loadDNS() {
687 $.get(API_ENDPOINTS.dns + '?limit=20', function(data) {
688 let html = '';
689 data.dns_queries.forEach(query => {
690 const process = query.dns_process ? query.dns_process.split('\\').pop() : 'Unknown';
691 html += `
692 <tr>
693 <td>${formatTime(query.timestamp)}</td>
694 <td>${query.computer}</td>
695 <td><strong>${query.dns_query}</strong></td>
696 <td>${query.dns_results || 'N/A'}</td>
697 <td>${process}</td>
698 </tr>
699 `;
700 });
701 $('#dnsTable').html(html);
702 });
703 }
704
705 function loadProcesses() {
706 $.get(API_ENDPOINTS.processes + '?limit=20', function(data) {
707 let html = '';
708 data.process_creations.forEach(proc => {
709 const processName = proc.process_name ? proc.process_name.split('\\').pop() : 'Unknown';
710 html += `
711 <tr>
712 <td>${formatTime(proc.timestamp)}</td>
713 <td>${proc.computer}</td>
714 <td><strong>${processName}</strong></td>
715 <td>${proc.process_user || 'N/A'}</td>
716 <td><small>${proc.command_line ? proc.command_line.substring(0, 80) + '...' : 'N/A'}</small></td>
717 </tr>
718 `;
719 });
720 $('#processesTable').html(html);
721 });
722 }
723
724 function loadNetwork() {
725 $.get(API_ENDPOINTS.network + '?limit=20', function(data) {
726 let html = '';
727 data.network_connections.forEach(conn => {
728 const processName = conn.process_name ? conn.process_name.split('\\').pop() : 'Unknown';
729 html += `
730 <tr>
731 <td>${formatTime(conn.timestamp)}</td>
732 <td>${conn.computer}</td>
733 <td>${processName}</td>
734 <td>${conn.dest_ip}</td>
735 <td>${conn.dest_port}</td>
736 </tr>
737 `;
738 });
739 $('#networkTable').html(html);
740 });
741 }
742
743 function formatTime(timestamp) {
744 if (!timestamp) return 'N/A';
745 const date = new Date(timestamp);
746 return date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
747 }
748 </script>
749</body>
750</html>
751'''
752
753# Dodadi gi site funkcii sto nedostavaat (od prethodniot kod)
754def update_computer_status(computer_name, user, ip_address, os_info):
755 conn = get_db_connection()
756 cursor = conn.cursor()
757 try:
758 cursor.execute('''
759 INSERT OR REPLACE INTO computers
760 (computer_name, user, ip_address, os, last_seen, status)
761 VALUES (?, ?, ?, ?, ?, ?)
762 ''', (computer_name, user, ip_address, os_info, datetime.now().isoformat(), 'online'))
763 conn.commit()
764 except Exception as e:
765 print(f"Error updating computer status: {e}")
766 finally:
767 conn.close()
768
769def parse_sysmon_event_data(event_data):
770 result = {}
771 result['process_name'] = event_data.get('Image', '')
772 result['command_line'] = event_data.get('CommandLine', '')
773 result['process_user'] = event_data.get('User', '')
774 result['parent_process'] = event_data.get('ParentImage', '')
775 result['dns_query'] = event_data.get('QueryName', '')
776 result['dns_results'] = event_data.get('QueryResults', '')
777 result['dns_process'] = event_data.get('Image', '')
778 result['source_ip'] = event_data.get('SourceIp', '')
779 result['dest_ip'] = event_data.get('DestinationIp', '')
780 result['dest_port'] = event_data.get('DestinationPort', '')
781 result['file_path'] = event_data.get('TargetFilename', '')
782 return result
783
784def format_event_for_display(row):
785 event_id = row['event_id']
786 if event_id == 22 and row['dns_query']:
787 return f"DNS Query: {row['dns_query']} → {row['dns_results'] or 'No results'} (Process: {row['dns_process'] or 'Unknown'})"
788 elif event_id == 1 and row['process_name']:
789 proc_name = row['process_name'].split('\\')[-1] if '\\' in row['process_name'] else row['process_name']
790 return f"Process: {proc_name} | User: {row['process_user'] or 'Unknown'}"
791 elif event_id == 3 and row['dest_ip']:
792 proc_name = row['process_name'].split('\\')[-1] if row['process_name'] and '\\' in row['process_name'] else row['process_name'] or 'Unknown'
793 return f"Network: {proc_name} → {row['dest_ip']}:{row['dest_port']}"
794 return f"Event {event_id}: {row['event_type']}"
795
796@app.route('/receive_data', methods=['POST'])
797def receive_data():
798 try:
799 data = request.json
800 if not data:
801 return jsonify({"error": "No data"}), 400
802
803 computer_name = data.get("metadata", {}).get("computer", "Unknown")
804 user = data.get("metadata", {}).get("user", "Unknown")
805
806 conn = get_db_connection()
807 cursor = conn.cursor()
808
809 events_inserted = 0
810
811 # Update computer
812 system_info = data.get("system_info", {})
813 update_computer_status(
814 computer_name,
815 user,
816 system_info.get("ip_address", "Unknown"),
817 system_info.get("os", "Unknown")
818 )
819
820 # Save sysmon events
821 if "sysmon_events" in data:
822 for event in data["sysmon_events"]:
823 try:
824 event_data = event.get("data", {})
825 parsed = parse_sysmon_event_data(event_data)
826
827 cursor.execute('''
828 INSERT INTO sysmon_events
829 (event_id, event_type, timestamp, computer,
830 process_name, command_line, process_user, parent_process,
831 dns_query, dns_results, dns_process,
832 source_ip, dest_ip, dest_port, file_path,
833 raw_data, received_at)
834 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
835 ''', (
836 event.get("event_id"),
837 event.get("event_type"),
838 event.get("timestamp"),
839 event.get("computer"),
840 parsed['process_name'],
841 parsed['command_line'],
842 parsed['process_user'],
843 parsed['parent_process'],
844 parsed['dns_query'],
845 parsed['dns_results'],
846 parsed['dns_process'],
847 parsed['source_ip'],
848 parsed['dest_ip'],
849 parsed['dest_port'],
850 parsed['file_path'],
851 json.dumps(event_data),
852 datetime.now().isoformat()
853 ))
854 events_inserted += 1
855 except Exception as e:
856 print(f"Error inserting event: {e}")
857 continue
858
859 # Save processes (bez exe_path)
860 if "processes" in data:
861 for proc in data["processes"]:
862 try:
863 cursor.execute('''
864 INSERT INTO processes
865 (pid, name, user, cpu_percent, memory_mb, cmdline, timestamp, computer, received_at)
866 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
867 ''', (
868 proc.get("pid"),
869 proc.get("name"),
870 proc.get("user"),
871 proc.get("cpu_percent", 0),
872 proc.get("memory_mb", 0),
873 proc.get("cmdline", ""),
874 datetime.now().isoformat(),
875 computer_name,
876 datetime.now().isoformat()
877 ))
878 except Exception as e:
879 print(f"Error inserting process: {e}")
880 continue
881
882 conn.commit()
883 conn.close()
884
885 return jsonify({
886 "message": "OK",
887 "events_inserted": events_inserted
888 }), 200
889
890 except Exception as e:
891 return jsonify({"error": str(e)}), 500
892
893# Write template
894if not os.path.exists('templates'):
895 os.makedirs('templates')
896
897with open('templates/dashboard_fixed.html', 'w', encoding='utf-8') as f:
898 f.write(dashboard_fixed_html)
899
900if __name__ == '__main__':
901 # REINITIALIZE DATABASE
902 init_database()
903
904 print("\n" + "="*60)
905 print("🚀 FIXED SYSMON SERVER")
906 print("="*60)
907 print("📊 Dashboard: http://localhost:5555/")
908 print("📡 Correct API Endpoints:")
909 print(" - GET /api/detailed_events - All events")
910 print(" - GET /api/dns_queries - DNS queries")
911 print(" - GET /api/process_creations - Process executions")
912 print(" - GET /api/network_connections - Network connections")
913 print(" - GET /api/stats - Statistics")
914 print(" - POST /receive_data - Receive client data")
915 print("\n✅ Database recreated with correct schema")
916 print("="*60)
917
918 app.run(host='0.0.0.0', port=5555, debug=True)
Note: See TracBrowser for help on using the repository browser.