- Timestamp:
- 01/21/26 13:35:44 (6 months ago)
- Branches:
- master
- Children:
- d42aac3
- Parents:
- 2058e5c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sctry.py
r2058e5c r505f39a 1 1 #!/usr/bin/env python3 2 2 """ 3 POPRAVEN CLIENT со фикс за Sysmon 3 netIntel Client (Fixed + more reliable) 4 - Sends payload to /receive with X-Env-Token header 4 5 """ 5 6 … … 9 10 import json 10 11 import requests 11 from datetime import datetime , timedelta12 from datetime import datetime 12 13 import psutil 13 14 import time 14 15 import subprocess 15 import re 16 from collections import defaultdict 17 18 16 import getpass 17 18 19 # ---------------------------- 20 # Helpers 21 # ---------------------------- 22 def safe_username(): 23 try: 24 return os.getlogin() 25 except Exception: 26 return getpass.getuser() 27 28 29 def get_local_ip_fallback(): 30 """ 31 More reliable local IP than socket.gethostbyname(hostname). 32 """ 33 try: 34 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 35 s.connect(("8.8.8.8", 80)) 36 ip = s.getsockname()[0] 37 s.close() 38 return ip 39 except Exception: 40 try: 41 return socket.gethostbyname(socket.gethostname()) 42 except Exception: 43 return "127.0.0.1" 44 45 46 # ---------------------------- 47 # Sysmon-like collector (simulated) 48 # ---------------------------- 19 49 class FixedSysmonCollector: 20 """ Симплифициран колектор што работи без инсталиран Sysmon"""50 """Simplified collector - works even without Sysmon installed""" 21 51 22 52 def __init__(self): … … 24 54 25 55 def collect_sysmon_events(self, limit=50): 26 """Симулирај Sysmon настани од процеси и мрежа"""27 56 events = [] 28 29 try: 30 # 1. Процес настани (Event ID 1 = Process Creation) 57 now = datetime.now() 58 59 try: 60 # 1) Process events (Event ID 1) 31 61 for proc in psutil.process_iter(['pid', 'name', 'create_time', 'username']): 32 62 try: 33 63 pinfo = proc.info 34 if pinfo['create_time']:35 create_time = datetime.fromtimestamp(pinfo['create_time'])36 # Додади само процеси креирани во последните 5 минути37 if not self.last_collection or create_time > self.last_collection:64 ct = pinfo.get('create_time') 65 if ct: 66 create_time = datetime.fromtimestamp(ct) 67 if (not self.last_collection) or (create_time > self.last_collection): 38 68 events.append({ 39 69 "event_id": 1, 40 70 "event_type": "Process Creation", 41 "message": f"Process created: {pinfo ['name']} (PID: {pinfo['pid']}, User: {pinfo['username']})",71 "message": f"Process created: {pinfo.get('name')} (PID: {pinfo.get('pid')}, User: {pinfo.get('username')})", 42 72 "timestamp": create_time.isoformat(), 43 "process_name": pinfo ['name'],44 "pid": pinfo ['pid'],45 "user": pinfo ['username']73 "process_name": pinfo.get('name'), 74 "pid": pinfo.get('pid'), 75 "user": pinfo.get('username'), 46 76 }) 47 77 except (psutil.NoSuchProcess, psutil.AccessDenied): … … 51 81 break 52 82 53 # 2 . Мрежни конекции (Event ID 3 = Network Connection)83 # 2) Network connections (Event ID 3) 54 84 for conn in psutil.net_connections(kind='inet'): 55 85 try: … … 59 89 "event_id": 3, 60 90 "event_type": "Network Connection", 61 "message": f"Network {conn.status}: {conn.laddr.ip if conn.laddr else 'N/A'}:{conn.laddr.port if conn.laddr else 'N/A'} -> {conn.raddr.ip}:{conn.raddr.port}", 62 "timestamp": datetime.now().isoformat(), 91 "message": f"Network {conn.status}: " 92 f"{conn.laddr.ip if conn.laddr else 'N/A'}:{conn.laddr.port if conn.laddr else 'N/A'} " 93 f"-> {conn.raddr.ip}:{conn.raddr.port}", 94 "timestamp": now.isoformat(), 63 95 "local_address": f"{conn.laddr.ip}:{conn.laddr.port}" if conn.laddr else None, 64 96 "remote_address": f"{conn.raddr.ip}:{conn.raddr.port}", 65 97 "status": conn.status, 66 98 "pid": conn.pid, 67 "process_name": proc.name() if proc else "Unknown" 99 "process_name": proc.name() if proc else "Unknown", 68 100 }) 69 101 except (psutil.NoSuchProcess, psutil.AccessDenied): … … 73 105 break 74 106 75 # 3 . Системски перформанси настани107 # 3) Performance alerts (optional) 76 108 cpu = psutil.cpu_percent(interval=0.1) 77 109 if cpu > 80: … … 80 112 "event_type": "High CPU Usage", 81 113 "message": f"High CPU usage detected: {cpu:.1f}%", 82 "timestamp": datetime.now().isoformat(),114 "timestamp": now.isoformat(), 83 115 "cpu_percent": cpu 84 116 }) … … 90 122 "event_type": "High Memory Usage", 91 123 "message": f"High RAM usage: {ram.percent:.1f}%", 92 "timestamp": datetime.now().isoformat(),124 "timestamp": now.isoformat(), 93 125 "ram_percent": ram.percent 94 126 }) … … 97 129 print(f"FixedSysmon error: {e}") 98 130 99 self.last_collection = datetime.now()131 self.last_collection = now 100 132 return events 101 133 102 def collect_network_connections_detailed(self): 103 """Детални мрежни конекции""" 134 def collect_network_connections_detailed(self, limit=30): 104 135 connections = [] 136 now = datetime.now().isoformat() 137 105 138 try: 106 139 for conn in psutil.net_connections(kind='inet'): 107 140 try: 108 141 proc = psutil.Process(conn.pid) if conn.pid else None 109 110 142 conn_info = { 111 143 "pid": conn.pid, … … 113 145 "family": str(conn.family), 114 146 "type": str(conn.type), 115 "timestamp": datetime.now().isoformat()147 "timestamp": now 116 148 } 117 149 … … 127 159 128 160 if proc: 129 conn_info.update({ 130 "process_name": proc.name(), 131 "process_cmdline": ' '.join(proc.cmdline()) if proc.cmdline() else None, 132 "process_username": proc.username() if hasattr(proc, 'username') else None 133 }) 161 conn_info["process_name"] = proc.name() 162 try: 163 cmd = proc.cmdline() 164 conn_info["process_cmdline"] = " ".join(cmd) if cmd else None 165 except Exception: 166 conn_info["process_cmdline"] = None 167 try: 168 conn_info["process_username"] = proc.username() 169 except Exception: 170 conn_info["process_username"] = None 134 171 135 172 connections.append(conn_info) … … 138 175 continue 139 176 140 if len(connections) >= 30:177 if len(connections) >= limit: 141 178 break 142 179 … … 147 184 148 185 def collect_all_security_data(self): 149 """Собери сите безбедносни податоци (очекуваниот метод!)"""150 186 return { 151 187 "sysmon_events": self.collect_sysmon_events(limit=50), 152 "network_connections": self.collect_network_connections_detailed( ),153 "file_changes": [], # Празен лист, можеш да го имплементираш подоцна188 "network_connections": self.collect_network_connections_detailed(limit=30), 189 "file_changes": [], 154 190 "collection_time": datetime.now().isoformat() 155 191 } 156 192 157 193 194 # ---------------------------- 195 # Client 196 # ---------------------------- 158 197 class EnhancedFixedClient: 159 198 def __init__(self, server_ip="192.168.1.13", port=5555, env_token=None): … … 161 200 self.port = port 162 201 self.computer_name = socket.gethostname() 163 self.user = os.getlogin()202 self.user = safe_username() 164 203 self.sysmon_collector = FixedSysmonCollector() 165 204 self.env_token = env_token 166 # Користи поправената верзија 167 168 def get_detailed_info(self): 169 """Собирај подробни податоци""" 170 info = { 171 "computer_name": self.computer_name, 172 "user": self.user, 173 "ip_address": socket.gethostbyname(self.computer_name), 174 "os": f"{platform.system()} {platform.release()} {platform.version()}", 175 "architecture": platform.architecture()[0], 176 "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 177 "is_sysmon_available": self._check_sysmon_installed() 178 } 179 180 info.update(self.get_performance_metrics()) 181 info.update(self.get_hardware_info()) 182 183 return info 205 206 # warmup cpu_percent so it doesn't start at 0 207 try: 208 psutil.cpu_percent(interval=None) 209 except Exception: 210 pass 184 211 185 212 def _check_sysmon_installed(self): 186 """Провери дали Sysmon е инсталиран"""187 213 try: 188 214 if platform.system() == "Windows": … … 192 218 ) 193 219 return result.returncode == 0 194 except :220 except Exception: 195 221 pass 196 222 return False 197 223 198 224 def get_performance_metrics(self): 199 """Метрики за перформанси - ПОПРАВЕНО БЕЗ DEPRECATION WARNING""" 200 try: 201 cpu_percent = psutil.cpu_percent(interval=1) 225 try: 226 cpu_percent = psutil.cpu_percent(interval=0.5) 202 227 cpu_freq = psutil.cpu_freq() 203 204 228 ram = psutil.virtual_memory() 205 229 swap = psutil.swap_memory() 206 207 230 disk = psutil.disk_usage("C:/" if platform.system() == "Windows" else "/") 208 231 209 # ДОБАВИ TRY-EXCEPT за disk_io_counters210 232 disk_read_mb = 0 211 233 disk_write_mb = 0 … … 215 237 disk_read_mb = round(disk_io.read_bytes / (1024 ** 2), 2) 216 238 disk_write_mb = round(disk_io.write_bytes / (1024 ** 2), 2) 217 except :239 except Exception: 218 240 pass 219 241 220 242 net_io = psutil.net_io_counters() 243 244 boot_dt = datetime.fromtimestamp(psutil.boot_time()) 245 uptime_hours = round((datetime.now() - boot_dt).total_seconds() / 3600, 2) 221 246 222 247 return { … … 237 262 "network_packets_sent": net_io.packets_sent, 238 263 "network_packets_recv": net_io.packets_recv, 239 "boot_time": datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"),240 "uptime_hours": round((datetime.now() - datetime.fromtimestamp(psutil.boot_time())).seconds / 3600, 2)264 "boot_time": boot_dt.strftime("%Y-%m-%d %H:%M:%S"), 265 "uptime_hours": uptime_hours 241 266 } 242 267 except Exception as e: … … 245 270 246 271 def get_hardware_info(self): 247 """Хардвер информации"""248 272 try: 249 273 partitions = [] … … 260 284 "percent_used": usage.percent 261 285 }) 262 except: 263 continue 264 265 # Мрежни интерфејси 286 except Exception: 287 continue 288 266 289 net_if_addrs = psutil.net_if_addrs() 267 290 interfaces = {} … … 271 294 "family": str(addr.family), 272 295 "address": addr.address, 273 "netmask": addr.netmask if hasattr(addr, 'netmask') else None296 "netmask": getattr(addr, "netmask", None) 274 297 } 275 for addr in addrs if addr.address298 for addr in addrs if getattr(addr, "address", None) 276 299 ] 300 301 batt = None 302 try: 303 b = psutil.sensors_battery() 304 batt = b.percent if b else None 305 except Exception: 306 batt = None 277 307 278 308 return { … … 281 311 "disks": partitions, 282 312 "network_interfaces": interfaces, 283 "battery_percent": psutil.sensors_battery().percent if hasattr(psutil.sensors_battery(), 284 'percent') else None, 313 "battery_percent": batt, 285 314 "temperatures": self._get_temperatures() 286 315 } … … 290 319 291 320 def _get_temperatures(self): 292 """Добиј температури на системот"""293 321 try: 294 322 temps = {} 295 if hasattr(psutil, 'sensors_temperatures'):323 if hasattr(psutil, "sensors_temperatures"): 296 324 sensors = psutil.sensors_temperatures() 297 325 for name, entries in sensors.items(): … … 299 327 temps[name] = entries[0].current 300 328 return temps 301 except :329 except Exception: 302 330 return {} 303 331 304 def get_detailed_processes(self): 305 """Детални информации за процесите - ПОПРАВЕНО БЕЗ DEPRECATION WARNING""" 332 def get_detailed_processes(self, limit=100): 306 333 processes = [] 307 334 try: 308 for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 309 ' memory_percent', 'create_time', 'status']):335 for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'memory_percent', 336 'create_time', 'status']): 310 337 try: 311 338 pinfo = proc.info 312 313 # КОРИСТИ psutil.Process() за да добиеш дополнителни информации314 339 with proc.oneshot(): 315 340 processes.append({ 316 "pid": pinfo ['pid'],317 "name": pinfo ['name'],318 "user": pinfo ['username'],319 "cpu_percent": pinfo ['cpu_percent'],341 "pid": pinfo.get("pid"), 342 "name": pinfo.get("name"), 343 "user": pinfo.get("username"), 344 "cpu_percent": pinfo.get("cpu_percent"), 320 345 "memory_mb": round(proc.memory_info().rss / (1024 ** 2), 2), 321 "memory_percent": pinfo['memory_percent'], 322 "create_time": datetime.fromtimestamp(pinfo['create_time']).strftime("%Y-%m-%d %H:%M:%S") if 323 pinfo['create_time'] else None, 324 "status": pinfo['status'], 325 "exe": proc.exe() if hasattr(proc, 'exe') else None, 326 "cmdline": ' '.join(proc.cmdline()) if hasattr(proc, 'cmdline') else None, 327 "num_threads": proc.num_threads() if hasattr(proc, 'num_threads') else None, 328 # НЕ КОРИСТИ proc.connections() - тоа е deprecated! 329 "connections_count": 0 # Стави 0 или избриши го ова поле 346 "memory_percent": pinfo.get("memory_percent"), 347 "create_time": datetime.fromtimestamp(pinfo["create_time"]).strftime("%Y-%m-%d %H:%M:%S") 348 if pinfo.get("create_time") else None, 349 "status": pinfo.get("status"), 350 "exe": proc.exe() if hasattr(proc, "exe") else None, 351 "cmdline": " ".join(proc.cmdline()) if hasattr(proc, "cmdline") else None, 352 "num_threads": proc.num_threads() if hasattr(proc, "num_threads") else None, 353 "connections_count": 0 330 354 }) 331 355 except (psutil.NoSuchProcess, psutil.AccessDenied): 332 356 continue 333 334 if len(processes) >= 100: 357 except Exception: 358 continue 359 360 if len(processes) >= limit: 335 361 break 336 362 … … 340 366 return processes 341 367 368 def get_detailed_info(self): 369 info = { 370 "computer_name": self.computer_name, 371 "user": self.user, 372 "ip_address": get_local_ip_fallback(), 373 "os": f"{platform.system()} {platform.release()} {platform.version()}", 374 "architecture": platform.architecture()[0], 375 "timestamp": datetime.now().isoformat(), 376 "is_sysmon_available": self._check_sysmon_installed() 377 } 378 info.update(self.get_performance_metrics()) 379 info.update(self.get_hardware_info()) 380 return info 381 342 382 def collect_and_send(self): 343 """Собери и испрати сите податоци""" 344 print(f"\n[{datetime.now().strftime('%H:%M:%S')}] 🔍 Собирање податоци...") 345 346 # Собери сите податоци 383 print(f"\n[{datetime.now().strftime('%H:%M:%S')}] 🔍 Collecting...") 384 347 385 data = { 348 386 "info": self.get_detailed_info(), 349 "processes": self.get_detailed_processes( ),350 "security_data": self.sysmon_collector.collect_all_security_data(), # ОВА СЕГА РАБОТИ!387 "processes": self.get_detailed_processes(limit=100), 388 "security_data": self.sysmon_collector.collect_all_security_data(), 351 389 "collection_time": datetime.now().isoformat(), 352 "client_version": "2. 1_fixed"390 "client_version": "2.2_fixed" 353 391 } 354 392 355 # Прикажи основни информации356 393 info = data["info"] 357 sec_data = data["security_data"] 358 359 print(f" 💻 Компјутер: {info['computer_name']}") 360 print(f" 👤 Корисник: {info['user']}") 361 print( 362 f" 📊 CPU: {info.get('cpu_usage', 0)}% | RAM: {info.get('ram_usage', 0)}% | Disk: {info.get('disk_usage', 0)}%") 363 print(f" 🔄 Процеси: {len(data['processes'])}") 364 print(f" 🛡️ Sysmon настани: {len(sec_data.get('sysmon_events', []))}") 365 print(f" 🌐 Мрежни конекции: {len(sec_data.get('network_connections', []))}") 366 367 # Испрати ги податоците 368 try: 369 headers = {"X-Env-Token": self.env_token} if self.env_token else {} 370 371 response = requests.post( 372 f"http://{self.server_ip}:{self.port}/receive", 373 json=data, 374 headers=headers, 375 timeout=30 376 ) 377 378 if response.status_code == 200: 379 result = response.json() 380 print(f" ✅ Податоците се успешно испратени!") 381 if 'event_count' in result: 382 print(f" 📝 Зачувани {result['event_count']} Sysmon настани") 394 sec = data["security_data"] 395 396 print(f" 💻 {info.get('computer_name')} | 👤 {info.get('user')}") 397 print(f" 📊 CPU {info.get('cpu_usage', 0)}% | RAM {info.get('ram_usage', 0)}% | Disk {info.get('disk_usage', 0)}%") 398 print(f" 🔄 Processes: {len(data['processes'])}") 399 print(f" 🛡️ Sysmon events: {len(sec.get('sysmon_events', []))}") 400 print(f" 🌐 Net conns: {len(sec.get('network_connections', []))}") 401 402 try: 403 headers = {} 404 if self.env_token: 405 headers["X-Env-Token"] = self.env_token 406 headers["X-Client-Id"] = self.computer_name # optional 407 408 url = f"http://{self.server_ip}:{self.port}/receive" 409 r = requests.post(url, json=data, headers=headers, timeout=30) 410 411 if r.ok: 412 resp = r.json() 413 print(" ✅ Sent OK") 414 if "sysmon_events_saved" in resp: 415 print(f" 📝 Saved sysmon: {resp['sysmon_events_saved']}") 383 416 return True 417 418 # errors 419 if r.status_code == 401: 420 try: 421 msg = r.json() 422 except Exception: 423 msg = {"error": r.text[:200]} 424 print(" 🔒 Token invalid/expired. Generate new token in Admin panel.") 425 print(f" Server says: {msg}") 384 426 else: 385 if response.status_code == 401: 386 try: 387 msg = response.json() 388 except: 389 msg = {} 390 print(" 🔒 Token invalid/expired. Побарај нов token од Admin панел.") 391 print(f" Server says: {msg}") 392 else: 393 print(f" ❌ Грешка: {response.status_code}") 394 try: 395 print(" ", response.text[:300]) 396 except: 397 pass 398 return False 399 400 except Exception as e: 401 print(f" ❌ Проблем со серверот: {e}") 427 print(f" ❌ HTTP {r.status_code}: {r.text[:300]}") 402 428 return False 403 429 430 except Exception as e: 431 print(f" ❌ Connection problem: {e}") 432 return False 433 404 434 405 435 def main(): 406 """Главна програма"""407 436 print("=" * 70) 408 print("🖥️ FIXED LAN LOG COLLECTOR v2.1")437 print("🖥️ netIntel Collector (Fixed)") 409 438 print("=" * 70) 410 print(f" Компјутер: {socket.gethostname()}")411 print(f" Корисник: {os.getlogin()}")412 print(f" IP: {socket.gethostbyname(socket.gethostname())}")439 print(f"Computer: {socket.gethostname()}") 440 print(f"User: {safe_username()}") 441 print(f"Local IP: {get_local_ip_fallback()}") 413 442 print("=" * 70) 414 print("Податоците ќе се собираат и испраќаат на секои 30 секунди.") 415 print("Притисни Ctrl+C за да го прекинеш.") 443 print("Will send every 30 seconds. Ctrl+C to stop.") 416 444 print("=" * 70) 417 445 418 # Провери дали серверот е достапен 419 server_ip = input("Внеси сервер IP (default 192.168.1.13): ").strip() or "192.168.1.13" 420 421 env_token = input("Внеси ENV TOKEN (од Admin панел): ").strip() 446 server_ip = input("Server IP (default 192.168.1.13): ").strip() or "192.168.1.13" 447 env_token = input("ENV TOKEN (from Admin panel): ").strip() 422 448 if not env_token: 423 print("❌ Мора ENV TOKEN за да се регистрира уредот.")449 print("❌ ENV TOKEN is required.") 424 450 return 425 451 426 452 client = EnhancedFixedClient(server_ip, 5555, env_token=env_token) 427 # Тест конекција 428 print(f"\n🔌 Тестирање на врска со серверот{server_ip}...")453 454 print(f"\n🔌 Testing server {server_ip}...") 429 455 try: 430 r esponse= requests.get(f"http://{server_ip}:5555/ping", timeout=5)431 if r esponse.status_code == 200:432 print(" ✅ Серверот е достапен!")456 r = requests.get(f"http://{server_ip}:5555/ping", timeout=5) 457 if r.ok: 458 print(" ✅ Server reachable") 433 459 else: 434 print(f" ⚠️ Серверот одговори со: {response.status_code}") 435 confirm = input(" Сакаш ли да продолжиш? (y/n): ").lower() 436 if confirm != 'y': 437 return 460 print(f" ⚠️ Server responded: {r.status_code}") 438 461 except Exception as e: 439 print(f" ❌ Не можам да се поврзам со серверот {server_ip}: {e}") 440 confirm = input(" Сакаш ли да продолжиш? (y/n): ").lower() 441 if confirm != 'y': 442 return 462 print(f" ❌ Can't reach server: {e}") 463 return 443 464 444 465 try: 445 466 count = 1 446 467 while True: 447 print(f"\n📤 Трансмисија #{count}") 448 449 success = client.collect_and_send() 450 468 print(f"\n📤 Transmission #{count}") 469 client.collect_and_send() 451 470 count += 1 452 print(f"\n⏳ Чекам 30 секунди до следната трансмисија...") 453 454 # Countdown 471 472 print("\n⏳ Waiting 30s...") 455 473 for i in range(30, 0, -1): 456 474 if i % 10 == 0 or i <= 5: 457 print(f"\r {i} секунди остануваат...", end="")475 print(f"\r {i} seconds remaining...", end="") 458 476 time.sleep(1) 459 477 print("\r" + " " * 40 + "\r", end="") 460 478 461 479 except KeyboardInterrupt: 462 print("\n\n🛑 Програмата е зајчана.")463 print(f"📊 Dashboard : http://{server_ip}:5555/")480 print("\n\n🛑 Stopped.") 481 print(f"📊 Dashboard/API: http://{server_ip}:5555/") 464 482 465 483 466 484 if __name__ == "__main__": 467 485 try: 468 import psutil 469 import requests 486 import psutil # noqa 487 import requests # noqa 470 488 except ImportError: 471 print(" Инсталирај ги модулите:")489 print("Install modules:") 472 490 print("pip install psutil requests") 473 input(" Притисни ENTER за излез...")474 exit(1)491 input("Press ENTER to exit...") 492 raise SystemExit(1) 475 493 476 494 main()
Note:
See TracChangeset
for help on using the changeset viewer.
