#!/usr/bin/env python3
"""
FINAL SYSMON CLIENT - Sends data in correct format
"""
import socket
import os
import platform
import json
import requests
from datetime import datetime
import psutil
import time
import re
class FinalSysmonClient:
def __init__(self, server_ip="192.168.1.13", port=5555):
self.server_ip = server_ip
self.port = port
self.computer_name = socket.gethostname()
self.user = os.getlogin()
def check_sysmon_installed(self):
"""Proveri dali Sysmon e instaliran"""
try:
import win32evtlog
hand = win32evtlog.OpenEventLog("localhost", "Microsoft-Windows-Sysmon/Operational")
win32evtlog.CloseEventLog(hand)
return True
except:
return False
def get_system_info(self):
"""Sobiraј system info"""
try:
ip_address = "N/A"
try:
ip_address = socket.gethostbyname(self.computer_name)
except:
pass
return {
"computer_name": self.computer_name,
"user": self.user,
"ip_address": ip_address,
"os": f"{platform.system()} {platform.release()}",
"cpu_usage": psutil.cpu_percent(interval=1),
"ram_usage": psutil.virtual_memory().percent,
"disk_usage": psutil.disk_usage("C:/").percent if os.name == 'nt' else 0,
"collection_time": datetime.now().isoformat()
}
except Exception as e:
return {"error": str(e)}
def get_running_processes(self):
"""Sobiraј procesi"""
processes = []
try:
for proc in psutil.process_iter(['pid', 'name', 'username']):
try:
processes.append({
"pid": proc.info['pid'],
"name": proc.info['name'],
"user": proc.info['username'] or "N/A",
"cpu_percent": round(proc.cpu_percent(), 2),
"memory_mb": round(proc.memory_info().rss / (1024 ** 2), 2),
"cmdline": ' '.join(proc.cmdline())[:200] if proc.cmdline() else ""
})
except:
continue
if len(processes) >= 20:
break
except:
pass
return processes
def collect_sysmon_events(self, max_events=30):
"""Sobiraј Sysmon eventi vo pravilen format"""
events = []
if not self.check_sysmon_installed():
return events
try:
import win32evtlog
hand = win32evtlog.OpenEventLog("localhost", "Microsoft-Windows-Sysmon/Operational")
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
events_collected = 0
while events_collected < max_events:
events_batch = win32evtlog.ReadEventLog(hand, flags, 0)
if not events_batch:
break
for event in events_batch:
try:
event_id = event.EventID
# Parse event data
event_data = {}
if event.StringInserts:
xml_content = ' '.join([str(s) for s in event.StringInserts])
event_data = self.parse_event_xml(xml_content)
# Create event object
event_obj = {
"event_id": event_id,
"event_type": self.get_event_type(event_id),
"timestamp": event.TimeGenerated.Format() if hasattr(event.TimeGenerated,
'Format') else str(
event.TimeGenerated),
"computer": self.computer_name,
"data": event_data # OVA E NAJVAZHNO - cela event data
}
events.append(event_obj)
events_collected += 1
if events_collected >= max_events:
break
except Exception as e:
continue
win32evtlog.CloseEventLog(hand)
except Exception as e:
print(f" ⚠️ Greshka pri Sysmon: {e}")
return events
def parse_event_xml(self, xml_content):
"""Parse Sysmon event XML"""
data = {}
# Extract all ... pairs
pattern = r']*>([^<]+)'
matches = re.findall(pattern, xml_content)
for name, value in matches:
data[name] = value.strip()
return data
def get_event_type(self, event_id):
"""Get event type name"""
event_types = {
1: "Process Creation",
2: "File creation time changed",
3: "Network Connection",
4: "Sysmon service state changed",
5: "Process Terminated",
6: "Driver Loaded",
7: "Image Loaded (DLL)",
8: "CreateRemoteThread",
10: "Process Access",
11: "File Create",
12: "Registry Object added/deleted",
13: "Registry Value Set",
14: "Registry Object Renamed",
15: "File Create Stream Hash",
17: "Pipe Created",
18: "Pipe Connected",
19: "WmiEventFilter activity detected",
20: "WmiEventConsumer activity detected",
21: "WmiConsumerToFilter activity detected",
22: "DNS Query",
23: "File Delete",
24: "Clipboard Changed",
25: "Process Tampering",
26: "File Delete Detected"
}
return event_types.get(event_id, f"Event {event_id}")
def collect_and_send(self):
"""Sobiraј i ispraќaj podatoci vo PRAVILEN format"""
print(f"\n[{datetime.now().strftime('%H:%M:%S')}] 🔍 Sobiranje podatoci...")
try:
sysmon_installed = self.check_sysmon_installed()
print(f" 🔍 Sysmon: {'✅ Instaliran' if sysmon_installed else '❌ Ne e instaliran'}")
# Sobiraј podatoci
print(f" 📥 Sobiranje Sysmon eventi...")
sysmon_events = self.collect_sysmon_events(max_events=20)
print(f" 📥 Sobiranje system info...")
system_info = self.get_system_info()
print(f" 📥 Sobiranje procesi...")
processes = self.get_running_processes()
# KREIRAJ GO TOCHNIOT FORMAT ZA SERVEROT
data = {
"metadata": {
"computer": self.computer_name,
"user": self.user,
"collection_time": datetime.now().isoformat(),
"sysmon_installed": sysmon_installed
},
"system_info": system_info,
"sysmon_events": sysmon_events, # OVA E KLUCHNO - sysmon_events
"processes": processes
}
# Prikaži statistika
print(f"\n 📊 STATISTIKA:")
print(f" • Sysmon eventi: {len(sysmon_events)}")
print(f" • Procesi: {len(processes)}")
# Prikaži primerok od eventite
if sysmon_events:
print(f"\n 📋 PRIMEROK OD EVENTI:")
for i, event in enumerate(sysmon_events[:3], 1):
event_id = event["event_id"]
event_data = event["data"]
if event_id == 22: # DNS
query = event_data.get("QueryName", "")
if query:
results = event_data.get("QueryResults", "")
process = event_data.get("Image", "")
print(f" {i}. 🌐 DNS: {query} → {results[:50]}... (Process: {process})")
elif event_id == 1: # Process
process = event_data.get("Image", "")
if process:
cmd = event_data.get("CommandLine", "")
user = event_data.get("User", "")
print(f" {i}. 🖥️ Process: {process.split('\\\\')[-1]} | User: {user}")
elif event_id == 3: # Network
dest_ip = event_data.get("DestinationIp", "")
if dest_ip:
port = event_data.get("DestinationPort", "")
process = event_data.get("Image", "")
print(
f" {i}. 🌐 Network: {process.split('\\\\')[-1] if process else 'Unknown'} → {dest_ip}:{port}")
# Prati na serverot
print(f"\n 📤 Prakanje na serverot...")
return self.send_to_server(data)
except Exception as e:
print(f" ❌ Greshka: {e}")
import traceback
traceback.print_exc()
return False
def send_to_server(self, data):
"""Prati gi podatocite na serverot"""
try:
# Proveri dali data e vo pravilen format
if "sysmon_events" not in data:
print(" ❌ Nema sysmon_events vo podatocite!")
return False
response = requests.post(
f"http://{self.server_ip}:{self.port}/receive_data",
json=data,
timeout=30
)
if response.status_code == 200:
result = response.json()
print(f" ✅ Uspeshno isprateno!")
print(f" 📝 Server: {result.get('message', 'OK')}")
print(f" 📊 Eventi vneseni: {result.get('events_inserted', 0)}")
return True
else:
print(f" ❌ Server error: {response.status_code}")
print(f" Response: {response.text[:200]}")
return False
except Exception as e:
print(f" ❌ Greshka pri prakanje: {e}")
return False
def main():
"""Glavna programa"""
print("=" * 70)
print("🛡️ FINAL SYSMON CLIENT")
print("=" * 70)
print(f"Computer: {socket.gethostname()}")
print(f"User: {os.getlogin()}")
print("=" * 70)
server_ip = input("Enter server IP (default 192.168.1.13): ").strip() or "192.168.1.13"
client = FinalSysmonClient(server_ip)
# Test connection
print(f"\n🔌 Testiranje na vrska so serverot {server_ip}...")
try:
response = requests.get(f"http://{server_ip}:5555/ping", timeout=5)
if response.status_code == 200:
print(" ✅ Serverot e dostapen!")
else:
print(f" ⚠️ Serverot odgovora so: {response.status_code}")
except Exception as e:
print(f" ⚠️ Ne moze da se konektira: {e}")
confirm = input(" Sakaš li da prodolzhish? (y/n): ").lower()
if confirm != 'y':
return
try:
count = 1
while True:
print(f"\n" + "=" * 60)
print(f"📤 TRANSMISSION #{count}")
print("=" * 60)
start_time = time.time()
success = client.collect_and_send()
elapsed = time.time() - start_time
print(f"\n ⏱️ Vreme: {elapsed:.2f} sekundi")
count += 1
if success:
wait_time = 60 # 1 minuta
else:
wait_time = 30 # 30 sekundi na failure
print(f"\n⏳ Chekam {wait_time} sekundi...")
for i in range(wait_time, 0, -1):
if i % 10 == 0:
print(f"\r Next in: {i // 60:02d}:{i % 60:02d}", end="")
time.sleep(1)
print("\r" + " " * 30 + "\r", end="")
except KeyboardInterrupt:
print("\n\n🛑 Programata e zaјchana.")
print(f"📊 Dashboard: http://{server_ip}:5555/")
print("=" * 70)
if __name__ == "__main__":
try:
import psutil
import requests
except ImportError:
print("Instaliraј gi modulite:")
print("pip install psutil requests")
if os.name == 'nt':
print("pip install pywin32")
input("Pritisni ENTER za izlez...")
exit(1)
main()