#!/usr/bin/env python3 """ netIntel Client (Fixed + more reliable) - Sends payload to /receive with X-Env-Token header """ import socket import os import platform import json import requests from datetime import datetime import psutil import time import subprocess import getpass # ---------------------------- # Helpers # ---------------------------- def safe_username(): try: return os.getlogin() except Exception: return getpass.getuser() def get_local_ip_fallback(): """ More reliable local IP than socket.gethostbyname(hostname). """ try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip = s.getsockname()[0] s.close() return ip except Exception: try: return socket.gethostbyname(socket.gethostname()) except Exception: return "127.0.0.1" # ---------------------------- # Sysmon-like collector (simulated) # ---------------------------- class FixedSysmonCollector: """Simplified collector - works even without Sysmon installed""" def __init__(self): self.last_collection = None def collect_sysmon_events(self, limit=50): events = [] now = datetime.now() try: # 1) Process events (Event ID 1) for proc in psutil.process_iter(['pid', 'name', 'create_time', 'username']): try: pinfo = proc.info ct = pinfo.get('create_time') if ct: create_time = datetime.fromtimestamp(ct) if (not self.last_collection) or (create_time > self.last_collection): events.append({ "event_id": 1, "event_type": "Process Creation", "message": f"Process created: {pinfo.get('name')} (PID: {pinfo.get('pid')}, User: {pinfo.get('username')})", "timestamp": create_time.isoformat(), "process_name": pinfo.get('name'), "pid": pinfo.get('pid'), "user": pinfo.get('username'), }) except (psutil.NoSuchProcess, psutil.AccessDenied): continue if len(events) >= limit // 2: break # 2) Network connections (Event ID 3) for conn in psutil.net_connections(kind='inet'): try: if conn.raddr and conn.status in ['ESTABLISHED', 'LISTEN']: proc = psutil.Process(conn.pid) if conn.pid else None events.append({ "event_id": 3, "event_type": "Network Connection", "message": f"Network {conn.status}: " f"{conn.laddr.ip if conn.laddr else 'N/A'}:{conn.laddr.port if conn.laddr else 'N/A'} " f"-> {conn.raddr.ip}:{conn.raddr.port}", "timestamp": now.isoformat(), "local_address": f"{conn.laddr.ip}:{conn.laddr.port}" if conn.laddr else None, "remote_address": f"{conn.raddr.ip}:{conn.raddr.port}", "status": conn.status, "pid": conn.pid, "process_name": proc.name() if proc else "Unknown", }) except (psutil.NoSuchProcess, psutil.AccessDenied): continue if len(events) >= limit: break # 3) Performance alerts (optional) cpu = psutil.cpu_percent(interval=0.1) if cpu > 80: events.append({ "event_id": "PERF_HIGH_CPU", "event_type": "High CPU Usage", "message": f"High CPU usage detected: {cpu:.1f}%", "timestamp": now.isoformat(), "cpu_percent": cpu }) ram = psutil.virtual_memory() if ram.percent > 85: events.append({ "event_id": "PERF_HIGH_RAM", "event_type": "High Memory Usage", "message": f"High RAM usage: {ram.percent:.1f}%", "timestamp": now.isoformat(), "ram_percent": ram.percent }) except Exception as e: print(f"FixedSysmon error: {e}") self.last_collection = now return events def collect_network_connections_detailed(self, limit=30): connections = [] now = datetime.now().isoformat() try: for conn in psutil.net_connections(kind='inet'): try: proc = psutil.Process(conn.pid) if conn.pid else None conn_info = { "pid": conn.pid, "status": conn.status, "family": str(conn.family), "type": str(conn.type), "timestamp": now } if conn.laddr: conn_info["local_address"] = f"{conn.laddr.ip}:{conn.laddr.port}" conn_info["local_ip"] = conn.laddr.ip conn_info["local_port"] = conn.laddr.port if conn.raddr: conn_info["remote_address"] = f"{conn.raddr.ip}:{conn.raddr.port}" conn_info["remote_ip"] = conn.raddr.ip conn_info["remote_port"] = conn.raddr.port if proc: conn_info["process_name"] = proc.name() try: cmd = proc.cmdline() conn_info["process_cmdline"] = " ".join(cmd) if cmd else None except Exception: conn_info["process_cmdline"] = None try: conn_info["process_username"] = proc.username() except Exception: conn_info["process_username"] = None connections.append(conn_info) except (psutil.NoSuchProcess, psutil.AccessDenied): continue if len(connections) >= limit: break except Exception as e: print(f"Network connections error: {e}") return connections def collect_all_security_data(self): return { "sysmon_events": self.collect_sysmon_events(limit=50), "network_connections": self.collect_network_connections_detailed(limit=30), "file_changes": [], "collection_time": datetime.now().isoformat() } # ---------------------------- # Client # ---------------------------- class EnhancedFixedClient: def __init__(self, server_ip="192.168.1.13", port=5555, env_token=None): self.server_ip = server_ip self.port = port self.computer_name = socket.gethostname() self.user = safe_username() self.sysmon_collector = FixedSysmonCollector() self.env_token = env_token # warmup cpu_percent so it doesn't start at 0 try: psutil.cpu_percent(interval=None) except Exception: pass def _check_sysmon_installed(self): try: if platform.system() == "Windows": result = subprocess.run( ["powershell", "-Command", "Get-Process -Name 'sysmon' -ErrorAction SilentlyContinue"], capture_output=True, text=True ) return result.returncode == 0 except Exception: pass return False def get_performance_metrics(self): try: cpu_percent = psutil.cpu_percent(interval=0.5) cpu_freq = psutil.cpu_freq() ram = psutil.virtual_memory() swap = psutil.swap_memory() disk = psutil.disk_usage("C:/" if platform.system() == "Windows" else "/") disk_read_mb = 0 disk_write_mb = 0 try: disk_io = psutil.disk_io_counters() if disk_io: disk_read_mb = round(disk_io.read_bytes / (1024 ** 2), 2) disk_write_mb = round(disk_io.write_bytes / (1024 ** 2), 2) except Exception: pass net_io = psutil.net_io_counters() boot_dt = datetime.fromtimestamp(psutil.boot_time()) uptime_hours = round((datetime.now() - boot_dt).total_seconds() / 3600, 2) return { "cpu_usage": cpu_percent, "cpu_cores": psutil.cpu_count(logical=True), "cpu_freq_current": cpu_freq.current if cpu_freq else 0, "ram_usage": ram.percent, "ram_total_gb": round(ram.total / (1024 ** 3), 2), "ram_used_gb": round(ram.used / (1024 ** 3), 2), "swap_usage": swap.percent if swap else 0, "disk_usage": disk.percent, "disk_total_gb": round(disk.total / (1024 ** 3), 2), "disk_used_gb": round(disk.used / (1024 ** 3), 2), "disk_read_mb": disk_read_mb, "disk_write_mb": disk_write_mb, "network_sent_mb": round(net_io.bytes_sent / (1024 ** 2), 2), "network_recv_mb": round(net_io.bytes_recv / (1024 ** 2), 2), "network_packets_sent": net_io.packets_sent, "network_packets_recv": net_io.packets_recv, "boot_time": boot_dt.strftime("%Y-%m-%d %H:%M:%S"), "uptime_hours": uptime_hours } except Exception as e: print(f"Performance metrics error: {e}") return {} def get_hardware_info(self): try: partitions = [] for partition in psutil.disk_partitions(): try: usage = psutil.disk_usage(partition.mountpoint) partitions.append({ "device": partition.device, "mountpoint": partition.mountpoint, "fstype": partition.fstype, "total_gb": round(usage.total / (1024 ** 3), 2), "used_gb": round(usage.used / (1024 ** 3), 2), "free_gb": round(usage.free / (1024 ** 3), 2), "percent_used": usage.percent }) except Exception: continue net_if_addrs = psutil.net_if_addrs() interfaces = {} for interface, addrs in net_if_addrs.items(): interfaces[interface] = [ { "family": str(addr.family), "address": addr.address, "netmask": getattr(addr, "netmask", None) } for addr in addrs if getattr(addr, "address", None) ] batt = None try: b = psutil.sensors_battery() batt = b.percent if b else None except Exception: batt = None return { "cpu_physical_cores": psutil.cpu_count(logical=False), "cpu_logical_cores": psutil.cpu_count(logical=True), "disks": partitions, "network_interfaces": interfaces, "battery_percent": batt, "temperatures": self._get_temperatures() } except Exception as e: print(f"Hardware info error: {e}") return {} def _get_temperatures(self): try: temps = {} if hasattr(psutil, "sensors_temperatures"): sensors = psutil.sensors_temperatures() for name, entries in sensors.items(): if entries: temps[name] = entries[0].current return temps except Exception: return {} def get_detailed_processes(self, limit=100): processes = [] try: for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'memory_percent', 'create_time', 'status']): try: pinfo = proc.info with proc.oneshot(): processes.append({ "pid": pinfo.get("pid"), "name": pinfo.get("name"), "user": pinfo.get("username"), "cpu_percent": pinfo.get("cpu_percent"), "memory_mb": round(proc.memory_info().rss / (1024 ** 2), 2), "memory_percent": pinfo.get("memory_percent"), "create_time": datetime.fromtimestamp(pinfo["create_time"]).strftime("%Y-%m-%d %H:%M:%S") if pinfo.get("create_time") else None, "status": pinfo.get("status"), "exe": proc.exe() if hasattr(proc, "exe") else None, "cmdline": " ".join(proc.cmdline()) if hasattr(proc, "cmdline") else None, "num_threads": proc.num_threads() if hasattr(proc, "num_threads") else None, "connections_count": 0 }) except (psutil.NoSuchProcess, psutil.AccessDenied): continue except Exception: continue if len(processes) >= limit: break except Exception as e: print(f"Process error: {e}") return processes def get_detailed_info(self): info = { "computer_name": self.computer_name, "user": self.user, "ip_address": get_local_ip_fallback(), "os": f"{platform.system()} {platform.release()} {platform.version()}", "architecture": platform.architecture()[0], "timestamp": datetime.now().isoformat(), "is_sysmon_available": self._check_sysmon_installed() } info.update(self.get_performance_metrics()) info.update(self.get_hardware_info()) return info def collect_and_send(self): print(f"\n[{datetime.now().strftime('%H:%M:%S')}] šŸ” Collecting...") data = { "info": self.get_detailed_info(), "processes": self.get_detailed_processes(limit=100), "security_data": self.sysmon_collector.collect_all_security_data(), "collection_time": datetime.now().isoformat(), "client_version": "2.2_fixed" } info = data["info"] sec = data["security_data"] print(f" šŸ’» {info.get('computer_name')} | šŸ‘¤ {info.get('user')}") print(f" šŸ“Š CPU {info.get('cpu_usage', 0)}% | RAM {info.get('ram_usage', 0)}% | Disk {info.get('disk_usage', 0)}%") print(f" šŸ”„ Processes: {len(data['processes'])}") print(f" šŸ›”ļø Sysmon events: {len(sec.get('sysmon_events', []))}") print(f" 🌐 Net conns: {len(sec.get('network_connections', []))}") try: headers = {} if self.env_token: headers["X-Env-Token"] = self.env_token headers["X-Client-Id"] = self.computer_name # optional url = f"http://{self.server_ip}:{self.port}/receive" r = requests.post(url, json=data, headers=headers, timeout=30) if r.ok: resp = r.json() print(" āœ… Sent OK") if "sysmon_events_saved" in resp: print(f" šŸ“ Saved sysmon: {resp['sysmon_events_saved']}") return True # errors if r.status_code == 401: try: msg = r.json() except Exception: msg = {"error": r.text[:200]} print(" šŸ”’ Token invalid/expired. Generate new token in Admin panel.") print(f" Server says: {msg}") else: print(f" āŒ HTTP {r.status_code}: {r.text[:300]}") return False except Exception as e: print(f" āŒ Connection problem: {e}") return False def main(): print("=" * 70) print("šŸ–„ļø netIntel Collector (Fixed)") print("=" * 70) print(f"Computer: {socket.gethostname()}") print(f"User: {safe_username()}") print(f"Local IP: {get_local_ip_fallback()}") print("=" * 70) print("Will send every 30 seconds. Ctrl+C to stop.") print("=" * 70) server_ip = input("Server IP (default 192.168.1.13): ").strip() or "192.168.1.13" env_token = input("ENV TOKEN (from Admin panel): ").strip() if not env_token: print("āŒ ENV TOKEN is required.") return client = EnhancedFixedClient(server_ip, 5555, env_token=env_token) print(f"\nšŸ”Œ Testing server {server_ip}...") try: r = requests.get(f"http://{server_ip}:5555/ping", timeout=5) if r.ok: print(" āœ… Server reachable") else: print(f" āš ļø Server responded: {r.status_code}") except Exception as e: print(f" āŒ Can't reach server: {e}") return try: count = 1 while True: print(f"\nšŸ“¤ Transmission #{count}") client.collect_and_send() count += 1 print("\nā³ Waiting 30s...") for i in range(30, 0, -1): if i % 10 == 0 or i <= 5: print(f"\r {i} seconds remaining...", end="") time.sleep(1) print("\r" + " " * 40 + "\r", end="") except KeyboardInterrupt: print("\n\nšŸ›‘ Stopped.") print(f"šŸ“Š Dashboard/API: http://{server_ip}:5555/") if __name__ == "__main__": try: import psutil # noqa import requests # noqa except ImportError: print("Install modules:") print("pip install psutil requests") input("Press ENTER to exit...") raise SystemExit(1) main()